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 )