Hi

The following patch adds some basic MT support to libsoup. It's against
v1.99.24. It allows the use of "soup_message_queue" in MT applications.
I'm not sure how to fix "soup_message_send", since it calls
g_main_iteration(TRUE), which blocks forever if it's called from an other
thread.

Is there an official homepage for libsoup development?

Thanks

Jan-Marek Glogowski


diff -burN -X develop/excl-diff -x get -x libsoup-ssl-proxy 
libsoup-1.99.24/libsoup/soup-message.c libsoup-1.99.24-jmg/libsoup/soup-message.c
--- libsoup-1.99.24/libsoup/soup-message.c      2003-06-26 18:27:03.000000000 +0200
+++ libsoup-1.99.24-jmg/libsoup/soup-message.c  2003-09-22 07:35:41.000000000 +0200
@@ -48,6 +48,8 @@

        ret->priv->http_version = SOUP_HTTP_1_1;

+       ret->refcnt = 1;
+
        soup_message_set_context (ret, context);

        return ret;
@@ -252,7 +254,13 @@
 {
        g_return_if_fail (req != NULL);

-       soup_message_cleanup (req);
+       /*
+        * Make sure we don't free the message
+        * inside soup_message_cleanup
+        */
+       soup_message_ref(req);
+
+       soup_message_cleanup(req);

        finalize_message (req);
 }
