Let _umtx_op directly return error code rather than from errno because
errno can be tampered potentially by nested signal handle. Now all error codes are returned in negative value, positive value are reserved for future expansion.
This commit is contained in:
parent
9e777bc6e2
commit
333d4875cd
@ -679,7 +679,6 @@ do_wake(struct thread *td, void *uaddr, int n_wake)
|
||||
ret = umtxq_signal(&key, n_wake);
|
||||
umtxq_unlock(&key);
|
||||
umtx_key_release(&key);
|
||||
td->td_retval[0] = ret;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -712,15 +711,20 @@ _umtx_op(struct thread *td, struct _umtx_op_args *uap)
|
||||
else {
|
||||
error = copyin(uap->uaddr2, &abstime, sizeof(abstime));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
break;
|
||||
printf("uap->abstime: %d.%ld\n", abstime.tv_sec, abstime.tv_nsec);
|
||||
if (abstime.tv_nsec >= 1000000000 ||
|
||||
abstime.tv_nsec < 0)
|
||||
return (EINVAL);
|
||||
abstime.tv_nsec < 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ts = &abstime;
|
||||
}
|
||||
return do_lock(td, uap->umtx, uap->id, ts);
|
||||
error = do_lock(td, uap->umtx, uap->id, ts);
|
||||
break;
|
||||
case UMTX_OP_UNLOCK:
|
||||
return do_unlock(td, uap->umtx, uap->id);
|
||||
error = do_unlock(td, uap->umtx, uap->id);
|
||||
break;
|
||||
case UMTX_OP_WAIT:
|
||||
/* Allow a null timespec (wait forever). */
|
||||
if (uap->uaddr2 == NULL)
|
||||
@ -728,16 +732,23 @@ _umtx_op(struct thread *td, struct _umtx_op_args *uap)
|
||||
else {
|
||||
error = copyin(uap->uaddr2, &abstime, sizeof(abstime));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
break;
|
||||
if (abstime.tv_nsec >= 1000000000 ||
|
||||
abstime.tv_nsec < 0)
|
||||
return (EINVAL);
|
||||
abstime.tv_nsec < 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ts = &abstime;
|
||||
}
|
||||
return do_wait(td, uap->umtx, uap->id, ts);
|
||||
error = do_wait(td, uap->umtx, uap->id, ts);
|
||||
break;
|
||||
case UMTX_OP_WAKE:
|
||||
return do_wake(td, uap->umtx, uap->id);
|
||||
error = do_wake(td, uap->umtx, uap->id);
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
td->td_retval[0] = -error;
|
||||
return (0);
|
||||
}
|
||||
|
@ -81,8 +81,7 @@ umtx_lock(struct umtx *umtx, long id)
|
||||
{
|
||||
if (atomic_cmpset_acq_ptr(&umtx->u_owner, (void *)UMTX_UNOWNED,
|
||||
(void *)id) == 0)
|
||||
if (_umtx_op(umtx, UMTX_OP_LOCK, id, 0, 0) == -1)
|
||||
return (errno);
|
||||
return (- _umtx_op(umtx, UMTX_OP_LOCK, id, 0, 0));
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -100,8 +99,7 @@ umtx_timedlock(struct umtx *umtx, long id, const struct timespec *abstime)
|
||||
{
|
||||
if (atomic_cmpset_acq_ptr(&umtx->u_owner, (void *)UMTX_UNOWNED,
|
||||
(void *)id) == 0)
|
||||
if (_umtx_op(umtx, UMTX_OP_LOCK, id, 0, (void *)abstime) == -1)
|
||||
return (errno);
|
||||
return (- _umtx_op(umtx, UMTX_OP_LOCK, id, 0, (void *)abstime));
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -110,35 +108,27 @@ umtx_unlock(struct umtx *umtx, long id)
|
||||
{
|
||||
if (atomic_cmpset_rel_ptr(&umtx->u_owner, (void *)id,
|
||||
(void *)UMTX_UNOWNED) == 0)
|
||||
if (_umtx_op(umtx, UMTX_OP_UNLOCK, id, 0, 0) == -1)
|
||||
return (errno);
|
||||
return (- _umtx_op(umtx, UMTX_OP_UNLOCK, id, 0, 0));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Unlock umtx and wait on a user address. */
|
||||
|
||||
static __inline int
|
||||
umtx_wait(struct umtx *umtx, long id)
|
||||
{
|
||||
if (_umtx_op(umtx, UMTX_OP_WAIT, id, 0, 0) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
return (- _umtx_op(umtx, UMTX_OP_WAIT, id, 0, 0));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
umtx_timedwait(struct umtx *umtx, long id, const struct timespec *abstime)
|
||||
{
|
||||
if (_umtx_op(umtx, UMTX_OP_WAIT, id, 0, (void *)abstime) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
return (- _umtx_op(umtx, UMTX_OP_WAIT, id, 0, (void *)abstime));
|
||||
}
|
||||
|
||||
/* Wake threads waiting on a user address. */
|
||||
static __inline int
|
||||
umtx_wake(struct umtx *umtx, int nr_wakeup)
|
||||
{
|
||||
/* return how many threads were woke up, -1 if error */
|
||||
return _umtx_op(umtx, UMTX_OP_WAKE, nr_wakeup, 0, 0);
|
||||
return (- _umtx_op(umtx, UMTX_OP_WAKE, nr_wakeup, 0, 0));
|
||||
}
|
||||
|
||||
#endif /* !_KERNEL */
|
||||
|
Loading…
x
Reference in New Issue
Block a user