svn commit: r249644 - head/sys/kern
Jilles Tjoelker
jilles at FreeBSD.org
Fri Apr 19 10:16:01 UTC 2013
Author: jilles
Date: Fri Apr 19 10:16:00 2013
New Revision: 249644
URL: http://svnweb.freebsd.org/changeset/base/249644
Log:
sem: Restart the POSIX sem_* calls after signals with SA_RESTART set.
Programs often do not expect an [EINTR] return from sem_wait() and POSIX
only allows it if the signal was installed without SA_RESTART. The timeout
in sem_timedwait() is absolute so it can be restarted normally.
The umtx call can be invoked with a relative timeout and in that case
[ERESTART] must be changed to [EINTR]. However, libc does not do this.
The old POSIX semaphore implementation did this correctly (before r249566),
unlike the new umtx one.
It may be desirable to avoid [EINTR] completely, which matches the pthread
functions and is explicitly permitted by POSIX. However, the kernel must
return [EINTR] at least for signals with SA_RESTART clear, otherwise pthread
cancellation will not abort a semaphore wait. In this commit, only restore
the 8.x behaviour which is also permitted by POSIX.
Discussed with: jhb
MFC after: 1 week
Modified:
head/sys/kern/kern_umtx.c
head/sys/kern/uipc_sem.c
Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c Fri Apr 19 09:19:10 2013 (r249643)
+++ head/sys/kern/kern_umtx.c Fri Apr 19 10:16:00 2013 (r249644)
@@ -2980,7 +2980,9 @@ do_sem_wait(struct thread *td, struct _u
error = 0;
else {
umtxq_remove(uq);
- if (error == ERESTART)
+ /* A relative timeout cannot be restarted. */
+ if (error == ERESTART && timeout != NULL &&
+ (timeout->_flags & UMTX_ABSTIME) == 0)
error = EINTR;
}
umtxq_unlock(&uq->uq_key);
Modified: head/sys/kern/uipc_sem.c
==============================================================================
--- head/sys/kern/uipc_sem.c Fri Apr 19 09:19:10 2013 (r249643)
+++ head/sys/kern/uipc_sem.c Fri Apr 19 10:16:00 2013 (r249644)
@@ -846,8 +846,6 @@ kern_sem_wait(struct thread *td, semid_t
err:
mtx_unlock(&sem_lock);
fdrop(fp, td);
- if (error == ERESTART)
- error = EINTR;
DP(("<<< kern_sem_wait leaving, pid=%d, error = %d\n",
(int)td->td_proc->p_pid, error));
return (error);
More information about the svn-src-all
mailing list