@@ -273,6 +281,12 @@
        g_return_if_fail (req != NULL);

        /*
+        * Make sure we don't free the message
+        * inside soup_message_cleanup
+        */
+       soup_message_ref (req);
+
+       /*
         * Make sure we don't have some icky recursion if the callback
         * runs the main loop, and the connection has some data or error
         * which causes the callback to be run again.
@@ -282,9 +296,15 @@
        if (req->priv->callback) {
                (*req->priv->callback) (req, req->priv->user_data);

-               if (req->status != SOUP_STATUS_QUEUED)
+               if (req->status != SOUP_STATUS_QUEUED) {
                        finalize_message (req);
+
+                       // Finalize frees the message so skip unref
+                       return;
+               }
        }
+
+       soup_message_unref (req);
 }

 /**
@@ -1213,3 +1233,20 @@
        msg->errorclass = SOUP_ERROR_CLASS_HANDLER;
        msg->errorphrase = g_strdup (errphrase);
 }
+
+void
+soup_message_ref (SoupMessage *msg)
+{
+       g_return_if_fail (msg != NULL);
+
+       msg->refcnt++;
+}
+
+void
+soup_message_unref (SoupMessage *msg)
+{
+       g_return_if_fail (msg != NULL);
+
+       if (msg->refcnt > 1) { msg->refcnt--; }
+       else { soup_message_free(msg); }
+}
diff -burN -X develop/excl-diff -x get -x libsoup-ssl-proxy 
libsoup-1.99.24/libsoup/soup-message.h libsoup-1.99.24-jmg/libsoup/soup-message.h
--- libsoup-1.99.24/libsoup/soup-message.h      2002-11-18 16:26:19.000000000 +0100
+++ libsoup-1.99.24-jmg/libsoup/soup-message.h  2003-09-22 06:16:48.000000000 +0200
@@ -59,6 +59,8 @@

        SoupDataBuffer      response;
        GHashTable         *response_headers;
+
+       guint               refcnt;
 };

 #define SOUP_MESSAGE_IS_ERROR(_msg)                            \
@@ -82,6 +84,10 @@

 void           soup_message_free                (SoupMessage       *req);

+void           soup_message_ref                 (SoupMessage       *msg);
+
+void           soup_message_unref               (SoupMessage       *msg);
+
 void           soup_message_cancel              (SoupMessage       *req);

 SoupErrorClass soup_message_send                (SoupMessage       *msg);
diff -burN -X develop/excl-diff -x get -x libsoup-ssl-proxy 
libsoup-1.99.24/libsoup/soup-queue.c libsoup-1.99.24-jmg/libsoup/soup-queue.c
--- libsoup-1.99.24/libsoup/soup-queue.c        2003-09-22 07:35:37.000000000 +0200
+++ libsoup-1.99.24-jmg/libsoup/soup-queue.c    2003-09-24 01:49:17.000000000 +0200
@@ -33,6 +33,7 @@
 static GSList *soup_active_requests = NULL, *soup_active_request_next = NULL;

 static guint soup_queue_idle_tag = 0;
+static GMutex *mutex = NULL;

 static void
 soup_debug_print_a_header (gchar *key, gchar *val, gpointer not_used)
@@ -685,15 +686,26 @@
 void
 soup_queue_add_request (SoupMessage *req)
 {
-       soup_active_requests = g_slist_prepend (soup_active_requests, req);
+       soup_message_ref(req);
+       soup_active_requests =
+               g_slist_prepend (soup_active_requests, req);
 }

 void
 soup_queue_remove_request (SoupMessage *req)
 {
+       GSList *list;
+
        if (soup_active_request_next && soup_active_request_next->data == req)
                soup_queue_next_request ();
-       soup_active_requests = g_slist_remove (soup_active_requests, req);
+
+       g_mutex_lock(mutex);
+       if ((list = g_slist_find(soup_active_requests, req)) != NULL) {
+               soup_active_requests =
+                       g_slist_remove_link(soup_active_requests, list);
+               soup_message_unref(req);
+       }
+       g_mutex_unlock(mutex);
 }

 SoupMessage *
@@ -730,13 +742,22 @@
 static gboolean
 soup_idle_handle_new_requests (gpointer unused)
 {
-       SoupMessage *req = soup_queue_first_request ();
+       SoupMessage *req;
+       GSList *first;

-       for (; req; req = soup_queue_next_request ()) {
+       g_mutex_lock(mutex);
+       req = soup_queue_first_request ();
+       if (req == NULL)
+               { goto handle_exit; }
+       first = soup_active_requests;
+       soup_message_ref(req);
+       g_mutex_unlock(mutex);
+
+       while (1) {
                SoupContext *ctx, *proxy;

                if (req->status != SOUP_STATUS_QUEUED)
-                       continue;
+                       goto handle_next_message;

                proxy = soup_get_proxy ();
                ctx = proxy ? proxy : req->context;
@@ -758,21 +779,40 @@
                        if (connect_tag && request_in_progress (req))
                                req->priv->connect_tag = connect_tag;
                }
+
+handle_next_message:
+               g_mutex_lock(mutex);
+               soup_message_unref(req);
+               req = soup_queue_next_request();
+               if (req == NULL) {
+                       if (first == soup_active_requests)
+                               break;
+                       else {
+                               first = soup_active_requests;
+                               req = soup_queue_first_request();
+                               if (req == NULL)
+                                       break;
+                       }
+               }
+               soup_message_ref(req);
+               g_mutex_unlock(mutex);
        }

+handle_exit:
        soup_queue_idle_tag = 0;
+
+       g_mutex_unlock(mutex);
+
        return FALSE;
 }

 static void
 soup_queue_initialize (void)
 {
-       if (!soup_initialized)
+       if (!soup_initialized) {
                soup_load_config (NULL);
-
-       if (!soup_queue_idle_tag)
-               soup_queue_idle_tag =
-                       g_idle_add (soup_idle_handle_new_requests, NULL);
+               mutex = g_mutex_new();
+       }
 }

 void
@@ -829,9 +869,16 @@

        req->status = SOUP_STATUS_QUEUED;

+       soup_queue_initialize ();
+
        soup_queue_add_request (req);

-       soup_queue_initialize ();
+       g_mutex_lock(mutex);
+       if (soup_queue_idle_tag == 0) {
+               soup_queue_idle_tag =
+                       g_idle_add (soup_idle_handle_new_requests, NULL);
+       }
+       g_mutex_unlock(mutex);
 }

 /**
@@ -857,4 +904,7 @@
                soup_message_cancel (req);

        soup_connection_purge_idle ();
+
+       g_mutex_free(mutex);
+       mutex = NULL;
 }
_______________________________________________
evolution-hackers maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/evolution-hackers

Reply via email to