[evolution-patches] e-d-s: pthread_t opaqueness patch



This patch makes e-d-s treat pthread_t as an opaque type, which it is
according to the standard. (It is a struct in the pthreads-win32
implementation, also at least on HP-UX I think). Has been tested only
on Win32, so there might be some problem on Linux. Constructive
comments, please.

- pthread_t values must be compared for (in)equality with
pthread_compare(). 

- One cannot assign an integer to a pthread_t. Instead of using a
sentinel value to indicate nonexistence or invalidity, I use a
separate boolean flag.

- One cannot print a pthread_t as if it was an integer. I add a
function to libedataserver, const char *e_pthread_id(pthread_t), to
produce a "signature" of a thread. On Linux it is the pthread_t (an
unsigned long) directly in hex (or would decimal be better?), on other
platforms just the byte contents of the pthread_t in hex.

The diff to e-msgport.c also contains the socket API related diffs,
just skip those parts for now if you aren't interested.

--tml
Index: camel/camel-debug.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-debug.c,v
retrieving revision 1.3
diff -p -u -2 -r1.3 camel-debug.c
--- camel/camel-debug.c	6 Apr 2004 12:11:59 -0000	1.3
+++ camel/camel-debug.c	16 Aug 2005 22:27:52 -0000
@@ -26,4 +26,5 @@
 #include <pthread.h>
 
+#include "e-util.h"
 #include "camel-debug.h"
 
