mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-11 17:04:19 +01:00
if a thread blocked on userland condition variable is
pthread_cancel()ed, it is expected that the thread will not consume a pthread_cond_signal(), therefor, we use thr_wake() to mark a flag, the flag tells a thread calling do_cv_wait() in umtx code to not block on a condition variable. Thread library is expected that once a thread detected itself is in pthread_cond_wait, it will call the thr_wake() for itself in its SIGCANCEL handler.
This commit is contained in:
parent
02f3691e93
commit
745fbd3a72
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164876
@ -402,6 +402,12 @@ kern_thr_suspend(struct thread *td, struct timespec *tsp)
|
||||
TIMESPEC_TO_TIMEVAL(&tv, tsp);
|
||||
hz = tvtohz(&tv);
|
||||
}
|
||||
|
||||
if (td->td_pflags & TDP_WAKEUP) {
|
||||
td->td_pflags &= ~TDP_WAKEUP;
|
||||
return (0);
|
||||
}
|
||||
|
||||
PROC_LOCK(td->td_proc);
|
||||
if ((td->td_flags & TDF_THRWAKEUP) == 0)
|
||||
error = msleep((void *)td, &td->td_proc->p_mtx, PCATCH, "lthr",
|
||||
@ -430,6 +436,11 @@ thr_wake(struct thread *td, struct thr_wake_args *uap)
|
||||
struct proc *p;
|
||||
struct thread *ttd;
|
||||
|
||||
if (uap->id == td->td_tid) {
|
||||
td->td_pflags |= TDP_WAKEUP;
|
||||
return (0);
|
||||
}
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
ttd = thread_find(p, uap->id);
|
||||
|
@ -2170,7 +2170,7 @@ do_unlock_umutex(struct thread *td, struct umutex *m)
|
||||
|
||||
static int
|
||||
do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m,
|
||||
struct timespec *timeout)
|
||||
struct timespec *timeout, u_long wflags)
|
||||
{
|
||||
struct umtx_q *uq;
|
||||
struct timeval tv;
|
||||
@ -2202,7 +2202,11 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m,
|
||||
|
||||
umtxq_lock(&uq->uq_key);
|
||||
if (error == 0) {
|
||||
if (timeout == NULL) {
|
||||
if ((wflags & UMTX_CHECK_UNPARKING) &&
|
||||
(td->td_pflags & TDP_WAKEUP)) {
|
||||
td->td_pflags &= ~TDP_WAKEUP;
|
||||
error = EINTR;
|
||||
} else if (timeout == NULL) {
|
||||
error = umtxq_sleep(uq, "ucond", 0);
|
||||
} else {
|
||||
getnanouptime(&ets);
|
||||
@ -2236,7 +2240,8 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m,
|
||||
* occur, and indeed a kernel based implementation
|
||||
* can not avoid it.
|
||||
*/
|
||||
umtxq_signal(&uq->uq_key, 1);
|
||||
if (!umtxq_signal(&uq->uq_key, 1))
|
||||
error = 0;
|
||||
}
|
||||
if (error == ERESTART)
|
||||
error = EINTR;
|
||||
@ -2431,7 +2436,7 @@ __umtx_op_cv_wait(struct thread *td, struct _umtx_op_args *uap)
|
||||
}
|
||||
ts = &timeout;
|
||||
}
|
||||
return (do_cv_wait(td, uap->obj, uap->uaddr1, ts));
|
||||
return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2592,7 +2597,7 @@ __umtx_op_cv_wait_compat32(struct thread *td, struct _umtx_op_args *uap)
|
||||
return (EINVAL);
|
||||
ts = &timeout;
|
||||
}
|
||||
return (do_cv_wait(td, uap->obj, uap->uaddr1, ts));
|
||||
return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val));
|
||||
}
|
||||
|
||||
static _umtx_op_func op_table_compat32[] = {
|
||||
|
@ -455,6 +455,7 @@ struct thread {
|
||||
#define TDP_GEOM 0x00010000 /* Settle GEOM before finishing syscall */
|
||||
#define TDP_SOFTDEP 0x00020000 /* Stuck processing softdep worklist */
|
||||
#define TDP_NORUNNINGBUF 0x00040000 /* Ignore runningbufspace check */
|
||||
#define TDP_WAKEUP 0x00080000 /* Don't sleep in umtx cond_wait */
|
||||
|
||||
/*
|
||||
* Reasons that the current thread can not be run yet.
|
||||
|
@ -80,6 +80,9 @@ struct ucond {
|
||||
#define UMTX_OP_CV_BROADCAST 10
|
||||
#define UMTX_OP_MAX 11
|
||||
|
||||
/* flags for UMTX_OP_CV_WAIT */
|
||||
#define UMTX_CHECK_UNPARKING 0x01
|
||||
|
||||
#ifndef _KERNEL
|
||||
|
||||
int _umtx_op(void *obj, int op, u_long val, void *uaddr, void *uaddr2);
|
||||
|
Loading…
Reference in New Issue
Block a user