GLX: Use XESetCloseDisplay for the close display callback.

libGLX will now use XAddExtension and XESetCloseDisplay to register a callback
when a display is closed.

Removed XGLVRegisterCloseDisplayCallback and
XGLVUnregisterCloseDisplayCallbacks from the x11glvnd client library.

This is in preparation for removing the x11glvnd extension.
This commit is contained in:
Kyle Brenneman 2016-03-07 13:52:19 -07:00
parent af2aeb0b42
commit 3f4674f8f6
5 changed files with 37 additions and 81 deletions

View file

@ -549,10 +549,9 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext context)
}
}
void DisplayClosed(Display *dpy)
void __glXDisplayClosed(Display *dpy, __GLXdisplayInfo *dpyInfo)
{
__GLXAPIState *apiState;
__glXFreeDisplay(dpy);
apiState = __glXGetCurrentAPIState();
if (apiState != NULL && apiState->currentDisplay == dpy) {
@ -2026,9 +2025,6 @@ void _init(void)
/* TODO install fork handlers using __register_atfork */
/* Register our XCloseDisplay() callback */
XGLVRegisterCloseDisplayCallback(DisplayClosed);
DBG_PRINTF(0, "Loading GLX...\n");
}
@ -2053,10 +2049,6 @@ void _fini(void)
__glDispatchLoseCurrent();
}
/* Unregister all XCloseDisplay() callbacks */
XGLVUnregisterCloseDisplayCallbacks();
/* Tear down all GLX API state */
__glXAPITeardown(False);

View file

@ -722,6 +722,25 @@ static void CleanupDisplayInfoEntry(void *unused, __GLXdisplayInfoHash *pEntry)
pEntry->info.xidVendorHash, NULL, NULL, False);
}
static int OnDisplayClosed(Display *dpy, XExtCodes *codes)
{
__GLXdisplayInfoHash *pEntry = NULL;
LKDHASH_WRLOCK(__glXDisplayInfoHash);
HASH_FIND_PTR(_LH(__glXDisplayInfoHash), &dpy, pEntry);
if (pEntry != NULL) {
__glXDisplayClosed(dpy, &pEntry->info);
HASH_DEL(_LH(__glXDisplayInfoHash), pEntry);
}
LKDHASH_UNLOCK(__glXDisplayInfoHash);
CleanupDisplayInfoEntry(NULL, pEntry);
free(pEntry);
return 0;
}
__GLXdisplayInfo *__glXLookupDisplay(Display *dpy)
{
__GLXdisplayInfoHash *pEntry = NULL;
@ -750,9 +769,19 @@ __GLXdisplayInfo *__glXLookupDisplay(Display *dpy)
LKDHASH_WRLOCK(__glXDisplayInfoHash);
HASH_FIND_PTR(_LH(__glXDisplayInfoHash), &dpy, foundEntry);
if (foundEntry == NULL) {
XExtCodes *extCodes = XAddExtension(dpy);
if (extCodes == NULL) {
CleanupDisplayInfoEntry(NULL, pEntry);
free(pEntry);
LKDHASH_UNLOCK(__glXDisplayInfoHash);
return NULL;
}
XESetCloseDisplay(dpy, extCodes->extension, OnDisplayClosed);
HASH_ADD_PTR(_LH(__glXDisplayInfoHash), dpy, pEntry);
} else {
// Another thread already created the hashtable entry.
CleanupDisplayInfoEntry(NULL, pEntry);
free(pEntry);
pEntry = foundEntry;
}

View file

@ -135,6 +135,12 @@ __GLXdisplayInfo *__glXLookupDisplay(Display *dpy);
*/
void __glXFreeDisplay(Display *dpy);
/*!
* This is called to perform any context-related cleanup when a display is
* closed.
*/
void __glXDisplayClosed(Display *dpy, __GLXdisplayInfo *dpyInfo);
/*
* Close the vendor library and perform any relevant teardown. This should
* be called when the API library is unloaded.

View file

@ -78,18 +78,4 @@ char *XGLVQueryScreenVendorMapping(
int screen
);
/*
* Registers a callback with x11glvnd which is fired whenever XCloseDisplay()
* is called. This gives x11glvnd clients a lightweight alternative to
* declaring themselves an X11 extension and using XESetCloseDisplay().
*
* This is NOT a thread-safe operation.
*/
void XGLVRegisterCloseDisplayCallback(void (*callback)(Display *));
/*
* Unregisters all registered callbacks.
*/
void XGLVUnregisterCloseDisplayCallbacks(void);
#endif // __X11GLVND_H__

View file

@ -41,8 +41,6 @@
const char *xglv_ext_name = XGLV_EXTENSION_NAME;
static XExtensionInfo *xglv_ext_info = NULL;
static int close_display(Display *dpy, XExtCodes *codes);
static /* const */ XExtensionHooks xglv_ext_hooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
@ -50,7 +48,7 @@ static /* const */ XExtensionHooks xglv_ext_hooks = {
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
close_display, /* close_display */
NULL, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
@ -63,61 +61,6 @@ static XEXT_GENERATE_FIND_DISPLAY(find_display, xglv_ext_info,
&xglv_ext_hooks,
XGLV_NUM_EVENTS, NULL);
typedef struct CloseDisplayHookRec {
/*
* Callback function
*/
void (*callback)(Display *);
/*
* List entry
*/
struct glvnd_list entry;
} CloseDisplayHook;
static int closeDisplayHookListInitialized;
static struct glvnd_list closeDisplayHookList;
void XGLVRegisterCloseDisplayCallback(void (*callback)(Display *))
{
CloseDisplayHook *hook = malloc(sizeof(*hook));
hook->callback = callback;
if (!closeDisplayHookListInitialized) {
glvnd_list_init(&closeDisplayHookList);
}
glvnd_list_add(&hook->entry, &closeDisplayHookList);
}
void XGLVUnregisterCloseDisplayCallbacks(void)
{
CloseDisplayHook *curHook, *tmpHook;
glvnd_list_for_each_entry_safe(curHook, tmpHook, &closeDisplayHookList, entry) {
glvnd_list_del(&curHook->entry);
free(curHook);
}
assert(glvnd_list_is_empty(&closeDisplayHookList));
closeDisplayHookListInitialized = False;
}
static XEXT_GENERATE_CLOSE_DISPLAY(close_display_internal, xglv_ext_info);
static XEXT_CLOSE_DISPLAY_PROTO(close_display)
{
CloseDisplayHook *curHook;
/*
* Call any registered hooks before calling into the
* generated close_display() hook.
*/
glvnd_list_for_each_entry(curHook, &closeDisplayHookList, entry) {
curHook->callback(dpy);
}
return close_display_internal(dpy, codes);
}
#define CHECK_EXTENSION(dpy, i, val) \
do { \
if (!XextHasExtension(i)) { \