[Xcb-commit] 2 commits - reply wm

Jamey Sharp jamey at kemper.freedesktop.org
Sat Oct 7 15:13:32 PDT 2006


 reply/reply.c      |  102 +++++++++++++++++++++++++----------------------------
 reply/test_reply.c |   18 ++++++---
 reply/xcb_reply.h  |    4 +-
 wm/manage.c        |    2 -
 4 files changed, 65 insertions(+), 61 deletions(-)

New commits:
diff-tree 4855f61ddb172e8f608083025775d155566979d5 (from 3f3758754a02a231ffb4ec79fc95a6d4d84c9d44)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Sat Oct 7 15:13:04 2006 -0700

    PropertyChanged was renamed to property_changed: update wm/manage.c.

diff --git a/wm/manage.c b/wm/manage.c
index 405d377..8c7b295 100644
--- a/wm/manage.c
+++ b/wm/manage.c
@@ -48,7 +48,7 @@ void manageWindow(property_handlers_t *p
 	if(attr && geom)
 	{
 		reparentWindow(c, window, attr->visual, geom->root, geom->depth, geom->x, geom->y, geom->width, geom->height);
-		PropertyChanged(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_NAME);
+		property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_NAME);
 	}
 	free(attr);
 	free(geom);
diff-tree 3f3758754a02a231ffb4ec79fc95a6d4d84c9d44 (from 8cbe72cf7dae11d3944a9f45973c11bcd3867952)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Sat Oct 7 15:12:35 2006 -0700

    Use xcb_poll_for_reply instead of the now-gone xcb_get_request_read.
    
    Rename stop_reply_threads to stop_reply_thread, since there should be
    only one.
    
    Don't return the thread id from start_reply_thread; track it internally
    and pthread_cancel/pthread_join it directly in stop_reply_thread.
    
    Fix the test app for these threading changes.

diff --git a/reply/reply.c b/reply/reply.c
index 794d91f..6f90883 100644
--- a/reply/reply.c
+++ b/reply/reply.c
@@ -16,7 +16,7 @@ struct reply_handlers {
 	pthread_cond_t cond;
 	struct node *head;
 	xcb_connection_t *c;
-	char stop;
+	pthread_t thread;
 };
 
 reply_handlers_t *alloc_reply_handlers(xcb_connection_t *c)
@@ -52,78 +52,74 @@ static void insert_handler(reply_handler
 	*prev = cur;
 }
 
-static int do_poll(reply_handlers_t *h)
+static void remove_handler(reply_handlers_t *h, struct node *cur)
 {
-	xcb_generic_reply_t *reply;
-	xcb_generic_error_t *error;
-	int handled;
-	struct node *cur = h->head;
-	h->head = cur->next;
-
-	pthread_mutex_unlock(&h->lock);
-	pthread_cleanup_push((void (*)(void *)) pthread_mutex_lock, &h->lock);
-	reply = xcb_wait_for_reply(h->c, cur->request, &error);
+	struct node **prev = &h->head;
+	while(*prev && (*prev)->request < cur->request)
+		prev = &(*prev)->next;
+	if(!(*prev) || (*prev)->request != cur->request)
+		return;
+	*prev = cur->next;
+	free(cur);
+}
 
-	if(reply || error)
-	{
-		cur->handler(cur->data, h->c, reply, error);
-		handled = cur->handled = 1;
-		free(reply);
-		free(error);
-	}
-	else
+static int process_replies(reply_handlers_t *h, int block)
+{
+	int handled = 0;
+	pthread_mutex_lock(&h->lock);
+	pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, &h->lock);
+	while(1)
 	{
-		handled = cur->handled;
-		free(cur);
+		struct node *cur = h->head;
+		xcb_generic_error_t *error;
+		void *reply;
+		pthread_mutex_unlock(&h->lock);
+		pthread_cleanup_push((void (*)(void *)) pthread_mutex_lock, &h->lock);
+		if(block)
+			reply = xcb_wait_for_reply(h->c, cur->request, &error);
+		else if(!xcb_poll_for_reply(h->c, cur->request, &reply, &error))
+			return handled;
+		if(reply || error)
+		{
+			cur->handler(cur->data, h->c, reply, error);
+			cur->handled = 1;
+			free(reply);
+			free(error);
+		}
+		handled |= cur->handled;
+		pthread_cleanup_pop(1);
+		if(!reply)
+			remove_handler(h, cur);
+		if(!h->head)
+			if(block)
+				pthread_cond_wait(&h->cond, &h->lock);
+			else
+				break;
 	}
-
 	pthread_cleanup_pop(1);
