Ejemplo n.º 1
0
void pthread_exit(void *retval) {
  /* Get all we need from the tdb before releasing it. */
  nc_thread_descriptor_t    *tdb = nc_get_tdb();
  nc_thread_memory_block_t  *stack_node = tdb->stack_node;
  int32_t                   *is_used = &stack_node->is_used;
  nc_basic_thread_data_t    *basic_data = tdb->basic_data;
  int                       joinable = tdb->joinable;

  /* Call cleanup handlers. */
  while (NULL != __nc_cleanup_handlers) {
    pthread_cleanup_pop(1);
  }

  /* Call the destruction functions for TSD. */
  __nc_tsd_exit();

  __newlib_thread_exit();

  __nc_futex_thread_exit();

  if (__nc_initial_thread_id != basic_data) {
    pthread_mutex_lock(&__nc_thread_management_lock);
    --__nc_running_threads_counter;
    pthread_mutex_unlock(&__nc_thread_management_lock);
  } else {
    /* This is the main thread - wait for other threads to complete. */
    wait_for_threads();
    exit(0);
  }

  pthread_mutex_lock(&__nc_thread_management_lock);

  basic_data->retval = retval;

  if (joinable) {
    /* If somebody is waiting for this thread, signal. */
    basic_data->status = THREAD_TERMINATED;
    pthread_cond_signal(&basic_data->join_condvar);
  }
  /*
   * We can release TLS+TDB - thread id and its return value are still
   * kept in basic_data.
   */
  nc_release_tls_node(tdb->tls_node, tdb);

  if (!joinable) {
    nc_release_basic_data_mu(basic_data);
  }

  /* Now add the stack to the list but keep it marked as used. */
  nc_free_memory_block_mu(THREAD_STACK_MEMORY, stack_node);

  if (1 == __nc_running_threads_counter) {
    pthread_cond_signal(&__nc_last_thread_cond);
  }

  pthread_mutex_unlock(&__nc_thread_management_lock);
  irt_thread.thread_exit(is_used);
  nc_abort();
}
Ejemplo n.º 2
0
static void nacl_irt_thread_exit(int32_t *stack_flag) {
  struct nc_combined_tdb *tdb = get_irt_tdb(__nacl_read_tp());

  __nc_tsd_exit();

  /*
   * Sanity check: Check that this function was not called on a thread
   * created by the IRT's internal pthread_create().  For such
   * threads, irt_thread_data == NULL.
   */
  assert(tdb->tdb.irt_thread_data != NULL);

  free(tdb->tdb.irt_thread_data);

  NACL_SYSCALL(thread_exit)(stack_flag);
  while (1) *(volatile int *) 0 = 0;  /* Crash.  */
}