summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_private.h
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2004-12-18 18:07:37 +0000
committerdeischen <deischen@FreeBSD.org>2004-12-18 18:07:37 +0000
commita5b13ff571d8e5b6e117756821e8aa5beb7b5d2c (patch)
tree3341fdd3fcdb8d611509d7622be5b25f271de80a /lib/libpthread/thread/thr_private.h
parentb231943e0e593788032a55590d7960ae015bddd2 (diff)
downloadFreeBSD-src-a5b13ff571d8e5b6e117756821e8aa5beb7b5d2c.zip
FreeBSD-src-a5b13ff571d8e5b6e117756821e8aa5beb7b5d2c.tar.gz
Use a generic way to back threads out of wait queues when handling
signals instead of having more intricate knowledge of thread state within signal handling. Simplify signal code because of above (by David Xu). Use macros for libpthread usage of pthread_cleanup_push() and pthread_cleanup_pop(). This removes some instances of malloc() and free() from the semaphore and pthread_once() implementations. When single threaded and forking(), make sure that the current thread's signal mask is inherited by the forked thread. Use private mutexes for libc and libpthread. Signals are deferred while threads hold private mutexes. This fix also breaks www/linuxpluginwrapper; a patch that fixes it is at http://people.freebsd.org/~deischen/kse/linuxpluginwrapper.diff Fix race condition in condition variables where handling a signal (pthread_kill() or kill()) may not see a wakeup (pthread_cond_signal() or pthread_cond_broadcast()). In collaboration with: davidxu
Diffstat (limited to 'lib/libpthread/thread/thr_private.h')
-rw-r--r--lib/libpthread/thread/thr_private.h24
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h
index b8ccb43..9f9f505 100644
--- a/lib/libpthread/thread/thr_private.h
+++ b/lib/libpthread/thread/thr_private.h
@@ -416,8 +416,24 @@ struct pthread_cleanup {
struct pthread_cleanup *next;
void (*routine) ();
void *routine_arg;
+ int onstack;
};
+#define THR_CLEANUP_PUSH(td, func, arg) { \
+ struct pthread_cleanup __cup; \
+ \
+ __cup.routine = func; \
+ __cup.routine_arg = arg; \
+ __cup.onstack = 1; \
+ __cup.next = (td)->cleanup; \
+ (td)->cleanup = &__cup;
+
+#define THR_CLEANUP_POP(td, exec) \
+ (td)->cleanup = __cup.next; \
+ if ((exec) != 0) \
+ __cup.routine(__cup.routine_arg); \
+}
+
struct pthread_atfork {
TAILQ_ENTRY(pthread_atfork) qe;
void (*prepare)(void);
@@ -573,6 +589,7 @@ struct pthread_sigframe {
sigset_t psf_sigset;
sigset_t psf_sigmask;
int psf_seqno;
+ thread_continuation_t psf_continuation;
};
struct join_status {
@@ -645,8 +662,8 @@ struct pthread {
/*
* Used for tracking delivery of signal handlers.
*/
- struct pthread_sigframe *curframe;
siginfo_t *siginfo;
+ thread_continuation_t sigbackout;
/*
* Cancelability flags - the lower 2 bits are used by cancel
@@ -1070,7 +1087,6 @@ SCLASS int _thr_debug_flags SCLASS_PRESET(0);
*/
__BEGIN_DECLS
int _cond_reinit(pthread_cond_t *);
-void _cond_wait_backout(struct pthread *);
struct kse *_kse_alloc(struct pthread *, int sys_scope);
kse_critical_t _kse_critical_enter(void);
void _kse_critical_leave(kse_critical_t);
@@ -1085,7 +1101,6 @@ int _kse_setthreaded(int);
void _kseg_free(struct kse_group *);
int _mutex_cv_lock(pthread_mutex_t *);
int _mutex_cv_unlock(pthread_mutex_t *);
-void _mutex_lock_backout(struct pthread *);
void _mutex_notify_priochange(struct pthread *, struct pthread *, int);
int _mutex_reinit(struct pthread_mutex *);
void _mutex_unlock_private(struct pthread *);
@@ -1148,8 +1163,7 @@ void _thr_set_timeout(const struct timespec *);
void _thr_seterrno(struct pthread *, int);
void _thr_sig_handler(int, siginfo_t *, ucontext_t *);
void _thr_sig_check_pending(struct pthread *);
-void _thr_sig_rundown(struct pthread *, ucontext_t *,
- struct pthread_sigframe *);
+void _thr_sig_rundown(struct pthread *, ucontext_t *);
void _thr_sig_send(struct pthread *pthread, int sig);
void _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
void _thr_spinlock_init(void);
OpenPOWER on IntegriCloud