-	if(reply || error)
-		insert_handler(h, cur);
-	return handled;
 }
 
 int poll_replies(reply_handlers_t *h)
 {
-	int ret = 1;
 	xcb_flush(h->c);
-	pthread_mutex_lock(&h->lock);
-	while(ret && h->head && xcb_get_request_read(h->c) >= h->head->request)
-		ret = do_poll(h);
-	pthread_mutex_unlock(&h->lock);
-	return ret;
+	return process_replies(h, 0);
 }
 
-static void *reply_thread(void *hvp)
+static void *reply_thread(void *h)
 {
-	reply_handlers_t *h = hvp;
-	pthread_mutex_lock(&h->lock);
-	pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, &h->lock);
-	while(1)
-	{
-		while(h->head)
-			do_poll(h);
-		if(h->stop)
-			break;
-		pthread_cond_wait(&h->cond, &h->lock);
-	}
-	pthread_cleanup_pop(1);
+	process_replies(h, 1);
 	return 0;
 }
 
-pthread_t start_reply_thread(reply_handlers_t *h)
+void start_reply_thread(reply_handlers_t *h)
 {
-	pthread_t ret;
-	pthread_create(&ret, 0, reply_thread, h);
-	return ret;
+	pthread_create(&h->thread, 0, reply_thread, h);
 }
 
-void stop_reply_threads(reply_handlers_t *h)
+void stop_reply_thread(reply_handlers_t *h)
 {
-	pthread_mutex_lock(&h->lock);
-	h->stop = 1;
-	pthread_cond_broadcast(&h->cond);
-	pthread_mutex_unlock(&h->lock);
+	pthread_cancel(h->thread);
+	pthread_join(h->thread, 0);
 }
 
 void add_reply_handler(reply_handlers_t *h, unsigned int request, generic_reply_handler handler, void *data)
diff --git a/reply/test_reply.c b/reply/test_reply.c
index 7331a2b..8aee7d8 100644
--- a/reply/test_reply.c
+++ b/reply/test_reply.c
@@ -6,6 +6,9 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
 void fontinfo_handler(void *data, xcb_connection_t *c, xcb_generic_reply_t *rg, xcb_generic_error_t *eg)
 {
 	xcb_list_fonts_with_info_reply_t *rep = (xcb_list_fonts_with_info_reply_t *) rg;
@@ -17,7 +20,12 @@ void fontinfo_handler(void *data, xcb_co
 					(unsigned int) rep->replies_hint,
 					len, xcb_list_fonts_with_info_name(rep));
 		else
+		{
+			pthread_mutex_lock(&lock);
+			pthread_cond_broadcast(&cond);
+			pthread_mutex_unlock(&lock);
 			printf("End of font list.\n");
+		}
 	}
 	if(eg)
 		printf("Error from ListFontsWithInfo: %d\n", eg->error_code);
@@ -29,7 +37,6 @@ int main(int argc, char **argv)
 	char *pattern = "*";
 	xcb_connection_t *c = xcb_connect(NULL, NULL);
 	reply_handlers_t *h = alloc_reply_handlers(c);
-	pthread_t reply_thread;
 
 	if(argc > 1)
 		count = atoi(argv[1]);
@@ -37,11 +44,12 @@ int main(int argc, char **argv)
 		pattern = argv[2];
 	
 	add_reply_handler(h, xcb_list_fonts_with_info(c, count, strlen(pattern), pattern).sequence, fontinfo_handler, 0);
-	reply_thread = start_reply_thread(h);
+	pthread_mutex_lock(&lock);
+	start_reply_thread(h);
+	pthread_cond_wait(&cond, &lock);
+	stop_reply_thread(h);
+	pthread_mutex_unlock(&lock);
 
-	free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL));
-	stop_reply_threads(h);
-	pthread_join(reply_thread, 0);
 	xcb_disconnect(c);
 	exit(0);
 }
diff --git a/reply/xcb_reply.h b/reply/xcb_reply.h
index de664eb..8a9e71e 100644
--- a/reply/xcb_reply.h
+++ b/reply/xcb_reply.h
@@ -16,8 +16,8 @@ void free_reply_handlers(reply_handlers_
 xcb_connection_t *get_xcb_connection(reply_handlers_t *h);
 
 int poll_replies(reply_handlers_t *h);
-pthread_t start_reply_thread(reply_handlers_t *h);
-void stop_reply_threads(reply_handlers_t *h);
+void start_reply_thread(reply_handlers_t *h);
+void stop_reply_thread(reply_handlers_t *h);
 
 typedef void (*generic_reply_handler)(void *data, xcb_connection_t *c, xcb_generic_reply_t *reply, xcb_generic_error_t *error);
 


More information about the xcb-commit mailing list