@@ -134,5 +135,5 @@ camel_debug_start(const char *mode)
 	if (camel_debug(mode)) {
 		pthread_mutex_lock(&debug_lock);
-		printf("Thread %lx >\n", pthread_self());
+		printf("Thread %s >\n", e_pthread_id(pthread_self());
 		return TRUE;
 	}
@@ -150,5 +151,5 @@ void
 camel_debug_end(void)
 {
-	printf("< %lx >\n", pthread_self());
+	printf("< %s >\n", e_pthread_id(pthread_self()));
 	pthread_mutex_unlock(&debug_lock);
 }
Index: camel/camel-object.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-object.c,v
retrieving revision 1.54
diff -p -u -2 -r1.54 camel-object.c
--- camel/camel-object.c	16 Aug 2005 06:14:40 -0000	1.54
+++ camel/camel-object.c	16 Aug 2005 23:09:50 -0000
@@ -91,4 +91,5 @@ struct _CamelObjectBagKey {
 	int waiters;		/* count of threads waiting for key */
 	pthread_t owner;	/* the thread that has reserved the bag for a new entry */
+	int have_owner;
 	GCond *cond;
 };
@@ -2018,9 +2016,9 @@ co_bag_unreserve(CamelObjectBag *bag, co
 
 	g_assert(res != NULL);
-	g_assert(res->owner == pthread_self());
+	g_assert(res->have_owner && pthread_equal(res->owner, pthread_self()));
 
 	if (res->waiters > 0) {
 		b(printf("unreserve bag '%s', waking waiters\n", (char *)key));
-		res->owner = 0;
+		res->have_owner = FALSE;
 		g_cond_signal(res->cond);
 	} else {
@@ -2122,5 +2120,5 @@ camel_object_bag_get(CamelObjectBag *bag
 
 			res->waiters++;
-			g_assert(res->owner != pthread_self());
+			g_assert(!res->have_owner || !pthread_equal(res->owner, pthread_self()));
 			g_cond_wait(res->cond, ref_lock);
 			res->waiters--;
@@ -2135,4 +2133,5 @@ camel_object_bag_get(CamelObjectBag *bag
 			/* we don't actually reserve it */
 			res->owner = pthread_self();
+			res->have_owner = TRUE;
 			co_bag_unreserve(bag, key);
 		}
@@ -2216,5 +2215,5 @@ camel_object_bag_reserve(CamelObjectBag 
 		if (res) {
 			b(printf("bag reserve %s, already reserved, waiting\n", (char *)key));
-			g_assert(res->owner != pthread_self());
+			g_assert(!res->have_owner || !pthread_equal(res->owner, pthread_self()));
 			res->waiters++;
 			g_cond_wait(res->cond, ref_lock);
@@ -2227,8 +2226,10 @@ camel_object_bag_reserve(CamelObjectBag 
 				/* in which case we dont need to reserve the bag either */
 				res->owner = pthread_self();
+				res->have_owner = TRUE;
 				co_bag_unreserve(bag, key);
 			} else {
 				b(printf("finished wait, now owner of '%s'\n", (char *)key));
 				res->owner = pthread_self();
+				res->have_owner = TRUE;
 			}
 		} else {
@@ -2239,4 +2240,5 @@ camel_object_bag_reserve(CamelObjectBag 
 			res->cond = g_cond_new();
 			res->owner = pthread_self();
+			res->have_owner = TRUE;
 			res->next = bag->reserved;
 			bag->reserved = res;
Index: camel/tests/lib/camel-test.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/tests/lib/camel-test.c,v
retrieving revision 1.8
diff -p -u -2 -r1.8 camel-test.c
--- camel/tests/lib/camel-test.c	9 Jul 2003 19:32:43 -0000	1.8
+++ camel/tests/lib/camel-test.c	16 Aug 2005 23:10:10 -0000
@@ -23,5 +25,4 @@ static pthread_mutex_t lock = PTHREAD_MU
 #define CAMEL_TEST_LOCK pthread_mutex_lock(&lock)
 #define CAMEL_TEST_UNLOCK pthread_mutex_unlock(&lock)
-#define CAMEL_TEST_ID (pthread_self())
 
 static int setup;
@@ -45,10 +46,30 @@ static GHashTable *info_table;
 int camel_test_verbose;
 
+static guint
+pthread_t_hash (gconstpointer v)
+{
+	const int *iv = (const int *) v;
+	int i;
+	guint hash = 0;
+
+	for (i = 0; i < sizeof (pthread_t) / sizeof (int); i++)
+		hash ^= iv[i];
+
+	return hash;
+}
+
+static gboolean
+pthread_t_equal (gconstpointer a,
+		 gconstpointer b)
+{
+	return pthread_equal (*(pthread_t *) a, *(pthread_t *) b);
+}
+
 static void
-dump_action(int id, struct _state *s, void *d)
+dump_action(pthread_t *id, struct _state *s, void *d)
 {
 	struct _stack *node;
 	
-	printf("\nThread %d:\n", id);
+	printf("\nThread %s:\n", e_pthread_id(*id));
 	
 	node = s->state;
@@ -74,5 +95,5 @@ static void die(int sig)
 		if (camel_test_verbose > 2) {
 			printf("Attach debugger to pid %d to debug\n", getpid());
-			sleep(1000);
+			g_usleep(1000000000);
 		}
 	}
@@ -85,12 +106,15 @@ current_state(void)
 {
 	struct _state *info;
+	pthread_t self = pthread_self();
 
 	if (info_table == NULL)
-		info_table = g_hash_table_new(0, 0);
+		info_table = g_hash_table_new(pthread_t_hash, pthread_t_equal);
 
-	info = g_hash_table_lookup(info_table, (void *)CAMEL_TEST_ID);
+	info = g_hash_table_lookup(info_table, &self);
 	if (info == NULL) {
+		pthread_t *key = g_malloc(sizeof(pthread_t));
+		*key = self;
 		info = g_malloc0(sizeof(*info));
-		g_hash_table_insert(info_table, (void *)CAMEL_TEST_ID, info);
+		g_hash_table_insert(info_table, key, info);
 	}
 	return info;
@@ -124,5 +148,5 @@ void camel_test_init(int argc, char **ar
 	camel_type_init ();
 	
-	info_table = g_hash_table_new(0, 0);
+	info_table = g_hash_table_new(pthread_t_hash, pthread_t_equal);
 	
 	signal(SIGSEGV, die);
@@ -266,6 +290,7 @@ void camel_test_failv(const char *why, v
 		ok=0;
 		if (camel_test_verbose > 1) {
+			pthread_t self = pthread_self();
 			printf("Known problem (ignored):\n");
-			dump_action(CAMEL_TEST_ID, s, 0);
+			dump_action(&self, s, 0);
 		}
 	}
Index: libedataserver/e-msgport.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserver/e-msgport.c,v
retrieving revision 1.3
diff -p -u -2 -r1.3 e-msgport.c
--- libedataserver/e-msgport.c	3 Dec 2004 03:33:06 -0000	1.3
+++ libedataserver/e-msgport.c	16 Aug 2005 23:10:25 -0000
@@ -40,10 +40,151 @@
 #endif
 
+#ifdef G_OS_WIN32
+#include <winsock2.h>
+#endif
+
 #include "e-msgport.h"
 
 #define m(x)			/* msgport debug */
-#define t(x) 			/* thread debug */
+#define t(x)			/* thread debug */
 #define c(x)			/* cache debug */
 
+#ifdef G_OS_WIN32
+#define E_CLOSE(socket) closesocket (socket)
+#define E_READ(socket,buf,nbytes) recv(socket,buf,nbytes,0)
+#define E_WRITE(socket,buf,nbytes) send(socket,buf,nbytes,0)
+#define E_IS_SOCKET_ERROR(status) ((status) == SOCKET_ERROR)
+#define E_IS_INVALID_SOCKET(socket) ((socket) == INVALID_SOCKET)
+#define E_IS_SELECT_STATUS_INTR() 0 /* No WSAEINTR errors in WinSock2  */
+#else
+#define E_CLOSE(fd) close (fd)
+#define E_READ(socket,buf,nbytes) read(socket,buf,nbytes)
+#define E_WRITE(socket,buf,nbytes) write(socket,buf,nbytes)
+#define E_IS_SOCKET_ERROR(status) ((status) == -1)
+#define E_IS_INVALID_SOCKET(socket) ((socket) < 0)
+#define E_IS_SELECT_STATUS_INTR() (errno == EINTR)
+#endif
+
+static int
+e_pipe (int *fds)
+{
+#ifndef G_OS_WIN32
+	return pipe (fds);
+#else
+	SOCKET temp, socket1 = -1, socket2 = -1;
+	struct sockaddr_in saddr;
+	int len;
+	u_long arg;
+	fd_set read_set, write_set;
+	struct timeval tv;
+
+	temp = socket (AF_INET, SOCK_STREAM, 0);
+	
+	if (temp == INVALID_SOCKET) {
+		goto out0;
+	}
+  	
+	arg = 1;
+	if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR) {
+		goto out0;
+	}
+
+	memset (&saddr, 0, sizeof (saddr));
+	saddr.sin_family = AF_INET;
+	saddr.sin_port = 0;
+	saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+
+	if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr))) {
+		goto out0;
+	}
+
+	if (listen (temp, 1) == SOCKET_ERROR) {
+		goto out0;
+	}
+
+	len = sizeof (saddr);
+	if (getsockname (temp, (struct sockaddr *)&saddr, &len)) {
+		goto out0;
+	}
+
+	socket1 = socket (AF_INET, SOCK_STREAM, 0);
+	
+	if (socket1 == INVALID_SOCKET) {
+		goto out0;
+	}
+
+	arg = 1;
+	if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) { 
+		goto out1;
+	}
+
+	if (connect (socket1, (struct sockaddr  *)&saddr, len) != SOCKET_ERROR ||
+	    WSAGetLastError () != WSAEWOULDBLOCK) {
+		goto out1;
+	}
+
+	FD_ZERO (&read_set);
+	FD_SET (temp, &read_set);
+
+	tv.tv_sec = 0;
+	tv.tv_usec = 0;
+
+	if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) {
+		goto out1;
+	}
+
+	if (!FD_ISSET (temp, &read_set)) {
+		goto out1;
+	}
+
+	socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
+	if (socket2 == INVALID_SOCKET) {
+		goto out1;
+	}
+
+	FD_ZERO (&write_set);
+	FD_SET (socket1, &write_set);
+
+	tv.tv_sec = 0;
+	tv.tv_usec = 0;
+
+	if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) {
+		goto out2;
+	}
+
+	if (!FD_ISSET (socket1, &write_set)) {
+		goto out2;
+	}
+
+	arg = 0;
+	if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR) {
+		goto out2;
+	}
+
+	arg = 0;
+	if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR) {
+		goto out2;
+	}
+
+	fds[0] = socket1;
+	fds[1] = socket2;
+
+	closesocket (temp);
+
+	return 0;
+
+out2:
+	closesocket (socket2);
+out1:
+	closesocket (socket1);
+out0:
+	closesocket (temp);
+	errno = EIO;		/* XXX */
+
+	return -1;
+
+#endif
+}
+
 void e_dlist_init(EDList *v)
 {
@@ -380,6 +521,6 @@ void e_msgport_destroy(EMsgPort *mp)
 	g_cond_free(mp->cond);
 	if (mp->pipe.fd.read != -1) {
-		close(mp->pipe.fd.read);
-		close(mp->pipe.fd.write);
+		E_CLOSE(mp->pipe.fd.read);
+		E_CLOSE(mp->pipe.fd.write);
 	}
 #ifdef HAVE_NSS
@@ -400,5 +541,5 @@ int e_msgport_fd(EMsgPort *mp)
 	fd = mp->pipe.fd.read;
 	if (fd == -1) {
-		pipe(mp->pipe.pipe);
+		e_pipe(mp->pipe.pipe);
 		fd = mp->pipe.fd.read;
 	}
@@ -416,5 +557,12 @@ PRFileDesc *e_msgport_prfd(EMsgPort *mp)
 	fd = mp->prpipe.read;
 	if (fd == NULL) {
+#ifdef G_OS_WIN32
+		PRFileDesc *fds[2];
+		PR_NewTCPSocketPair (fds);
+		mp->prpipe.read = fds[0];
+		mp->prpipe.write = fds[1];
+#else
 		PR_CreatePipe(&mp->prpipe.read, &mp->prpipe.write);
+#endif
 		fd = mp->prpipe.read;
 	}
@@ -447,5 +595,5 @@ void e_msgport_put(EMsgPort *mp, EMsg *m
 	if (fd != -1) {
 		m(printf("put: have pipe, writing notification to it\n"));
-		write(fd, "", 1);
+		E_WRITE(fd, "", 1);
 	}
 
@@ -483,5 +631,5 @@ EMsg *e_msgport_wait(EMsgPort *mp)
 				FD_ZERO(&rfds);
 				FD_SET(mp->pipe.fd.read, &rfds);
-				retry = select(mp->pipe.fd.read+1, &rfds, NULL, NULL, NULL) == -1 && errno == EINTR;
+				retry = E_IS_SOCKET_ERROR(select(mp->pipe.fd.read+1, &rfds, NULL, NULL, NULL)) && E_IS_SELECT_STATUS_INTR();
 				pthread_testcancel();
 			} while (retry);
@@ -531,5 +679,5 @@ EMsg *e_msgport_get(EMsgPort *mp)
 	if (msg) {
 		if (mp->pipe.fd.read != -1)
-			read(mp->pipe.fd.read, dummy, 1);
+			E_READ(mp->pipe.fd.read, dummy, 1);
 #ifdef HAVE_NSS
 		if (mp->prpipe.read != NULL) {
@@ -570,5 +718,6 @@ struct _EThread {
 
 	int waiting;		/* if we are waiting for a new message, count of waiting processes */
-	pthread_t id;		/* id of our running child thread */
+	pthread_t id;		/* our running child thread */
+	int have_thread;
 	GList *id_list;		/* if THREAD_NEW, then a list of our child threads in thread_info structs */
 
@@ -585,7 +734,7 @@ struct _EThread {
 /* All active threads */
 static EDList ethread_list = E_DLIST_INITIALISER(ethread_list);
+static int e_thread_counter = 0;
 static pthread_mutex_t ethread_lock = PTHREAD_MUTEX_INITIALIZER;
 
-#define E_THREAD_NONE ((pthread_t)~0)
 #define E_THREAD_QUIT_REPLYPORT ((struct _EMsgPort *)~0)
 
@@ -600,5 +749,5 @@ static struct _thread_info *thread_find(
 	while (node) {
 		info = node->data;
-		if (info->id == id)
+		if (pthread_equal (info->id, id))
 			return info;
 		node = node->next;
@@ -616,5 +765,5 @@ static void thread_remove(EThread *e, pt
 	while (node) {
 		info = node->data;
-		if (info->id == id) {
+		if (pthread_equal (info->id, id)) {
 			e->id_list = g_list_remove(e->id_list, info);
 			g_free(info);
@@ -633,5 +782,5 @@ EThread *e_thread_new(e_thread_t type)
 	e->type = type;
 	e->server_port = e_msgport_new();
-	e->id = E_THREAD_NONE;
+	e->have_thread = FALSE;
 	e->queue_limit = INT_MAX;
 
@@ -662,10 +811,9 @@ void e_thread_destroy(EThread *e)
 	case E_THREAD_DROP:
 		/* if we have a thread, 'kill' it */
-		if (e->id != E_THREAD_NONE) {
+		if (e->have_thread) {
 			pthread_t id = e->id;
+			t(printf("Sending thread '%s' quit message\n", e_pthread_id(id)));
 
-			t(printf("Sending thread '%d' quit message\n", id));
-
-			e->id = E_THREAD_NONE;
+			e->have_thread = FALSE;
 
 			msg = g_malloc0(sizeof(*msg));
@@ -674,10 +822,10 @@ void e_thread_destroy(EThread *e)
 
 			pthread_mutex_unlock(&e->mutex);
-			t(printf("Joining thread '%d'\n", id));
-			pthread_join(id, 0);
-			t(printf("Joined thread '%d'!\n", id));
+			t(printf("Joining thread '%s'\n", e_pthread_id(id)));
+			pthread_join(e->id, 0);
+			t(printf("Joined thread '%s'!\n", e_pthread_id(id)));
 			pthread_mutex_lock(&e->mutex);
 		}
-		busy = e->id != E_THREAD_NONE;
+		busy = e->have_thread;
 		break;
 	case E_THREAD_NEW:
@@ -686,5 +834,5 @@ void e_thread_destroy(EThread *e)
 		while (l) {
 			info = l->data;
-			t(printf("Sending thread '%d' quit message\n", info->id));
+			t(printf("Sending thread '%s' quit message\n", e_pthread_id(info->id)));
 			msg = g_malloc0(sizeof(*msg));
 			msg->reply_port = E_THREAD_QUIT_REPLYPORT;
@@ -698,7 +846,7 @@ void e_thread_destroy(EThread *e)
 			e->id_list = g_list_remove(e->id_list, info);
 			pthread_mutex_unlock(&e->mutex);
-			t(printf("Joining thread '%d'\n", info->id));
+			t(printf("Joining thread '%s'\n", e_pthread_id(info->id)));
 			pthread_join(info->id, 0);
-			t(printf("Joined thread '%d'!\n", info->id));
+			t(printf("Joined thread '%s'!\n", e_pthread_id(info->id)));
 			pthread_mutex_lock(&e->mutex);
 			g_free(info);
@@ -783,5 +931,5 @@ int e_thread_busy(EThread *e)
 		case E_THREAD_QUEUE:
 		case E_THREAD_DROP:
-			busy = e->waiting != 1 && e->id != E_THREAD_NONE;
+			busy = e->waiting != 1 && e->have_thread;
 			break;
 		case E_THREAD_NEW:
@@ -854,5 +1002,5 @@ thread_dispatch(void *din)
 	pthread_t self = pthread_self();
 
-	t(printf("dispatch thread started: %ld\n", pthread_self()));
+	t(printf("dispatch thread started: %s\n", e_pthread_id(self)));
 
 	while (1) {
@@ -887,5 +1035,5 @@ thread_dispatch(void *din)
 			continue;
 		} else if (m->reply_port == E_THREAD_QUIT_REPLYPORT) {
-			t(printf("Thread %d got quit message\n", self));
+			t(printf("Thread %s got quit message\n", e_pthread_id(self)));
 			/* Handle a quit message, say we're quitting, free the message, and break out of the loop */
 			info = thread_find(e, self);
@@ -965,5 +1113,5 @@ void e_thread_put(EThread *e, EMsg *msg)
 		    && pthread_create(&id, NULL, thread_dispatch, e) == 0) {
 			struct _thread_info *info = g_malloc0(sizeof(*info));
-			t(printf("created NEW thread %ld\n", id));
+			t(printf("created NEW thread %s\n", e_pthread_id(id)));
 			info->id = id;
 			info->busy = TRUE;
@@ -975,10 +1123,10 @@ void e_thread_put(EThread *e, EMsg *msg)
 
 	/* create the thread, if there is none to receive it yet */
-	if (e->id == E_THREAD_NONE) {
+	if (!e->have_thread) {
 		int err;
 
 		if ((err = pthread_create(&e->id, NULL, thread_dispatch, e)) != 0) {
 			g_warning("Could not create dispatcher thread, message queued?: %s", strerror(err));
-			e->id = E_THREAD_NONE;
+			e->have_thread = FALSE;
 		}
 	}
@@ -996,4 +1144,5 @@ struct _EMutex {
 	int type;
 	pthread_t owner;
+	int have_owner;
 	short waiters;
 	short depth;
@@ -1014,5 +1163,5 @@ EMutex *e_mutex_new(e_mutex_t type)
 	m->waiters = 0;
 	m->depth = 0;
-	m->owner = E_THREAD_NONE;
+	m->have_owner = FALSE;
 
 	switch (type) {
@@ -1067,9 +1216,10 @@ int e_mutex_lock(EMutex *m)
 			return err;
 		while (1) {
-			if (m->owner == E_THREAD_NONE) {
+			if (!m->have_owner) {
 				m->owner = id;
+				m->have_owner = TRUE;
 				m->depth = 1;
 				break;
-			} else if (id == m->owner) {
+			} else if (pthread_equal (id, m->owner)) {
 				m->depth++;
 				break;
@@ -1097,9 +1247,9 @@ int e_mutex_unlock(EMutex *m)
 		if ((err = pthread_mutex_lock(&m->mutex)) != 0)
 			return err;
-		g_assert(m->owner == pthread_self());
+		g_assert(m->have_owner && pthread_equal(m->owner, pthread_self()));
 
 		m->depth--;
 		if (m->depth == 0) {
-			m->owner = E_THREAD_NONE;
+			m->have_owner = FALSE;
 			if (m->waiters > 0)
 				pthread_cond_signal(&m->cond);
@@ -1116,5 +1266,5 @@ void e_mutex_assert_locked(EMutex *m)
 	g_return_if_fail (m->type == E_MUTEX_REC);
 	pthread_mutex_lock(&m->mutex);
-	g_assert(m->owner == pthread_self());
+	g_assert(m->have_owner && pthread_equal(m->owner, pthread_self()));
 	pthread_mutex_unlock(&m->mutex);
 }
@@ -1131,7 +1281,7 @@ int e_mutex_cond_wait(void *vcond, EMute
 		if ((ret = pthread_mutex_lock(&m->mutex)) != 0)
 			return ret;
-		g_assert(m->owner == pthread_self());
+		g_assert(m->have_owner && pthread_equal(m->owner, pthread_self()));
 		ret = pthread_cond_wait(cond, &m->mutex);
-		g_assert(m->owner == pthread_self());
+		g_assert(m->have_owner && pthread_equal(m->owner, pthread_self()));
 		pthread_mutex_unlock(&m->mutex);
 		return ret;
@@ -1164,5 +1314,5 @@ void *fdserver(void *data)
 		while ((msg = e_msgport_get(server_port))) {
 			printf("server %d: got message\n", id);
-			sleep(1);
+			g_usleep(1000000);
 			printf("server %d: replying\n", id);
 			e_msgport_reply(msg);
@@ -1184,5 +1334,5 @@ void *server(void *data)
 		if (msg) {
 			printf("server %d: got message\n", id);
-			sleep(1);
+			g_usleep(1000000);
 			printf("server %d: replying\n", id);
 			e_msgport_reply(msg);
@@ -1213,5 +1363,5 @@ void *client(void *data)
 
 	printf("client: sleeping ...\n");
-	sleep(2);
+	g_usleep(2000000);
 	printf("client: sending multiple\n");
 
@@ -1244,5 +1394,5 @@ int main(int argc, char **argv)
 	pthread_create(&clientid, NULL, client, NULL);
 
-	sleep(60);
+	g_usleep(60000000);
 
 	return 0;
Index: libedataserver/e-util.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserver/e-util.c,v
retrieving revision 1.7
diff -p -u -2 -r1.7 e-util.c
--- libedataserver/e-util.c	6 Jul 2005 16:01:42 -0000	1.7
+++ libedataserver/e-util.c	16 Aug 2005 23:39:40 -0000
@@ -375,2 +375,26 @@ e_utf8_strftime(char *s, size_t max, con
 	return sz;
 }
+const char *
+e_pthread_id(pthread_t t)
+{
+	static char buffer[100];
+	char *p = buffer;
+
+#ifdef __linux
+	/* We know that pthread_t is an unsigned long */
+	sprintf(p, "%lu", t);
+#else
+	/* Just print out the contents of the pthred_t */
+	{
+		guchar *const tend = (guchar *) ((&t)+1);
+		guchar *tp = (guchar *) &t;
+		while (tp < tend) {
+			p += sprintf (p, "%02x", *tp);
+			tp++;
+			if (tp < tend)
+				*p++ = ':';
+		}
+	}
+#endif
+	return buffer;
+}
Index: libedataserver/e-util.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserver/e-util.h,v
retrieving revision 1.5
diff -p -u -2 -r1.5 e-util.h
--- libedataserver/e-util.h	24 Mar 2005 18:23:37 -0000	1.5
+++ libedataserver/e-util.h	16 Aug 2005 23:10:27 -0000
@@ -23,4 +23,5 @@
 #define __E_UTIL_H__
 
+#include <pthread.h>
 #include <sys/types.h>
 #include <glib/gmacros.h>
@@ -38,4 +39,13 @@ gchar       *e_util_unicode_get_utf8 (co
 const gchar *e_util_utf8_strstrcase (const gchar *haystack, const gchar *needle);
 const gchar *e_util_utf8_strstrcasedecomp (const gchar *haystack, const gchar *needle);
+
+/* Return an string hopefully uniquely identifying the thread. To be
+ * used in debugging output and logging only. No guarantee that
+ * calling e_pthread_id() on two threads than didn't coexist won't
+ * return the same string, or that when called again on the same
+ * thread the string will be 100% identical. The return value is the
+ * same static buffer each time, so use accordingly.
+ */
+const char *e_pthread_id(pthread_t t);
 
 size_t e_utf8_strftime(char *s, size_t max, const char *fmt, const struct tm *tm);
Index: libedataserverui/e-passwords.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-passwords.c,v
retrieving revision 1.28
diff -p -u -2 -r1.28 e-passwords.c
--- libedataserverui/e-passwords.c	5 Aug 2005 06:48:14 -0000	1.28
+++ libedataserverui/e-passwords.c	16 Aug 2005 23:10:28 -0000
@@ -141,5 +141,5 @@ ep_msg_new(void (*dispatch)(EPassMsg *))
 	msg->msg.reply_port = e_msgport_new();
 #ifdef ENABLE_THREADS
-	msg->ismain = pthread_self() == main_thread;
+	msg->ismain = pthread_equal(pthread_self(), main_thread);
 #else
 	msg->ismain = TRUE;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]