dix: make DeleteCallbackList() non-static and document it

Allow using it by other places outside this file, so we can also support
callback lists in dynamically allocated structures:

Those cases need to explicitly call DeleteCallbackList() before free()ing
the structures - otherwise we're getting heap corruptions, because the
actual deletion can happen asynchronously.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-04-23 19:59:06 +02:00
parent a110b3e02e
commit 48ca8adc6d
2 changed files with 17 additions and 14 deletions

View File

@ -10,4 +10,15 @@
void InitCallbackManager(void); void InitCallbackManager(void);
void DeleteCallbackManager(void); void DeleteCallbackManager(void);
/*
* @brief delete a callback list
*
* Calling this is necessary if a CallbackListPtr is used inside a dynamically
* allocated structure, before it is freed. If it's not done, memory corruption
* or segfault can happen at a much later point (eg. next server incarnation)
*
* @param pcbl pointer to the list head (CallbackListPtr)
*/
void DeleteCallbackList(CallbackListPtr *pcbl);
#endif /* _XSERVER_CALLBACK_PRIV_H */ #endif /* _XSERVER_CALLBACK_PRIV_H */

View File

@ -693,8 +693,6 @@ _DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data)
return FALSE; return FALSE;
} }
static void DeleteCallbackList(CallbackListPtr *pcbl);
void void
_CallCallbacks(CallbackListPtr *pcbl, void *call_data) _CallCallbacks(CallbackListPtr *pcbl, void *call_data)
{ {
@ -745,25 +743,26 @@ _CallCallbacks(CallbackListPtr *pcbl, void *call_data)
} }
} }
static void void DeleteCallbackList(CallbackListPtr *pcbl)
_DeleteCallbackList(CallbackListPtr *pcbl)
{ {
if (!pcbl || !*pcbl)
return;
CallbackListPtr cbl = *pcbl; CallbackListPtr cbl = *pcbl;
CallbackPtr cbr, nextcbr;
int i;
if (cbl->inCallback) { if (cbl->inCallback) {
cbl->deleted = TRUE; cbl->deleted = TRUE;
return; return;
} }
for (i = 0; i < numCallbackListsToCleanup; i++) { for (int i = 0; i < numCallbackListsToCleanup; i++) {
if (listsToCleanup[i] == pcbl) { if (listsToCleanup[i] == pcbl) {
listsToCleanup[i] = NULL; listsToCleanup[i] = NULL;
break; break;
} }
} }
CallbackPtr cbr, nextcbr;
for (cbr = cbl->list; cbr != NULL; cbr = nextcbr) { for (cbr = cbl->list; cbr != NULL; cbr = nextcbr) {
nextcbr = cbr->next; nextcbr = cbr->next;
free(cbr); free(cbr);
@ -827,13 +826,6 @@ DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data)
return _DeleteCallback(pcbl, callback, data); return _DeleteCallback(pcbl, callback, data);
} }
static void DeleteCallbackList(CallbackListPtr *pcbl)
{
if (!pcbl || !*pcbl)
return;
_DeleteCallbackList(pcbl);
}
void void
DeleteCallbackManager(void) DeleteCallbackManager(void)
{ {