BOOL MemHeapTerm(VOID) { if ( hp ) { return !(_uclose(hp) || _udestroy(hp, _FORCE) || DosSubUnsetMem(pbasemem) || DosFreeMem(pbasemem)); } /* endif */ closeLogFile(); return FALSE; }
static void shared_term() { APIRET arc; int rc; TRACE("gMutex %lx, gpData %p (heap %p, refcnt %d), gSeenAssertion %lu\n", gMutex, gpData, gpData ? gpData->heap : 0, gpData ? gpData->refcnt : 0, gSeenAssertion); #if !defined(TRACE_ENABLED) if (gSeenAssertion && get_log_instance()) { /* * We're crashing after an assertion, write out LIBCx stats (not needed in * trace builds as we will trace that out later anyway) */ char *buf = alloca(StatsBufSize); if (buf) { format_stats(buf, StatsBufSize); __libc_LogRaw(gLogInstance, __LIBC_LOG_MSGF_FLUSH, buf, StatsBufSize); } } #endif ASSERT(gSeenAssertion || gMutex != NULLHANDLE); DosRequestMutexSem(gMutex, SEM_INDEFINITE_WAIT); if (gpData) { if (gpData->heap) { int i; ProcDesc *proc; ASSERT(gpData->refcnt); gpData->refcnt--; /* Remove the process description upon process termination */ size_t bucket = 0; ProcDesc *prev = NULL; proc = find_proc_desc_ex(getpid(), &bucket, &prev); /* Uninitialize individual components */ fcntl_locking_term(proc); mmap_term(proc); TRACE("proc %p\n", proc); if (proc) { if (proc->spawn2_wrappers) { TRACE("proc->spawn2_wrappers %p\n", proc->spawn2_wrappers); free(proc->spawn2_wrappers); } if (proc->spawn2_sem) { TRACE("proc->spawn2_sem %lx (refcnt %d)\n", proc->spawn2_sem, gpData->spawn2_sem_refcnt); ASSERT(proc->spawn2_sem == gpData->spawn2_sem); DosCloseEventSem(gpData->spawn2_sem); ASSERT(gpData->spawn2_sem_refcnt != 0); --gpData->spawn2_sem_refcnt; if (gpData->spawn2_sem_refcnt == 0) gpData->spawn2_sem = NULLHANDLE; } /* Free common per-process structures */ TRACE("proc->files %p\n", proc->files); if (proc->files) { for (i = 0; i < FILE_DESC_HASH_SIZE; ++i) { FileDesc *desc = proc->files[i]; while (desc) { FileDesc *next = desc->next; free_file_desc(desc, i, NULL, NULL); desc = next; } } free(proc->files); } free_proc_desc(proc, bucket, prev); } if (gpData->refcnt == 0) { /* We are the last process, free common structures */ TRACE("gpData->files %p\n", gpData->files); if (gpData->files) { /* Make sure we don't have lost SharedFileDesc data */ for (i = 0; i < FILE_DESC_HASH_SIZE; ++i) ASSERT_MSG(!gpData->files[i], "%p", gpData->files[i]); free(gpData->files); } TRACE("gpData->procs %p\n", gpData->procs); if (gpData->procs) free(gpData->procs); } #ifdef TRACE_ENABLED { char *buf = alloca(StatsBufSize); if (buf) { format_stats(buf, StatsBufSize); TRACE("%s", buf); } } #endif _uclose(gpData->heap); if (gpData->refcnt == 0) { #ifdef STATS_ENABLED _HEAPSTATS hst; rc = _ustats(gpData->heap, &hst); ASSERT_MSG(!rc, "%d (%d)", rc, errno); ASSERT_MSG(!hst._used, "%d", hst._used); #endif rc = _udestroy(gpData->heap, !_FORCE); TRACE("_udestroy = %d (%d)\n", rc, errno); } } arc = DosFreeMem(gpData); TRACE("DosFreeMem = %ld\n", arc); } DosReleaseMutexSem(gMutex); arc = DosCloseMutexSem(gMutex); if (arc == ERROR_SEM_BUSY) { /* The semaphore may be owned by us, try to release it */ arc = DosReleaseMutexSem(gMutex); TRACE("DosReleaseMutexSem = %ld\n", arc); arc = DosCloseMutexSem(gMutex); } TRACE("DosCloseMutexSem = %ld\n", arc); DosExitList(EXLST_REMOVE, ProcessExit); }