Index: gstgnomevfssrc.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/ext/gnomevfs/gstgnomevfssrc.c,v
retrieving revision 1.87
diff -u -u -r1.87 gstgnomevfssrc.c
--- gstgnomevfssrc.c	27 Mar 2006 16:36:46 -0000	1.87
+++ gstgnomevfssrc.c	17 Apr 2006 21:35:35 -0000
@@ -4,6 +4,7 @@
  *                    2001 Bastien Nocera <hadess@hadess.net>
  *                    2002 Kristian Rietveld <kris@gtk.org>
  *                    2002,2003 Colin Walters <walters@gnu.org>
+ *                    2006 Stefan Kost <ensonic@users.sf.net>
  *
  * gnomevfssrc.c:
  *
@@ -218,6 +219,7 @@
   /* properties */
   gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
       "location", ARG_LOCATION, G_PARAM_READWRITE, NULL);
+  /* FIXME : should be async handle */
   g_object_class_install_property (gobject_class,
       ARG_HANDLE,
       g_param_spec_boxed ("handle",
@@ -268,6 +270,7 @@
   gnomevfssrc->handle = NULL;
   gnomevfssrc->curoffset = 0;
   gnomevfssrc->seekable = FALSE;
+  gnomevfssrc->timeout = 5.0; /* 5 second default timeout */
 
   gnomevfssrc->icy_metaint = 0;
   gnomevfssrc->iradio_mode = FALSE;
@@ -515,6 +518,155 @@
   return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
 }
 
+/* gnome-vfs async api helpers */
+
+static void
+gst_gnome_vfs_src_async_read_cb (GnomeVFSAsyncHandle *handle,
+                                 GnomeVFSResult result, gpointer buffer,
+                                 GnomeVFSFileSize bytes_requested,
+                                 GnomeVFSFileSize bytes_read,
+                                 gpointer callback_data)
+{
+  GstGnomeVFSSrc * src = GST_GNOME_VFS_SRC (callback_data);
+  GST_DEBUG_OBJECT (src, "Read callback : handle=%p : %d/%d",handle,bytes_requested,bytes_read);
+  
+  src->bytes_read = bytes_read;
+  src->result = result;
+  src->async_op_pending = FALSE;
+}
+
+static GnomeVFSResult
+gst_gnome_vfs_async_read (GstGnomeVFSSrc * src, guint8 *data, guint size,
+        GnomeVFSFileSize *bytes_read)
+{
+  GnomeVFSResult res;
+  GTimer *timer = g_timer_new ();
+  
+  src->bytes_read = 0;
+  src->async_op_pending = TRUE;
+  gnome_vfs_async_read (src->handle, data, size,
+      gst_gnome_vfs_src_async_read_cb, (gpointer)src);
+      
+  /* wait for callback to be called */
+  while (src->async_op_pending) {
+    while (g_main_context_pending (NULL)) {
+      g_main_context_iteration (NULL, FALSE);
+      if (g_timer_elapsed (timer, NULL) > src->timeout) {
+        gnome_vfs_async_cancel (src->handle);
+        res = GNOME_VFS_ERROR_TIMEOUT;
+        GST_DEBUG_OBJECT (src, "Timeout occured");
+        goto done;
+      }
+    }
+  }
+  res = src->result;
+done:
+  *bytes_read = src->bytes_read;
+  g_timer_destroy (timer);
+  return(res);
+}
+
+static void
+gst_gnome_vfs_src_async_default_cb (GnomeVFSAsyncHandle *handle,
+                                    GnomeVFSResult result,
+                                    gpointer callback_data)
+{
+  GstGnomeVFSSrc * src = GST_GNOME_VFS_SRC (callback_data);
+  GST_DEBUG_OBJECT (src, "Default callback : handle=%p", handle);
+  
+  src->result = result;
+  src->async_op_pending = FALSE;
+}
+
+static GnomeVFSResult
+gst_gnome_vfs_async_open_uri (GstGnomeVFSSrc * src)
+{
+  GnomeVFSResult res;
+  GTimer *timer = g_timer_new ();
+  
+  src->async_op_pending = TRUE;
+  gnome_vfs_async_open_uri (&src->handle, src->uri, GNOME_VFS_OPEN_READ,
+                            GNOME_VFS_PRIORITY_DEFAULT,
+                            gst_gnome_vfs_src_async_default_cb,
+                            (gpointer)src);
+  /*
+  gnome_vfs_async_open (&src->handle, src->uri_name, GNOME_VFS_OPEN_READ,
+                            GNOME_VFS_PRIORITY_DEFAULT,
+                            gst_gnome_vfs_src_async_default_cb,
+                            (gpointer)src);
+  */
+  /* wait for callback to be called */
+  while (src->async_op_pending) {
+    while (g_main_context_pending (NULL)) {
+      g_main_context_iteration (NULL, FALSE);
+      if (g_timer_elapsed (timer, NULL) > src->timeout) {
+        gnome_vfs_async_cancel (src->handle);
+        res = GNOME_VFS_ERROR_TIMEOUT;
+        GST_DEBUG_OBJECT (src, "Timeout occured");
+        goto done;
+      }
+    }
+  }
+  res = src->result;
+  GST_DEBUG_OBJECT (src, "open uri okay : handle = %p, res=%s", src->handle,
+      gnome_vfs_result_to_string (res));
+done:
+  g_timer_destroy (timer);
+  return(res);
+}
+
+static void
+gst_gnome_vfs_async_close (GstGnomeVFSSrc * src)
+{
+  GTimer *timer = g_timer_new ();
+  
+  src->async_op_pending = TRUE;
+  gnome_vfs_async_close (src->handle,
+                         gst_gnome_vfs_src_async_default_cb,
+                         (gpointer)src);
+  /* wait for callback to be called */
+  while (src->async_op_pending) {
+    while (g_main_context_pending (NULL)) {
+      g_main_context_iteration (NULL, FALSE);
+      if (g_timer_elapsed (timer, NULL) > src->timeout) {
+        gnome_vfs_async_cancel (src->handle);
+        GST_DEBUG_OBJECT (src, "Timeout occured");
+        break;
+      }
+    }
+  }
+  g_timer_destroy (timer);
+}
+
+static GnomeVFSResult
+gst_gnome_vfs_seek_async (GstGnomeVFSSrc *src, GnomeVFSSeekPosition whence,
+                          GnomeVFSFileOffset offset)
+{
+  GnomeVFSResult res;
+  GTimer *timer = g_timer_new ();
+  
+  src->async_op_pending = TRUE;
+  gnome_vfs_async_seek (src->handle, whence, offset,
+                            gst_gnome_vfs_src_async_default_cb,
+                            (gpointer)src);
+  /* wait for callback to be called */
+  while (src->async_op_pending) {
+    while (g_main_context_pending (NULL)) {
+      g_main_context_iteration (NULL, FALSE);
+      if (g_timer_elapsed (timer, NULL) > src->timeout) {
+        gnome_vfs_async_cancel (src->handle);
+        res = GNOME_VFS_ERROR_TIMEOUT;
+        GST_DEBUG_OBJECT (src, "Timeout occured");
+        goto done;
+      }
+    }
+  }
+  res = src->result;
+done:
+  g_timer_destroy (timer);
+  return(res);  
+}
+
 /*
  * icecast/audiocast metadata extraction support code
  */
@@ -770,7 +922,7 @@
 
   if (!src->iradio_mode)
     return;
-  GST_DEBUG_OBJECT (src, "sending headers\n");
+  GST_DEBUG_OBJECT (src, "sending headers");
 
   out_args->headers = g_list_append (out_args->headers,
       g_strdup ("icy-metadata:1\r\n"));
@@ -885,12 +1037,14 @@
   guchar *data;
   guchar *pos;
   gchar **tags;
-  int i;
+  guint i, size;
 
   GST_DEBUG_OBJECT (src, "reading icecast metadata");
 
   while (length == 0) {
-    res = gnome_vfs_read (src->handle, &foobyte, 1, &length);
+    //res = gnome_vfs_read (src->handle, &foobyte, 1, &length);
+    res = gst_gnome_vfs_async_read (src, &foobyte, 1, &length);
+    
     if (res != GNOME_VFS_OK)
       return;
   }
@@ -904,8 +1058,11 @@
   pos = data;
 
   while (pos - data < metadata_length) {
-    res = gnome_vfs_read (src->handle, pos,
-        metadata_length - (pos - data), &length);
+    size = metadata_length - (pos - data);
+    //res = gnome_vfs_read (src->handle, pos, size, &length);
+    res = gst_gnome_vfs_async_read (src, data, size, &length);
+        
+        
     /* FIXME: better error handling here? */
     if (res != GNOME_VFS_OK) {
       g_free (data);
@@ -958,7 +1115,7 @@
 {
   GnomeVFSResult res;
   GstBuffer *buf;
-  GnomeVFSFileSize readbytes;
+  GnomeVFSFileSize bytes_read;
   guint8 *data;
   GstGnomeVFSSrc *src;
 
@@ -972,7 +1129,9 @@
     GST_DEBUG ("need to seek");
     if (src->seekable) {
       GST_DEBUG ("seeking to %lld", offset);
-      res = gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_START, offset);
+      //res = gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_START, offset);
+      res = gst_gnome_vfs_seek_async (src, GNOME_VFS_SEEK_START, offset);
+      
       if (res != GNOME_VFS_OK)
         goto seek_failed;
       src->curoffset = offset;
@@ -984,6 +1143,8 @@
   audiocast_do_notifications (src);
 
   if (src->iradio_mode && src->icy_metaint > 0) {
+    guint isize = src->icy_metaint - src->icy_count;
+    
     buf = gst_buffer_new_and_alloc (src->icy_metaint);
 
     data = GST_BUFFER_DATA (buf);
@@ -992,41 +1153,43 @@
     GST_DEBUG_OBJECT (src, "doing read: icy_count: %" G_GINT64_FORMAT,
         src->icy_count);
 
-    res = gnome_vfs_read (src->handle, data,
-        src->icy_metaint - src->icy_count, &readbytes);
+    //res = gnome_vfs_read (src->handle, data, isize, &bytes_read);
+    res = gst_gnome_vfs_async_read (src, data, isize, &bytes_read);
 
-    if (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK && readbytes == 0))
+    if (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK && bytes_read == 0))
       goto eos;
 
     if (res != GNOME_VFS_OK)
       goto read_failed;
 
-    src->icy_count += readbytes;
+    src->icy_count += bytes_read;
     GST_BUFFER_OFFSET (buf) = src->curoffset;
-    GST_BUFFER_SIZE (buf) = readbytes;
-    src->curoffset += readbytes;
+    GST_BUFFER_SIZE (buf) = bytes_read;
+    src->curoffset += bytes_read;
 
     if (src->icy_count == src->icy_metaint) {
       gst_gnome_vfs_src_get_icy_metadata (src);
       src->icy_count = 0;
     }
-  } else {
+  } else {    
     buf = gst_buffer_new_and_alloc (size);
 
     data = GST_BUFFER_DATA (buf);
-    GST_BUFFER_OFFSET (buf) = src->curoffset;
 
-    res = gnome_vfs_read (src->handle, data, size, &readbytes);
+    GST_DEBUG_OBJECT (src, "doing read");
 
-    if (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK && readbytes == 0))
-      goto eos;
+    //res = gnome_vfs_read (src->handle, data, size, &bytes_read);
+    res = gst_gnome_vfs_async_read (src, data, size, &bytes_read);
 
-    GST_BUFFER_SIZE (buf) = readbytes;
+    if (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK && bytes_read == 0))
+      goto eos;
 
     if (res != GNOME_VFS_OK)
       goto read_failed;
 
-    src->curoffset += readbytes;
+    GST_BUFFER_OFFSET (buf) = src->curoffset;
+    GST_BUFFER_SIZE (buf) = bytes_read;
+    src->curoffset += bytes_read;
   }
 
   /* we're done, return the buffer */
@@ -1152,10 +1315,12 @@
 
   if (src->uri != NULL) {
     /* this can block... */
-    if ((res = gnome_vfs_open_uri (&src->handle, src->uri,
-                GNOME_VFS_OPEN_READ)) != GNOME_VFS_OK)
+    //if ((res = gnome_vfs_open_uri (&src->handle, src->uri,
+    //            GNOME_VFS_OPEN_READ)) != GNOME_VFS_OK)
+    if ((res = gst_gnome_vfs_async_open_uri (src)) != GNOME_VFS_OK)
       goto open_failed;
     src->own_handle = TRUE;
+    GST_DEBUG_OBJECT (src, "open uri okay : handle = %p", src->handle);
   } else if (!src->handle) {
     goto no_filename;
   } else {
@@ -1164,7 +1329,10 @@
 
   src->size = (GnomeVFSFileSize) - 1;
   info = gnome_vfs_file_info_new ();
-  if ((res = gnome_vfs_get_file_info_from_handle (src->handle,
+  /* TODO: port to async API */
+  //if ((res = gnome_vfs_get_file_info_from_handle (src->handle,
+  //            info, GNOME_VFS_FILE_INFO_DEFAULT)) == GNOME_VFS_OK) {
+  if ((res = gnome_vfs_get_file_info_uri (src->uri,
               info, GNOME_VFS_FILE_INFO_DEFAULT)) == GNOME_VFS_OK) {
     if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
       src->size = info->size;
@@ -1179,13 +1347,17 @@
 
   audiocast_do_notifications (src);
 
-  if (gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_CURRENT, 0)
-      == GNOME_VFS_OK) {
+  //if (gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_CURRENT, 0)
+  if (gst_gnome_vfs_seek_async (src, GNOME_VFS_SEEK_CURRENT, 0)
+    == GNOME_VFS_OK) {
     src->seekable = TRUE;
+    GST_DEBUG_OBJECT (src, "is seekable");
   } else {
     src->seekable = FALSE;
+    GST_DEBUG_OBJECT (src, "is not seekable");
   }
 
+  GST_DEBUG_OBJECT (src, "open uri still okay : handle = %p", src->handle);
   return TRUE;
 
   /* ERRORS */
@@ -1228,7 +1400,8 @@
   audiocast_thread_kill (src);
 
   if (src->own_handle) {
-    gnome_vfs_close (src->handle);
+    //gnome_vfs_close (src->handle);
+    gst_gnome_vfs_async_close (src);
     src->handle = NULL;
   }
   src->size = (GnomeVFSFileSize) - 1;
Index: gstgnomevfssrc.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/ext/gnomevfs/gstgnomevfssrc.h,v
retrieving revision 1.2
diff -u -u -r1.2 gstgnomevfssrc.h
--- gstgnomevfssrc.h	1 Mar 2006 17:39:28 -0000	1.2
+++ gstgnomevfssrc.h	17 Apr 2006 21:35:35 -0000
@@ -58,11 +58,16 @@
   /* uri, file, ... */
   GnomeVFSURI *uri;
   gchar *uri_name;
-  GnomeVFSHandle *handle;
+  //GnomeVFSHandle *handle;
+  GnomeVFSAsyncHandle *handle;
   gboolean own_handle;
   GnomeVFSFileSize size;        /* -1 = unknown */
   GnomeVFSFileOffset curoffset; /* current offset in file */
+  GnomeVFSResult result;
   gboolean seekable;
+  gboolean async_op_pending;
+  GnomeVFSFileSize bytes_read;
+  gdouble timeout;
 
   /* icecast/audiocast metadata extraction handling */
   gboolean iradio_mode;
