Implement this by sending the message (synchronously) in another thread
authorDan Winship <danw@src.gnome.org>
Fri, 30 Mar 2007 14:58:54 +0000 (14:58 +0000)
committerDan Winship <danw@src.gnome.org>
Fri, 30 Mar 2007 14:58:54 +0000 (14:58 +0000)
* libsoup/soup-session-sync.c (queue_message): Implement this by
sending the message (synchronously) in another thread and then
queueing the callback back in the main thread.

* libsoup/soup-session.c (soup_session_queue_message): update docs
to be more explicit about what thread the callback occurs in

svn path=/trunk/; revision=923

ChangeLog
libsoup/soup-session-sync.c
libsoup/soup-session.c

index 6bee2c6..f75fb39 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-03-29  Dan Winship  <danw@novell.com>
+
+       * libsoup/soup-session-sync.c (queue_message): Implement this by
+       sending the message (synchronously) in another thread and then
+       queueing the callback back in the main thread.
+
+       * libsoup/soup-session.c (soup_session_queue_message): update docs
+       to be more explicit about what thread the callback occurs in
+
 2007-03-17  Dan Winship  <danw@novell.com>
 
        * libsoup/soup-message.c (soup_message_set_auth)
index b8608b9..b6abbdf 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "soup-session-sync.h"
 #include "soup-connection.h"
+#include "soup-misc.h"
 
 typedef struct {
        GMutex *lock;
@@ -98,13 +99,63 @@ soup_session_sync_new_with_options (const char *optname1, ...)
        return session;
 }
 
+typedef struct {
+       SoupSession *session;
+       SoupMessage *msg;
+       SoupMessageCallbackFn callback;
+       gpointer user_data;
+} SoupSessionSyncAsyncData;
+
+static void
+async_data_free (SoupSessionSyncAsyncData *sad)
+{
+       g_object_unref (sad->session);
+       g_object_unref (sad->msg);
+       g_free (sad);
+}
+
+static gboolean
+queue_message_callback (gpointer data)
+{
+       SoupSessionSyncAsyncData *sad = data;
+
+       sad->callback (sad->msg, sad->user_data);
+       async_data_free (sad);
+       return FALSE;
+}
+
+static gpointer
+queue_message_thread (gpointer data)
+{
+       SoupSessionSyncAsyncData *sad = data;
+
+       soup_session_send_message (sad->session, sad->msg);
+       if (sad->callback) {
+               GMainContext *async_context;
+
+               g_object_get (sad->session,
+                             SOUP_SESSION_ASYNC_CONTEXT, &async_context,
+                             NULL);
+               soup_add_idle (async_context, queue_message_callback, sad);
+       } else
+               async_data_free (sad);
+
+       return NULL;
+}
 
 static void
 queue_message (SoupSession *session, SoupMessage *msg,
               SoupMessageCallbackFn callback, gpointer user_data)
 {
-       /* FIXME */
-       g_warning ("soup_session_queue_message called on synchronous session");
+       SoupSessionSyncAsyncData *sad;
+
+       sad = g_new (SoupSessionSyncAsyncData, 1);
+       sad->session = g_object_ref (session);
+       sad->msg = g_object_ref (msg);
+       sad->callback = callback;
+       sad->user_data = user_data;
+
+       g_thread_create (queue_message_thread, sad, FALSE, NULL);
 }
 
 static SoupConnection *
index 2dfe67b..633d443 100644 (file)
@@ -1259,8 +1259,9 @@ queue_message (SoupSession *session, SoupMessage *msg,
  * any resources related to the time it was last sent are freed.
  *
  * Upon message completion, the callback specified in @callback will
- * be invoked. If after returning from this callback the message has
- * not been requeued, @msg will be unreffed.
+ * be invoked (in the thread associated with @session's async
+ * context). If after returning from this callback the message has not
+ * been requeued, @msg will be unreffed.
  */
 void
 soup_session_queue_message (SoupSession *session, SoupMessage *msg,