diff options
Diffstat (limited to 'libxcb/src/xcb_xid.c')
-rw-r--r-- | libxcb/src/xcb_xid.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/libxcb/src/xcb_xid.c b/libxcb/src/xcb_xid.c index 7ff0c5fc2..3df5dbec6 100644 --- a/libxcb/src/xcb_xid.c +++ b/libxcb/src/xcb_xid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp. +/* Copyright (C) 2001-2008 Bart Massey and Jamey Sharp. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ /* XID allocators. */ +#include <assert.h> #include <stdlib.h> #include "xcb.h" #include "xcbext.h" @@ -39,21 +40,40 @@ uint32_t xcb_generate_id(xcb_connection_t *c) if(c->has_error) return -1; pthread_mutex_lock(&c->xid.lock); - if(c->xid.last == c->xid.max) + if(c->xid.last >= c->xid.max - c->xid.inc + 1) { xcb_xc_misc_get_xid_range_reply_t *range; - range = xcb_xc_misc_get_xid_range_reply(c, xcb_xc_misc_get_xid_range(c), 0); - if(!range) - { - pthread_mutex_unlock(&c->xid.lock); - return -1; + assert(c->xid.last == c->xid.max); + if (c->xid.last == 0) { + /* finish setting up initial range */ + c->xid.max = c->setup->resource_id_mask; + } else { + /* check for extension */ + const xcb_query_extension_reply_t *xc_misc_reply = + xcb_get_extension_data(c, &xcb_xc_misc_id); + if (!xc_misc_reply) { + pthread_mutex_unlock(&c->xid.lock); + return -1; + } + /* get new range */ + range = xcb_xc_misc_get_xid_range_reply(c, + xcb_xc_misc_get_xid_range(c), 0); + /* XXX The latter disjunct is what the server returns + when it is out of XIDs. Sweet. */ + if(!range || (range->start_id == 0 && range->count == 1)) + { + pthread_mutex_unlock(&c->xid.lock); + return -1; + } + assert(range->count > 0 && range->start_id > 0); + c->xid.last = range->start_id; + c->xid.max = range->start_id + (range->count - 1) * c->xid.inc; + free(range); } - c->xid.last = range->start_id; - c->xid.max = range->start_id + (range->count - 1) * c->xid.inc; - free(range); + } else { + c->xid.last += c->xid.inc; } ret = c->xid.last | c->xid.base; - c->xid.last += c->xid.inc; pthread_mutex_unlock(&c->xid.lock); return ret; } @@ -65,8 +85,8 @@ int _xcb_xid_init(xcb_connection_t *c) if(pthread_mutex_init(&c->xid.lock, 0)) return 0; c->xid.last = 0; + c->xid.max = 0; c->xid.base = c->setup->resource_id_base; - c->xid.max = c->setup->resource_id_mask; c->xid.inc = c->setup->resource_id_mask & -(c->setup->resource_id_mask); return 1; } |