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:
David Xu 2005-01-12 05:55:52 +00:00
parent 9e777bc6e2
commit 333d4875cd
2 changed files with 29 additions and 28 deletions

View File

@ -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);
}

View File

@ -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 */