diff options
| author | David Lamparter <equinox@diac24.net> | 2017-05-30 15:10:52 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-30 15:10:52 +0200 |
| commit | b7218a79037e803e33c42a80f564b2831a79a4fc (patch) | |
| tree | 255ea2c9e012f6ae0397681fd2fb22f53ae4cab1 /lib/thread.c | |
| parent | 9ad245006dd4829478521d25c2098031aa792124 (diff) | |
| parent | 48cdf1a9d6e687abe71421c3cce59b93ab34ac54 (diff) | |
Merge pull request #563 from qlyoung/enforce-no-pthread-cancellation
lib: enforce thread_cancel() MT-unsafe invariant
Diffstat (limited to 'lib/thread.c')
| -rw-r--r-- | lib/thread.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/thread.c b/lib/thread.c index 2843a9211e..ccb635a87d 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -377,6 +377,7 @@ thread_master_create (void) rv->timer->update = rv->background->update = thread_timer_update; rv->spin = true; rv->handle_signals = true; + rv->owner = pthread_self(); #if defined(HAVE_POLL_CALL) rv->handler.pfdsize = rv->fd_limit; @@ -1021,7 +1022,7 @@ thread_cancel_read_or_write (struct thread *thread, short int state) * Cancel thread from scheduler. * * This function is *NOT* MT-safe. DO NOT call it from any other pthread except - * the one which owns thread->master. + * the one which owns thread->master. You will crash. */ void thread_cancel (struct thread *thread) @@ -1030,8 +1031,10 @@ thread_cancel (struct thread *thread) struct pqueue *queue = NULL; struct thread **thread_array = NULL; - pthread_mutex_lock (&thread->master->mtx); pthread_mutex_lock (&thread->mtx); + pthread_mutex_lock (&thread->master->mtx); + + assert (pthread_self() == thread->master->owner); switch (thread->type) { @@ -1092,8 +1095,8 @@ thread_cancel (struct thread *thread) thread_add_unuse (thread->master, thread); done: - pthread_mutex_unlock (&thread->mtx); pthread_mutex_unlock (&thread->master->mtx); + pthread_mutex_unlock (&thread->mtx); } /* Delete all events which has argument value arg. */ |
