Exemple #1
0
void WINAPI myThread(void* arg) {
  int num;
  num = *((int*) arg);
  if (TEST_NUM != num) {
    fprintf(stderr, "myThread: %d expected, but %d received\n", TEST_NUM, num);
    exit(EXIT_FAILURE);
  }
  NaClThreadExit(0);
}
Exemple #2
0
void NaClReverseThreadIfExit(struct NaClThreadInterface   *vself,
                             void                         *exit_code) {
  struct NaClReverseCountingThreadInterface *self =
      (struct NaClReverseCountingThreadInterface *) vself;
  NaClLog(4,
          ("NaClReverseThreadIfExit: thread 0x%"NACL_PRIxPTR
           " is exiting\n"),
          (uintptr_t) vself);

  (*NACL_VTBL(NaClReverseService, self->reverse_service)->ThreadCountDecr)(
      self->reverse_service);

  NaClRefCountUnref((struct NaClRefCount *) self);
  NaClThreadExit((int)(uintptr_t) exit_code);
}
Exemple #3
0
void WINAPI serviceThread(void* arg) {
  struct ServiceThreadArgs* typedArg;
  NaClSrpcImcDescType desc;
  NaClSrpcHandlerDesc handlers[] = {
    { "getNum::i", handleGetNum },
    { NULL, NULL }
  };
  typedArg = (struct ServiceThreadArgs*) arg;
  desc = typedArg->desc;
  free(typedArg);

  if (!NaClSrpcServerLoop(desc, handlers, 0)) {
    failWithErrno("NaClSrpcServerLoop");
    exit(EXIT_FAILURE);
  }
#ifdef __native_client__
  close(desc);
#else
  NaClDescUnref(desc);
#endif
  NaClThreadExit(0);
}
Exemple #4
0
/*
 * natp should be thread_self(), called while holding no locks.
 */
void NaClAppThreadTeardown(struct NaClAppThread *natp) {
  struct NaClApp  *nap;
  size_t          thread_idx;

  /*
   * mark this thread as dead; doesn't matter if some other thread is
   * asking us to commit suicide.
   */
  NaClLog(3, "NaClAppThreadTeardown(0x%08"NACL_PRIxPTR")\n",
          (uintptr_t) natp);
  nap = natp->nap;
  if (NULL != nap->debug_stub_callbacks) {
    NaClLog(3, " notifying the debug stub of the thread exit\n");
    /*
     * This must happen before deallocating the ID natp->thread_num.
     * We have the invariant that debug stub lock should be acquired before
     * nap->threads_mu lock. Hence we must not hold threads_mu lock while
     * calling debug stub hooks.
     */
    nap->debug_stub_callbacks->thread_exit_hook(natp);
  }

  NaClLog(3, " getting thread table lock\n");
  NaClXMutexLock(&nap->threads_mu);
  NaClLog(3, " getting thread lock\n");
  NaClXMutexLock(&natp->mu);
  /*
   * Remove ourselves from the ldt-indexed global tables.  The ldt
   * entry is released as part of NaClAppThreadDelete(), and if
   * another thread is immediately created (from some other running
   * thread) we want to be sure that any ldt-based lookups will not
   * reach this dying thread's data.
   */
  thread_idx = NaClGetThreadIdx(natp);
  /*
   * On x86-64 and ARM, clearing nacl_user entry ensures that we will
   * fault if another syscall is made with this thread_idx.  In
   * particular, thread_idx 0 is never used.
   */
  nacl_user[thread_idx] = NULL;
#if NACL_WINDOWS
  nacl_thread_ids[thread_idx] = 0;
#elif NACL_OSX
  NaClClearMachThreadForThreadIndex(thread_idx);
#endif
  /*
   * Unset the TLS variable so that if a crash occurs during thread
   * teardown, the signal handler does not dereference a dangling
   * NaClAppThread pointer.
   */
  NaClTlsSetCurrentThread(NULL);

  NaClLog(3, " removing thread from thread table\n");
  /* Deallocate the ID natp->thread_num. */
  NaClRemoveThreadMu(nap, natp->thread_num);
  NaClLog(3, " unlocking thread\n");
  NaClXMutexUnlock(&natp->mu);
  NaClLog(3, " unlocking thread table\n");
  NaClXMutexUnlock(&nap->threads_mu);
  NaClLog(3, " unregistering signal stack\n");
  NaClSignalStackUnregister();
  NaClLog(3, " freeing thread object\n");
  NaClAppThreadDelete(natp);
  NaClLog(3, " NaClThreadExit\n");
  NaClThreadExit();
  NaClLog(LOG_FATAL,
          "NaClAppThreadTeardown: NaClThreadExit() should not return\n");
  /* NOTREACHED */
}