Ejemplo n.º 1
0
BOOL MemHeapTerm(VOID)
  {
  if ( hp )
    {
    return !(_uclose(hp) ||
             _udestroy(hp, _FORCE) ||
             DosSubUnsetMem(pbasemem) ||
             DosFreeMem(pbasemem));
    } /* endif */
  closeLogFile();
  return FALSE;
  }
Ejemplo n.º 2
0
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);
}