(!1714) 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:
		
							parent
							
								
									5cef2bc833
								
							
						
					
					
						commit
						3f9cbebcdf
					
				| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue