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 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 */

View File

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