rpms/evolution-data-server/devel evolution-data-server-1.8.0-emsgport.patch, NONE, 1.1 evolution-data-server.spec, 1.121, 1.122 evolution-data-server-1.8.0-msgport-pipes.patch, 1.1, NONE

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Fri Sep 15 18:25:55 UTC 2006


Author: mbarnes

Update of /cvs/dist/rpms/evolution-data-server/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv10149

Modified Files:
	evolution-data-server.spec 
Added Files:
	evolution-data-server-1.8.0-emsgport.patch 
Removed Files:
	evolution-data-server-1.8.0-msgport-pipes.patch 
Log Message:

* Fri Sep 15 2006 Matthew Barnes <mbarnes at redhat.com> - 1.8.0-3.fc6
- Revise patch for RH bug #198935 to eliminate a race condition.


evolution-data-server-1.8.0-emsgport.patch:
 e-msgport.c |  326 ++++++++++++++++++++++++++++++++----------------------------
 e-msgport.h |    1 
 2 files changed, 175 insertions(+), 152 deletions(-)

--- NEW FILE evolution-data-server-1.8.0-emsgport.patch ---
--- evolution-data-server-1.8.0/libedataserver/e-msgport.c.emsgport	2006-08-07 00:48:26.000000000 -0400
+++ evolution-data-server-1.8.0/libedataserver/e-msgport.c	2006-09-15 12:49:44.000000000 -0400
@@ -486,29 +486,19 @@
 }
 
 struct _EMsgPort {
-	EDList queue;
-	int condwait;		/* how many waiting in condwait */
-	union {
-		int pipe[2];	/* On Win32 actually a pair of SOCKETs */
-		struct {
-			int read;
-			int write;
-		} fd;
-	} pipe;
+	GAsyncQueue *queue;
+	EMsg *cache;
+	gint pipe[2];  /* on Win32, actually a pair of SOCKETs */
 #ifdef HAVE_NSS
-	union {
-		PRFileDesc *pipe[2];
-		struct {
-			PRFileDesc *read;
-			PRFileDesc *write;
-		} fd;
-	} prpipe;
-#endif
-	/* @#@$#$ glib stuff */
-	GCond *cond;
-	GMutex *lock;
+	PRFileDesc *prpipe[2];
+#endif
 };
 
+/* message flags */
+enum {
+	MSG_FLAG_SYNC_WITH_PIPE    = 1 << 0,
+	MSG_FLAG_SYNC_WITH_PR_PIPE = 1 << 1
+};
 
 #ifdef HAVE_NSS
 static int
@@ -529,189 +519,221 @@
 }
 #endif
 
-EMsgPort *e_msgport_new(void)
+static void
+msgport_sync_with_pipe (gint fd)
 {
-	EMsgPort *mp;
+	gchar buffer[1];
+
+	while (fd >= 0) {
+		if (E_READ (fd, buffer, 1) > 1)
+			break;
+		else if (!E_IS_STATUS_INTR ())
+			break;
+	}
+}
 
-	mp = g_malloc(sizeof(*mp));
-	e_dlist_init(&mp->queue);
-	mp->lock = g_mutex_new();
-	mp->cond = g_cond_new();
-	e_pipe (mp->pipe.pipe);
 #ifdef HAVE_NSS
-	e_prpipe (mp->prpipe.pipe);
+static void
+msgport_sync_with_prpipe (PRFileDesc *prfd)
+{
+	gchar buffer[1];
+
+	while (prfd != NULL) {
+		if (PR_Read (prfd, buffer, 1) > 1)
+			break;
+		else if (PR_GetError () != PR_PENDING_INTERRUPT_ERROR)
+			break;
+	}
+}
 #endif
-	mp->condwait = 0;
 
-	return mp;
+EMsgPort *
+e_msgport_new (void)
+{
+	EMsgPort *msgport;
+
+	msgport = g_slice_new (EMsgPort);
+	msgport->queue = g_async_queue_new ();
+	msgport->cache = NULL;
+	msgport->pipe[0] = -1;
+	msgport->pipe[1] = -1;
+#ifdef HAVE_NSS
+	msgport->prpipe[0] = NULL;
+	msgport->prpipe[1] = NULL;
+#endif
+
+	return msgport;
 }
 
