diff options
| author | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-05-18 18:41:24 +0200 | 
|---|---|---|
| committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-05-18 18:41:24 +0200 | 
| commit | 6a8ccc95528f5e86a8770ed15ce89609b5b3dee9 (patch) | |
| tree | bbd4df35b4d4a6a8b00d7a5e61fb2668b850ad62 /libpthread/linuxthreads.old/join.c | |
| parent | 398a27a5b323956344b4f831d892fed3bd9813c7 (diff) | |
remove linuxthreads.new, rename linuxthreads.old
Linuxthreads.new isn't really useful with the existence
of NPTL/TLS for well supported architectures. There is no
reason to use LT.new for ARM/MIPS or other architectures
supporting NPTL/TLS. It is not available for noMMU architectures
like Blackfin or FR-V. To simplify the live of the few uClibc-ng
developers, LT.new is removed and LT.old is renamed to LT.
LINUXTHREADS_OLD -> UCLIBC_HAS_LINUXTHREADS
Diffstat (limited to 'libpthread/linuxthreads.old/join.c')
| -rw-r--r-- | libpthread/linuxthreads.old/join.c | 369 | 
1 files changed, 0 insertions, 369 deletions
diff --git a/libpthread/linuxthreads.old/join.c b/libpthread/linuxthreads.old/join.c deleted file mode 100644 index c7e547951..000000000 --- a/libpthread/linuxthreads.old/join.c +++ /dev/null @@ -1,369 +0,0 @@ -/* Linuxthreads - a simple clone()-based implementation of Posix        */ -/* threads for Linux.                                                   */ -/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */ -/*                                                                      */ -/* This program is free software; you can redistribute it and/or        */ -/* modify it under the terms of the GNU Library General Public License  */ -/* as published by the Free Software Foundation; either version 2       */ -/* of the License, or (at your option) any later version.               */ -/*                                                                      */ -/* This program is distributed in the hope that it will be useful,      */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of       */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */ -/* GNU Library General Public License for more details.                 */ - -/* Thread termination and joining */ - -#include <features.h> -#include <errno.h> -#include <sched.h> -#include <unistd.h> -#include <stdlib.h> -#include "pthread.h" -#include "internals.h" -#include "spinlock.h" -#include "restart.h" -#include "debug.h" /* PDEBUG, added by StS */ - -libpthread_hidden_proto(pthread_exit) -void pthread_exit(void * retval) -{ -  __pthread_do_exit (retval, CURRENT_STACK_FRAME); -} -libpthread_hidden_def (pthread_exit) - -void __pthread_do_exit(void *retval, char *currentframe) -{ -  pthread_descr self = thread_self(); -  pthread_descr joining; -  struct pthread_request request; -  PDEBUG("self=%p, pid=%d\n", self, self->p_pid); - -  /* obey POSIX behavior and prevent cancellation functions from -   * being called more than once. -   * http://sourceware.org/ml/libc-ports/2006-10/msg00043.html -   */ -  THREAD_SETMEM(self, p_cancelstate, PTHREAD_CANCEL_DISABLE); -  THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED); - -  /* Call cleanup functions and destroy the thread-specific data */ -  __pthread_perform_cleanup(currentframe); -  __pthread_destroy_specifics(); -  /* Store return value */ -  __pthread_lock(THREAD_GETMEM(self, p_lock), self); -  THREAD_SETMEM(self, p_retval, retval); -  /* See whether we have to signal the death.  */ -  if (THREAD_GETMEM(self, p_report_events)) -    { -      /* See whether TD_DEATH is in any of the mask.  */ -      int idx = __td_eventword (TD_DEATH); -      uint32_t mask = __td_eventmask (TD_DEATH); - -      if ((mask & (__pthread_threads_events.event_bits[idx] -		   | THREAD_GETMEM_NC(self, -				   p_eventbuf.eventmask).event_bits[idx])) -	  != 0) -	{ -	  /* Yep, we have to signal the death.  */ -	  THREAD_SETMEM(self, p_eventbuf.eventnum, TD_DEATH); -	  THREAD_SETMEM(self, p_eventbuf.eventdata, self); -	  __pthread_last_event = self; - -	  /* Now call the function to signal the event.  */ -	  __linuxthreads_death_event(); -	} -    } -  /* Say that we've terminated */ -  THREAD_SETMEM(self, p_terminated, 1); -  /* See if someone is joining on us */ -  joining = THREAD_GETMEM(self, p_joining); -  PDEBUG("joining = %p, pid=%d\n", joining, joining ? joining->p_pid : 0); -  __pthread_unlock(THREAD_GETMEM(self, p_lock)); -  /* Restart joining thread if any */ -  if (joining != NULL) restart(joining); -  /* If this is the initial thread, block until all threads have terminated. -     If another thread calls exit, we'll be terminated from our signal -     handler. */ -  if (self == __pthread_main_thread && __pthread_manager_request >= 0) { -    request.req_thread = self; -    request.req_kind = REQ_MAIN_THREAD_EXIT; -    TEMP_FAILURE_RETRY(write(__pthread_manager_request, -		(char *)&request, sizeof(request))); -    suspend(self); -    /* Main thread flushes stdio streams and runs atexit functions. -     * It also calls a handler within LinuxThreads which sends a process exit -     * request to the thread manager. */ -    exit(0); -  } -  /* Exit the process (but don't flush stdio streams, and don't run -     atexit functions). */ -  _exit(0); -} - -/* Function called by pthread_cancel to remove the thread from -   waiting on a condition variable queue. */ - -static int join_extricate_func(void *obj, pthread_descr th attribute_unused) -{ -  volatile pthread_descr self = thread_self(); -  pthread_handle handle = obj; -  pthread_descr jo; -  int did_remove = 0; - -  __pthread_lock(&handle->h_lock, self); -  jo = handle->h_descr; -  did_remove = jo->p_joining != NULL; -  jo->p_joining = NULL; -  __pthread_unlock(&handle->h_lock); - -  return did_remove; -} - -int pthread_join(pthread_t thread_id, void ** thread_return) -{ -  volatile pthread_descr self = thread_self(); -  struct pthread_request request; -  pthread_handle handle = thread_handle(thread_id); -  pthread_descr th; -  pthread_extricate_if extr; -  int already_canceled = 0; -  PDEBUG("\n"); - -  /* Set up extrication interface */ -  extr.pu_object = handle; -  extr.pu_extricate_func = join_extricate_func; - -  __pthread_lock(&handle->h_lock, self); -  if (invalid_handle(handle, thread_id)) { -    __pthread_unlock(&handle->h_lock); -    return ESRCH; -  } -  th = handle->h_descr; -  if (th == self) { -    __pthread_unlock(&handle->h_lock); -    return EDEADLK; -  } -  /* If detached or already joined, error */ -  if (th->p_detached || th->p_joining != NULL) { -    __pthread_unlock(&handle->h_lock); -    return EINVAL; -  } -  /* If not terminated yet, suspend ourselves. */ -  if (! th->p_terminated) { -    /* Register extrication interface */ -    __pthread_set_own_extricate_if(self, &extr); -    if (!(THREAD_GETMEM(self, p_canceled) -	&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) -      th->p_joining = self; -    else -      already_canceled = 1; -    __pthread_unlock(&handle->h_lock); - -    if (already_canceled) { -      __pthread_set_own_extricate_if(self, 0); -      __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); -    } - -  PDEBUG("before suspend\n"); -    suspend(self); -  PDEBUG("after suspend\n"); -    /* Deregister extrication interface */ -    __pthread_set_own_extricate_if(self, 0); - -    /* This is a cancellation point */ -    if (THREAD_GETMEM(self, p_woken_by_cancel) -	&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { -      THREAD_SETMEM(self, p_woken_by_cancel, 0); -      __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); -    } -    __pthread_lock(&handle->h_lock, self); -  } -  /* Get return value */ -  if (thread_return != NULL) *thread_return = th->p_retval; -  __pthread_unlock(&handle->h_lock); -  /* Send notification to thread manager */ -  if (__pthread_manager_request >= 0) { -    request.req_thread = self; -    request.req_kind = REQ_FREE; -    request.req_args.free.thread_id = thread_id; -    TEMP_FAILURE_RETRY(write(__pthread_manager_request, -		(char *) &request, sizeof(request))); -  } -  return 0; -} - -int pthread_tryjoin_np(pthread_t thread_id, void ** thread_return) -{ -  volatile pthread_descr self = thread_self(); -  struct pthread_request request; -  pthread_handle handle = thread_handle(thread_id); -  pthread_descr th; -  int result = 0; - -  /* Make sure the descriptor is valid.  */ -  __pthread_lock(&handle->h_lock, self); -  if (invalid_handle(handle, thread_id)) { -    result = ESRCH; -    goto err; -  } -  th = handle->h_descr; -  /* Is the thread joinable?.  */ -  if (th->p_detached || th->p_joining != NULL) { -    result = EINVAL; -    goto err; -  } -  if (th == self) { -    result = EDEADLK; -    goto err; -  } -  /* Return right away if the thread hasn't terminated yet.  */ -  if (! th->p_terminated) { -    result = EBUSY; -    goto err; -  } - -  /* Get return value */ -  if (thread_return != NULL) *thread_return = th->p_retval; -  __pthread_unlock(&handle->h_lock); -  /* Send notification to thread manager */ -  if (__pthread_manager_request >= 0) { -    request.req_thread = self; -    request.req_kind = REQ_FREE; -    request.req_args.free.thread_id = thread_id; -    TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, -		(char *) &request, sizeof(request))); -  } -  return 0; - -err: -  __pthread_unlock(&handle->h_lock); -  return result; -} - -int pthread_timedjoin_np(pthread_t thread_id, void ** thread_return, -			const struct timespec *abstime) -{ -  volatile pthread_descr self = thread_self(); -  struct pthread_request request; -  pthread_handle handle = thread_handle(thread_id); -  pthread_descr th; -  pthread_extricate_if extr; -  int already_canceled = 0; -  int result = 0; -  PDEBUG("\n"); - -  /* Set up extrication interface */ -  extr.pu_object = handle; -  extr.pu_extricate_func = join_extricate_func; - -  __pthread_lock(&handle->h_lock, self); -  if (invalid_handle(handle, thread_id)) { -    result = ESRCH; -    goto err; -  } -  th = handle->h_descr; -  if (th == self) { -    result = EDEADLK; -    goto err; -  } -  /* If detached or already joined, error */ -  if (th->p_detached || th->p_joining != NULL) { -    result = EINVAL; -    goto err; -  } -  /* If not terminated yet, suspend ourselves. */ -  if (! th->p_terminated) { -    /* Register extrication interface */ -    __pthread_set_own_extricate_if(self, &extr); -    if (!(THREAD_GETMEM(self, p_canceled) -	&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) -      th->p_joining = self; -    else -      already_canceled = 1; -    __pthread_unlock(&handle->h_lock); - -    if (already_canceled) { -      __pthread_set_own_extricate_if(self, 0); -      __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); -    } - -  PDEBUG("before suspend\n"); -    result = (timedsuspend(self, abstime) == 0) ? ETIMEDOUT : 0; -  PDEBUG("after suspend\n"); -    /* Deregister extrication interface */ -    __pthread_set_own_extricate_if(self, 0); - -    /* This is a cancellation point */ -    if (result == 0 -        && THREAD_GETMEM(self, p_woken_by_cancel) -	&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { -      THREAD_SETMEM(self, p_woken_by_cancel, 0); -      __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); -    } -    __pthread_lock(&handle->h_lock, self); -  } - -  /* We might have timed out. */ -  if (result == 0) { -    /* Get return value */ -    if (thread_return != NULL) *thread_return = th->p_retval; -  } -  else -    th->p_joining = NULL; - -  __pthread_unlock(&handle->h_lock); - -  if (result == 0) { -    /* Send notification to thread manager */ -    if (__pthread_manager_request >= 0) { -      request.req_thread = self; -      request.req_kind = REQ_FREE; -      request.req_args.free.thread_id = thread_id; -      TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, -		(char *) &request, sizeof(request))); -    } -  } -  return result; - -err: -  __pthread_unlock(&handle->h_lock); -  return result; -} - -int pthread_detach(pthread_t thread_id) -{ -  int terminated; -  struct pthread_request request; -  pthread_handle handle = thread_handle(thread_id); -  pthread_descr th; - -  __pthread_lock(&handle->h_lock, NULL); -  if (invalid_handle(handle, thread_id)) { -    __pthread_unlock(&handle->h_lock); -    return ESRCH; -  } -  th = handle->h_descr; -  /* If already detached, error */ -  if (th->p_detached) { -    __pthread_unlock(&handle->h_lock); -    return EINVAL; -  } -  /* If already joining, don't do anything. */ -  if (th->p_joining != NULL) { -    __pthread_unlock(&handle->h_lock); -    return 0; -  } -  /* Mark as detached */ -  th->p_detached = 1; -  terminated = th->p_terminated; -  __pthread_unlock(&handle->h_lock); -  /* If already terminated, notify thread manager to reclaim resources */ -  if (terminated && __pthread_manager_request >= 0) { -    request.req_thread = thread_self(); -    request.req_kind = REQ_FREE; -    request.req_args.free.thread_id = thread_id; -    TEMP_FAILURE_RETRY(write(__pthread_manager_request, -		(char *) &request, sizeof(request))); -  } -  return 0; -}  | 
