mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-25 11:57:07 +00:00
Merge pull request #563 from qlyoung/enforce-no-pthread-cancellation
lib: enforce thread_cancel() MT-unsafe invariant
This commit is contained in:
commit
b7218a7903
@ -377,6 +377,7 @@ thread_master_create (void)
|
|||||||
rv->timer->update = rv->background->update = thread_timer_update;
|
rv->timer->update = rv->background->update = thread_timer_update;
|
||||||
rv->spin = true;
|
rv->spin = true;
|
||||||
rv->handle_signals = true;
|
rv->handle_signals = true;
|
||||||
|
rv->owner = pthread_self();
|
||||||
|
|
||||||
#if defined(HAVE_POLL_CALL)
|
#if defined(HAVE_POLL_CALL)
|
||||||
rv->handler.pfdsize = rv->fd_limit;
|
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.
|
* Cancel thread from scheduler.
|
||||||
*
|
*
|
||||||
* This function is *NOT* MT-safe. DO NOT call it from any other pthread except
|
* 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
|
void
|
||||||
thread_cancel (struct thread *thread)
|
thread_cancel (struct thread *thread)
|
||||||
@ -1030,8 +1031,10 @@ thread_cancel (struct thread *thread)
|
|||||||
struct pqueue *queue = NULL;
|
struct pqueue *queue = NULL;
|
||||||
struct thread **thread_array = NULL;
|
struct thread **thread_array = NULL;
|
||||||
|
|
||||||
pthread_mutex_lock (&thread->master->mtx);
|
|
||||||
pthread_mutex_lock (&thread->mtx);
|
pthread_mutex_lock (&thread->mtx);
|
||||||
|
pthread_mutex_lock (&thread->master->mtx);
|
||||||
|
|
||||||
|
assert (pthread_self() == thread->master->owner);
|
||||||
|
|
||||||
switch (thread->type)
|
switch (thread->type)
|
||||||
{
|
{
|
||||||
@ -1092,8 +1095,8 @@ thread_cancel (struct thread *thread)
|
|||||||
thread_add_unuse (thread->master, thread);
|
thread_add_unuse (thread->master, thread);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
pthread_mutex_unlock (&thread->mtx);
|
|
||||||
pthread_mutex_unlock (&thread->master->mtx);
|
pthread_mutex_unlock (&thread->master->mtx);
|
||||||
|
pthread_mutex_unlock (&thread->mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete all events which has argument value arg. */
|
/* Delete all events which has argument value arg. */
|
||||||
|
@ -88,6 +88,7 @@ struct thread_master
|
|||||||
bool spin;
|
bool spin;
|
||||||
bool handle_signals;
|
bool handle_signals;
|
||||||
pthread_mutex_t mtx;
|
pthread_mutex_t mtx;
|
||||||
|
pthread_t owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef unsigned char thread_type;
|
typedef unsigned char thread_type;
|
||||||
|
Loading…
Reference in New Issue
Block a user