-void e_msgport_destroy(EMsgPort *mp)
+void
+e_msgport_destroy (EMsgPort *msgport)
 {
-	g_mutex_free(mp->lock);
-	g_cond_free(mp->cond);
-	if (mp->pipe.fd.read != -1) {
-		E_CLOSE(mp->pipe.fd.read);
-		E_CLOSE(mp->pipe.fd.write);
+	g_return_if_fail (msgport != NULL);
+
+	if (msgport->pipe[0] >= 0) {
+		E_CLOSE (msgport->pipe[0]);
+		E_CLOSE (msgport->pipe[1]);
 	}
 #ifdef HAVE_NSS
-	if (mp->prpipe.fd.read) {
-		PR_Close(mp->prpipe.fd.read);
-		PR_Close(mp->prpipe.fd.write);
+	if (msgport->prpipe[0] != NULL) {
+		PR_Close (msgport->prpipe[0]);
+		PR_Close (msgport->prpipe[1]);
 	}
 #endif
-	g_free(mp);
+
+	g_async_queue_unref (msgport->queue);
+	g_slice_free (EMsgPort, msgport);
 }
 
-/* get a fd that can be used to wait on the port asynchronously */
-int e_msgport_fd(EMsgPort *mp)
+int
+e_msgport_fd (EMsgPort *msgport)
 {
-	return mp->pipe.fd.read;
+	gint fd;
+
+	g_return_val_if_fail (msgport != NULL, -1);
+
+	g_async_queue_lock (msgport->queue);
+	fd = msgport->pipe[0];
+	if (fd < 0 && e_pipe (msgport->pipe) == 0)
+		fd = msgport->pipe[0];
+	g_async_queue_unlock (msgport->queue);
+
+	return fd;
 }
 
 #ifdef HAVE_NSS
-PRFileDesc *e_msgport_prfd(EMsgPort *mp)
+PRFileDesc *
+e_msgport_prfd (EMsgPort *msgport)
 {
-	return mp->prpipe.fd.read;
+	PRFileDesc *prfd;
+
+	g_return_val_if_fail (msgport != NULL, NULL);
+
+	g_async_queue_lock (msgport->queue);
+	prfd = msgport->prpipe[0];
+	if (prfd == NULL && e_prpipe (msgport->prpipe) == 0)
+		prfd = msgport->prpipe[0];
+	g_async_queue_unlock (msgport->queue);
+
+	return prfd;
 }
 #endif
 
-void e_msgport_put(EMsgPort *mp, EMsg *msg)
+void
+e_msgport_put (EMsgPort *msgport, EMsg *msg)
 {
+	gint fd;
 #ifdef HAVE_NSS
 	PRFileDesc *prfd;
 #endif
-	ssize_t w;
-	int fd;
-	
-	m(printf("put:\n"));
-	g_mutex_lock(mp->lock);
-	e_dlist_addtail(&mp->queue, &msg->ln);
-	if (mp->condwait > 0) {
-		m(printf("put: condwait > 0, waking up\n"));
-		g_cond_signal(mp->cond);
+
+	g_return_if_fail (msgport != NULL);
+	g_return_if_fail (msg != NULL);
+
+	g_async_queue_lock (msgport->queue);
+
+	msg->flags = 0;
+
+	fd = msgport->pipe[1];
+	while (fd >= 0) {
+		if (E_WRITE (fd, "E", 1) > 0) {
+			msg->flags |= MSG_FLAG_SYNC_WITH_PIPE;
+			break;
+		} else if (!E_IS_STATUS_INTR ())
+			break;
 	}
-	
-	fd = mp->pipe.fd.write;
-#ifdef HAVE_NSS
-	prfd = mp->prpipe.fd.write;
-#endif
-	g_mutex_unlock(mp->lock);
 
 #ifdef HAVE_NSS
-	if (prfd != NULL) {
-		m(printf("put: have pr pipe, writing notification to it\n"));
-		do {
-			w = PR_Write (prfd, "E", 1);
-		} while (w == -1 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR);
+	prfd = msgport->prpipe[1];
+	while (prfd != NULL) {
+		if (PR_Write (prfd, "E", 1) > 0) {
+			msg->flags |= MSG_FLAG_SYNC_WITH_PR_PIPE;
+			break;
+		} else if (PR_GetError () != PR_PENDING_INTERRUPT_ERROR)
+			break;
 	}
 #endif
-	if (fd != -1) {
-		m(printf("put: have pipe, writing notification to it\n"));
-		do {
-			w = E_WRITE (fd, "E", 1);
-		} while (w == -1 && E_IS_STATUS_INTR ());
-	}
 
-	m(printf("put: done\n"));
+	g_async_queue_push_unlocked (msgport->queue, msg);
+	g_async_queue_unlock (msgport->queue);
 }
 
-static void
-msgport_cleanlock(void *data)
+EMsg *
+e_msgport_wait (EMsgPort *msgport)
 {
-	EMsgPort *mp = data;
+	EMsg *msg;
 
-	g_mutex_unlock(mp->lock);
-}
+	g_return_val_if_fail (msgport != NULL, NULL);
 
-EMsg *e_msgport_wait(EMsgPort *mp)
-{
-	EMsg *msg;
+	g_async_queue_lock (msgport->queue);
 
-	m(printf("wait:\n"));
-	g_mutex_lock(mp->lock);
-	while (e_dlist_empty(&mp->queue)) {
-		if (mp->pipe.fd.read != -1) {
-			fd_set rfds;
-			int retry;
-
-			m(printf("wait: waiting on pipe\n"));
-			g_mutex_unlock(mp->lock);
-			do {
-				FD_ZERO(&rfds);
-				FD_SET(mp->pipe.fd.read, &rfds);
-				retry = E_IS_SOCKET_ERROR(select(mp->pipe.fd.read+1, &rfds, NULL, NULL, NULL)) && E_IS_STATUS_INTR();
-				pthread_testcancel();
-			} while (retry);
-			g_mutex_lock(mp->lock);
-			m(printf("wait: got pipe\n"));
-#ifdef HAVE_NSS
-		} else if (mp->prpipe.fd.read != NULL) {
-			PRPollDesc rfds[1];
-			int retry;
-
-			m(printf("wait: waitng on pr pipe\n"));
-			g_mutex_unlock(mp->lock);
-			do {
-				rfds[0].fd = mp->prpipe.fd.read;
-				rfds[0].in_flags = PR_POLL_READ|PR_POLL_ERR;
-				retry = PR_Poll(rfds, 1, PR_INTERVAL_NO_TIMEOUT) == -1 && PR_GetError() == PR_PENDING_INTERRUPT_ERROR;
-				pthread_testcancel();
-			} while (retry);
-			g_mutex_lock(mp->lock);
-			m(printf("wait: got pr pipe\n"));
-#endif /* HAVE_NSS */
-		} else {
-			m(printf("wait: waiting on condition\n"));
-			mp->condwait++;
-			/* if we are cancelled in the cond-wait, then we need to unlock our lock when we cleanup */
-			pthread_cleanup_push(msgport_cleanlock, mp);
-			g_cond_wait(mp->cond, mp->lock);
-			pthread_cleanup_pop(0);
-			m(printf("wait: got condition\n"));
-			mp->condwait--;
-		}
+	/* check the cache first */
+	if (msgport->cache != NULL) {
+		msg = msgport->cache;
+		/* don't clear the cache */
+		g_async_queue_unlock (msgport->queue);
+		return msg;
 	}
-	msg = (EMsg *)mp->queue.head;
-	m(printf("wait: message = %p\n", msg));
-	g_mutex_unlock(mp->lock);
-	m(printf("wait: done\n"));
+
+	msg = g_async_queue_pop_unlocked (msgport->queue);
+
+	g_assert (msg != NULL);
+
+	/* The message is not actually "removed" from the EMsgPort until
+ 	 * e_msgport_get() is called.  So we cache the popped message. */
+	msgport->cache = msg;
+
+	if (msg->flags & MSG_FLAG_SYNC_WITH_PIPE)
+		msgport_sync_with_pipe (msgport->pipe[0]);
+#ifdef HAVE_NSS
+	if (msg->flags & MSG_FLAG_SYNC_WITH_PR_PIPE)
+		msgport_sync_with_prpipe (msgport->prpipe[0]);
+#endif
+
+	g_async_queue_unlock (msgport->queue);
+
 	return msg;
 }
 
-EMsg *e_msgport_get(EMsgPort *mp)
+EMsg *
+e_msgport_get (EMsgPort *msgport)
 {
 	EMsg *msg;
-	char dummy[1];
-	ssize_t n;
-	
-	g_mutex_lock(mp->lock);
-	msg = (EMsg *)e_dlist_remhead(&mp->queue);
-	if (msg) {
-		if (mp->pipe.fd.read != -1) {
-			do {
-				n = E_READ (mp->pipe.fd.read, dummy, 1);
-			} while (n == -1 && E_IS_STATUS_INTR ());
-		}
+
+	g_return_val_if_fail (msgport != NULL, NULL);
+
+	g_async_queue_lock (msgport->queue);
+
+	/* check the cache first */
+	if (msgport->cache != NULL) {
+		msg = msgport->cache;
+		msgport->cache = NULL;
+		g_async_queue_unlock (msgport->queue);
+		return msg;
+	}
+
+	msg = g_async_queue_try_pop_unlocked (msgport->queue);
+
+	if (msg != NULL && msg->flags & MSG_FLAG_SYNC_WITH_PIPE)
+		msgport_sync_with_pipe (msgport->pipe[0]);
 #ifdef HAVE_NSS
-		if (mp->prpipe.fd.read != NULL) {
-			do {
-				n = PR_Read (mp->prpipe.fd.read, dummy, 1);
-			} while (n == -1 && PR_GetError () == PR_PENDING_INTERRUPT_ERROR);
-		}
+	if (msg != NULL && msg->flags & MSG_FLAG_SYNC_WITH_PR_PIPE)
+		msgport_sync_with_prpipe (msgport->prpipe[0]);
 #endif
-	}
-	m(printf("get: message = %p\n", msg));
-	g_mutex_unlock(mp->lock);
+
+	g_async_queue_unlock (msgport->queue);
 
 	return msg;
 }
 
-void e_msgport_reply(EMsg *msg)
+void
+e_msgport_reply (EMsg *msg)
 {
-	if (msg->reply_port) {
-		e_msgport_put(msg->reply_port, msg);
-	}
+	g_return_if_fail (msg != NULL);
+
+	if (msg->reply_port)
+		e_msgport_put (msg->reply_port, msg);
+
 	/* else lost? */
 }
 
--- evolution-data-server-1.8.0/libedataserver/e-msgport.h.emsgport	2004-12-02 22:33:06.000000000 -0500
+++ evolution-data-server-1.8.0/libedataserver/e-msgport.h	2006-09-15 12:27:21.000000000 -0400
@@ -56,6 +56,7 @@
 typedef struct _EMsg {
 	EDListNode ln;
 	EMsgPort *reply_port;
+	gint flags;
 } EMsg;
 
 EMsgPort *e_msgport_new(void);


Index: evolution-data-server.spec
===================================================================
RCS file: /cvs/dist/rpms/evolution-data-server/devel/evolution-data-server.spec,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -r1.121 -r1.122
--- evolution-data-server.spec	12 Sep 2006 13:48:18 -0000	1.121
+++ evolution-data-server.spec	15 Sep 2006 18:25:53 -0000	1.122
@@ -22,7 +22,7 @@
 
 Name: evolution-data-server
 Version: 1.8.0
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: LGPL
 Group: System Environment/Libraries
 Summary: Backend data server for Evolution
@@ -51,7 +51,7 @@
 Patch17: evolution-data-server-1.7.92-chain-finalize.patch
 
 # RH bug #198935 / Gnome.org bug #348888
-Patch18: evolution-data-server-1.8.0-msgport-pipes.patch
+Patch18: evolution-data-server-1.8.0-emsgport.patch
 
 ### Dependencies ###
 
@@ -137,7 +137,7 @@
 %patch15 -p1 -b .maybe-fix-crash
 %patch16 -p1 -b .fix-fd-leak
 %patch17 -p1 -b .chain-finalize
-%patch18 -p1 -b .msgport-pipes
+%patch18 -p1 -b .emsgport
 
 mkdir -p krb5-fakeprefix/include
 mkdir -p krb5-fakeprefix/lib
@@ -340,6 +340,9 @@
 %{_libdir}/pkgconfig/libexchange-storage-%{eds_api_version}.pc
 
 %changelog
+* Fri Sep 15 2006 Matthew Barnes <mbarnes at redhat.com> - 1.8.0-3.fc6
+- Revise patch for RH bug #198935 to eliminate a race condition.
+
 * Tue Sep 12 2006 Matthew Barnes <mbarnes at redhat.com> - 1.8.0-2.fc6
 - Add patch for RH bug #198935.
 


--- evolution-data-server-1.8.0-msgport-pipes.patch DELETED ---




More information about the fedora-cvs-commits mailing list