Merge branch 'fix-gldispatch-thread-state-leak' into 'master'
Fix a memory leak in libGLdispatch Closes #230 See merge request glvnd/libglvnd!265
This commit is contained in:
commit
7b892b72e0
|
@ -42,6 +42,13 @@
|
|||
*/
|
||||
static struct glvnd_list currentDispatchList;
|
||||
|
||||
/**
|
||||
* A linked list of __GLdispatchThreadStatePrivate structs that we've
|
||||
* allocated. This is used to make sure that we clean up if we get unloaded
|
||||
* while a thread is still current.
|
||||
*/
|
||||
static struct glvnd_list threadStatePrivateList;
|
||||
|
||||
/*
|
||||
* Number of clients using GLdispatch.
|
||||
*/
|
||||
|
@ -64,6 +71,8 @@ typedef struct __GLdispatchThreadStatePrivateRec {
|
|||
|
||||
/// The current (high-level) __GLdispatch table
|
||||
__GLdispatchTable *dispatch;
|
||||
|
||||
struct glvnd_list entry;
|
||||
} __GLdispatchThreadStatePrivate;
|
||||
|
||||
/*
|
||||
|
@ -178,6 +187,7 @@ void __glDispatchInit(void)
|
|||
glvnd_list_init(&extProcList);
|
||||
glvnd_list_init(¤tDispatchList);
|
||||
glvnd_list_init(&dispatchStubList);
|
||||
glvnd_list_init(&threadStatePrivateList);
|
||||
|
||||
// Register GLdispatch's static entrypoints for rewriting
|
||||
localDispatchStubId = RegisterStubCallbacks(stub_get_patch_callbacks());
|
||||
|
@ -588,8 +598,7 @@ PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchThreadState *threadState,
|
|||
|
||||
DispatchCurrentRef(dispatch);
|
||||
numCurrentContexts++;
|
||||
|
||||
UnlockDispatch();
|
||||
glvnd_list_add(&priv->entry, &threadStatePrivateList);
|
||||
|
||||
/*
|
||||
* Update the API state with the new values.
|
||||
|
@ -599,6 +608,8 @@ PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchThreadState *threadState,
|
|||
priv->threadState = threadState;
|
||||
threadState->priv = priv;
|
||||
|
||||
UnlockDispatch();
|
||||
|
||||
/*
|
||||
* Set the current state in TLS.
|
||||
*/
|
||||
|
@ -624,6 +635,7 @@ static void LoseCurrentInternal(__GLdispatchThreadState *curThreadState,
|
|||
DispatchCurrentUnref(curThreadState->priv->dispatch);
|
||||
}
|
||||
|
||||
glvnd_list_del(&curThreadState->priv->entry);
|
||||
free(curThreadState->priv);
|
||||
curThreadState->priv = NULL;
|
||||
}
|
||||
|
@ -722,6 +734,14 @@ void __glDispatchFini(void)
|
|||
clientRefcount--;
|
||||
|
||||
if (clientRefcount == 0) {
|
||||
while (!glvnd_list_is_empty(&threadStatePrivateList))
|
||||
{
|
||||
__GLdispatchThreadStatePrivate *priv = glvnd_list_first_entry(&threadStatePrivateList,
|
||||
__GLdispatchThreadStatePrivate, entry);
|
||||
glvnd_list_del(&priv->entry);
|
||||
free(priv);
|
||||
}
|
||||
|
||||
/* This frees the dispatchStubList */
|
||||
UnregisterAllStubCallbacks();
|
||||
|
||||
|
|
Loading…
Reference in a new issue