[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