X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fxcb_ext.c;h=68bb29bdf2a6d320433a07ecd6304aaae984cb3d;hb=1c590d5a86ae854e53f388e40c952e92f11d59e6;hp=46a5519675cb859ca15918d43adca830d975e21f;hpb=47ceed78612d48dcda62cc2686fc527d61abe38b;p=free-sw%2Fxcb%2Flibxcb diff --git a/src/xcb_ext.c b/src/xcb_ext.c index 46a5519..68bb29b 100644 --- a/src/xcb_ext.c +++ b/src/xcb_ext.c @@ -32,15 +32,30 @@ #include "xcbext.h" #include "xcbint.h" -typedef struct { - enum { LAZY_COOKIE, LAZY_FORCED } tag; +typedef struct lazyreply { + enum lazy_reply_tag tag; union { - XCBQueryExtensionCookie cookie; - XCBQueryExtensionRep *reply; + xcb_query_extension_cookie_t cookie; + xcb_query_extension_reply_t *reply; } value; } lazyreply; -static lazyreply *get_lazyreply(XCBConnection *c, XCBExtension *ext) +static lazyreply *get_index(xcb_connection_t *c, int idx) +{ + if(idx > c->ext.extensions_size) + { + int new_size = idx << 1; + lazyreply *new_extensions = realloc(c->ext.extensions, sizeof(lazyreply) * new_size); + if(!new_extensions) + return 0; + memset(new_extensions + c->ext.extensions_size, 0, sizeof(lazyreply) * (new_size - c->ext.extensions_size)); + c->ext.extensions = new_extensions; + c->ext.extensions_size = new_size; + } + return c->ext.extensions + idx - 1; +} + +static lazyreply *get_lazyreply(xcb_connection_t *c, xcb_extension_t *ext) { static pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER; static int next_global_id; @@ -52,50 +67,42 @@ static lazyreply *get_lazyreply(XCBConnection *c, XCBExtension *ext) ext->global_id = ++next_global_id; pthread_mutex_unlock(&global_lock); - data = _xcb_map_get(c->ext.extensions, ext->global_id); - if(!data) + data = get_index(c, ext->global_id); + if(data && data->tag == LAZY_NONE) { /* cache miss: query the server */ - data = malloc(sizeof(lazyreply)); - if(!data) - return 0; data->tag = LAZY_COOKIE; - data->value.cookie = XCBQueryExtension(c, strlen(ext->name), ext->name); - _xcb_map_put(c->ext.extensions, ext->global_id, data); + data->value.cookie = xcb_query_extension(c, strlen(ext->name), ext->name); } return data; } -static void free_lazyreply(void *p) -{ - lazyreply *data = p; - if(data->tag == LAZY_FORCED) - free(data->value.reply); - free(data); -} - /* Public interface */ -/* Do not free the returned XCBQueryExtensionRep - on return, it's aliased +/* Do not free the returned xcb_query_extension_reply_t - on return, it's aliased * from the cache. */ -const XCBQueryExtensionRep *XCBGetExtensionData(XCBConnection *c, XCBExtension *ext) +const xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext) { lazyreply *data; + if(c->has_error) + return 0; pthread_mutex_lock(&c->ext.lock); data = get_lazyreply(c, ext); if(data && data->tag == LAZY_COOKIE) { data->tag = LAZY_FORCED; - data->value.reply = XCBQueryExtensionReply(c, data->value.cookie, 0); + data->value.reply = xcb_query_extension_reply(c, data->value.cookie, 0); } pthread_mutex_unlock(&c->ext.lock); return data ? data->value.reply : 0; } -void XCBPrefetchExtensionData(XCBConnection *c, XCBExtension *ext) +void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext) { + if(c->has_error) + return; pthread_mutex_lock(&c->ext.lock); get_lazyreply(c, ext); pthread_mutex_unlock(&c->ext.lock); @@ -103,20 +110,18 @@ void XCBPrefetchExtensionData(XCBConnection *c, XCBExtension *ext) /* Private interface */ -int _xcb_ext_init(XCBConnection *c) +int _xcb_ext_init(xcb_connection_t *c) { if(pthread_mutex_init(&c->ext.lock, 0)) return 0; - - c->ext.extensions = _xcb_map_new(); - if(!c->ext.extensions) - return 0; - return 1; } -void _xcb_ext_destroy(XCBConnection *c) +void _xcb_ext_destroy(xcb_connection_t *c) { pthread_mutex_destroy(&c->ext.lock); - _xcb_map_delete(c->ext.extensions, free_lazyreply); + while(c->ext.extensions_size-- > 0) + if(c->ext.extensions[c->ext.extensions_size].tag == LAZY_FORCED) + free(c->ext.extensions[c->ext.extensions_size].value.reply); + free(c->ext.extensions); }