mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-24 05:21:20 -08:00
threading: fix possible race conditions in ecl_wakeup_waiters
Checking process.phase without holding the start_stop_spinlock
looks dangerous, the thread may exit after the check but before we
interrupt it. Also, we can't call mp_process_kill while interrupts
are disabled, so we have to use the lower level ecl_interrupt_process.
This commit is contained in:
parent
0ecea9487c
commit
f0506f511e
1 changed files with 6 additions and 2 deletions
|
|
@ -338,6 +338,7 @@ ecl_wakeup_waiters(cl_env_ptr the_env, cl_object q, int flags)
|
|||
cl_object *tail, l;
|
||||
for (tail = &q->queue.list; (l = *tail) != ECL_NIL; ) {
|
||||
cl_object p = ECL_CONS_CAR(l);
|
||||
ecl_get_spinlock(the_env, &p->process.start_stop_spinlock);
|
||||
if (p->process.phase == ECL_PROCESS_INACTIVE ||
|
||||
p->process.phase == ECL_PROCESS_EXITING) {
|
||||
print_lock("removing %p", q, p);
|
||||
|
|
@ -351,12 +352,15 @@ ecl_wakeup_waiters(cl_env_ptr the_env, cl_object q, int flags)
|
|||
*tail = ECL_CONS_CDR(l);
|
||||
tail = &ECL_CONS_CDR(l);
|
||||
if (flags & ECL_WAKEUP_KILL)
|
||||
mp_process_kill(p);
|
||||
ecl_interrupt_process(p, @'mp::exit-process');
|
||||
else
|
||||
ecl_wakeup_process(p);
|
||||
if (!(flags & ECL_WAKEUP_ALL))
|
||||
if (!(flags & ECL_WAKEUP_ALL)) {
|
||||
ecl_giveup_spinlock(&p->process.start_stop_spinlock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ecl_giveup_spinlock(&p->process.start_stop_spinlock);
|
||||
}
|
||||
}
|
||||
ecl_giveup_spinlock(&q->queue.spinlock);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue