[Evolution-hackers] Patch: SOUP MT support
- From: Jan-Marek Glogowski <glogow stud fbi fh-darmstadt de>
- To: evolution-hackers lists ximian com
- Subject: [Evolution-hackers] Patch: SOUP MT support
- Date: Wed, 24 Sep 2003 02:04:17 +0200 (CEST)
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;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]