diff options
author | alfred <alfred@FreeBSD.org> | 1999-11-28 05:38:13 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 1999-11-28 05:38:13 +0000 |
commit | e7efcb5302ff3b4faef7cf619f51a4b4a509f09a (patch) | |
tree | 295e248e2503f8c817b16353f285d30439bf4bf4 /lib/libpthread/thread/thr_exit.c | |
parent | dff67f0b84733be29e807fc281e817bc8639fd70 (diff) | |
download | FreeBSD-src-e7efcb5302ff3b4faef7cf619f51a4b4a509f09a.zip FreeBSD-src-e7efcb5302ff3b4faef7cf619f51a4b4a509f09a.tar.gz |
add pthread_cancel, obtained from OpenBSD.
eischen (Daniel Eischen) added wrappers to protect against cancled
threads orphaning internal resources.
the cancelability code is still a bit fuzzy but works for test
programs of my own, OpenBSD's and some examples from ORA's books.
add readdir_r to both libc and libc_r
add some 'const' attributes to function parameters
Reviewed by: eischen, jasone
Diffstat (limited to 'lib/libpthread/thread/thr_exit.c')
-rw-r--r-- | lib/libpthread/thread/thr_exit.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/lib/libpthread/thread/thr_exit.c b/lib/libpthread/thread/thr_exit.c index 795decc..abe4b27 100644 --- a/lib/libpthread/thread/thr_exit.c +++ b/lib/libpthread/thread/thr_exit.c @@ -34,6 +34,8 @@ #include <errno.h> #include <unistd.h> #include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> #ifdef _THREAD_SAFE #include <pthread.h> @@ -101,17 +103,45 @@ _thread_exit(char *fname, int lineno, char *string) #endif } +/* + * Only called when a thread is cancelled. It may be more useful + * to call it from pthread_exit() if other ways of asynchronous or + * abnormal thread termination can be found. + */ +void +_thread_exit_cleanup(void) +{ + /* + * POSIX states that cancellation/termination of a thread should + * not release any visible resources (such as mutexes) and that + * it is the applications responsibility. Resources that are + * internal to the threads library, including file and fd locks, + * are not visible to the application and need to be released. + */ + /* Unlock all owned fd locks: */ + _thread_fd_unlock_owned(_thread_run); + + /* Unlock all owned file locks: */ + _funlock_owned(_thread_run); + + /* Unlock all private mutexes: */ + _mutex_unlock_private(_thread_run); + + /* + * This still isn't quite correct because we don't account + * for held spinlocks (see libc/stdlib/malloc.c). + */ +} + void pthread_exit(void *status) { - int sig; - long l; - pthread_t pthread; + pthread_t pthread; /* Check if this thread is already in the process of exiting: */ if ((_thread_run->flags & PTHREAD_EXITING) != 0) { char msg[128]; - snprintf(msg,"Thread %p has called pthread_exit() from a destructor. POSIX 1003.1 1996 s16.2.5.2 does not allow this!",_thread_run); + snprintf(msg, sizeof(msg), "Thread %p has called pthread_exit() from a destructor. POSIX 1003.1 1996 s16.2.5.2 does not allow this!",_thread_run); PANIC(msg); } @@ -134,7 +164,7 @@ pthread_exit(void *status) _thread_cleanupspecific(); } - /* Free thread-specific poll_data structure, if allocated */ + /* Free thread-specific poll_data structure, if allocated: */ if (_thread_run->poll_data.fds != NULL) { free(_thread_run->poll_data.fds); _thread_run->poll_data.fds = NULL; |