AcePerl
view release on metacpan or search on metacpan
acelib/memsubs.c view on Meta::CPAN
const char *hfname, int hlineno)
{
void *result = halloc_dbg(size, handle, hfname, hlineno) ;
#else
void *handleAlloc (void (*final)(void*), STORE_HANDLE handle, int size)
{
void *result = halloc(size, handle);
#endif
if (final)
blockSetFinalise(result, final);
return result;
}
/****************** useful utility ************/
#ifdef MEM_DEBUG
char *strnew_dbg(char *old, STORE_HANDLE handle, const char *hfname, int hlineno)
{ char *result = 0 ;
if (old)
{ result = (char *)halloc_dbg(1+strlen(old), handle, hfname, hlineno) ;
#else
char *strnew(char *old, STORE_HANDLE handle)
{ char *result = 0 ;
if (old)
{ result = (char *)halloc(1+strlen(old), handle);
#endif
strcpy(result, old);
}
return result;
}
/****************** messfree ***************/
void umessfree (void *cp)
{
STORE_HANDLE unit = toAllocUnit(cp) ;
#ifdef MALLOC_CHECK
checkUnit (unit) ;
unit->check1 = 0x87654321; /* test for double free */
#endif
if (unit->final)
(*unit->final)(cp) ;
if (unit->back)
{ (unit->back)->next = unit->next;
if (unit->next) (unit->next)->back = unit->back;
}
--numMessAlloc ;
totMessAlloc -= unit->size ;
free (unit) ;
}
/************** create and destroy handles **************/
/* NOTE: handleDestroy is #defined in regular.h to be messfree */
/* The actual work is done by handleFinalise, which is the finalisation */
/* routine attached to all STORE_HANDLEs. This allows multiple levels */
/* of free-ing by allocating new STORE_HANDLES on old ones, using */
/* handleHandleCreate. handleCreate is simply defined as handleHandleCreate(0) */
static void handleFinalise (void *p)
{
STORE_HANDLE handle = (STORE_HANDLE)p;
STORE_HANDLE next, unit = handle->next ;
/* do handle finalisation first */
if (handle->final)
(*handle->final)((void *)handle->back);
while (unit)
{
#ifdef MALLOC_CHECK
checkUnit (unit) ;
unit->check1 = 0x87654321; /* test for double free */
#endif
if (unit->final)
(*unit->final)(toMemPtr(unit)) ;
next = unit->next ;
--numMessAlloc ;
totMessAlloc -= unit->size ;
free (unit) ;
unit = next ;
}
#ifdef MALLOC_CHECK
arrayRemove (handles, &p, handleOrder) ;
#endif
/* This is a finalisation routine, the actual store is freed in messfree,
or another invokation of itself. */
}
void handleSetFinalise(STORE_HANDLE handle, void (*final)(void *), void *arg)
{ handle->final = final;
handle->back = (STORE_HANDLE)arg;
}
STORE_HANDLE handleHandleCreate(STORE_HANDLE handle)
{
STORE_HANDLE res = (STORE_HANDLE) handleAlloc(handleFinalise,
handle,
sizeof(STORE_HANDLE_STRUCT));
#ifdef MALLOC_CHECK
/* NB call to handleAlloc above ensures that handles is initialised here */
arrayInsert (handles, &res, handleOrder) ;
#endif
res->next = res->back = 0 ; /* No blocks on this handle yet. */
res->final = 0 ; /* No handle finalisation */
return res ;
}
BOOL finalCleanup = FALSE ;
#ifdef MEM_DEBUG
void handleCleanUp (void)
{ finalCleanup = TRUE ;
handleFinalise ((void *)&handle0) ;
}
( run in 0.716 second using v1.01-cache-2.11-cpan-d8267643d1d )