Cygwin: Implement sigtimedwait

Abstract out common code from sigwait/sigwaitinfo/sigtimedwait to
implement the latter.
This commit is contained in:
Mark Geisert 2017-12-14 17:05:55 -08:00 committed by Corinna Vinschen
parent 314ddf908c
commit 24ff42d79a
5 changed files with 39 additions and 5 deletions

View File

@ -1326,6 +1326,7 @@ sigrelse SIGFE
sigset SIGFE
sigsetjmp NOSIGFE
sigsuspend SIGFE
sigtimedwait SIGFE
sigwait SIGFE
sigwaitinfo SIGFE
sin NOSIGFE

View File

@ -492,12 +492,13 @@ details. */
321: Export wmempcpy.
322: [w]scanf %m modifier.
323: scanf %l[ conversion.
324: Export sigtimedwait.
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
sigaltstack, sethostname. */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 323
#define CYGWIN_VERSION_API_MINOR 324
/* There is also a compatibity version number associated with the shared memory
regions. It is incremented when incompatible changes are made to the shared

View File

@ -575,6 +575,29 @@ siginterrupt (int sig, int flag)
return res;
}
static int sigwait_common (const sigset_t *, siginfo_t *, PLARGE_INTEGER);
extern "C" int
sigtimedwait (const sigset_t *set, siginfo_t *info, const timespec *timeout)
{
LARGE_INTEGER waittime;
if (timeout)
{
if (timeout->tv_sec < 0
|| timeout->tv_nsec < 0 || timeout->tv_nsec > (NSPERSEC * 100LL))
{
set_errno (EINVAL);
return -1;
}
/* convert timespec to 100ns units */
waittime.QuadPart = (LONGLONG) timeout->tv_sec * NSPERSEC
+ ((LONGLONG) timeout->tv_nsec + 99LL) / 100LL;
}
return sigwait_common (set, info, timeout ? &waittime : cw_infinite);
}
extern "C" int
sigwait (const sigset_t *set, int *sig_ptr)
{
@ -582,7 +605,7 @@ sigwait (const sigset_t *set, int *sig_ptr)
do
{
sig = sigwaitinfo (set, NULL);
sig = sigwait_common (set, NULL, cw_infinite);
}
while (sig == -1 && get_errno () == EINTR);
if (sig > 0)
@ -592,6 +615,12 @@ sigwait (const sigset_t *set, int *sig_ptr)
extern "C" int
sigwaitinfo (const sigset_t *set, siginfo_t *info)
{
return sigwait_common (set, info, cw_infinite);
}
static int
sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime)
{
int res = -1;
@ -602,7 +631,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
set_signal_mask (_my_tls.sigwait_mask, *set);
sig_dispatch_pending (true);
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
switch (cygwait (NULL, waittime, cw_sig_eintr | cw_cancel | cw_cancel_self))
{
case WAIT_SIGNALED:
if (!sigismember (set, _my_tls.infodata.si_signo))
@ -619,6 +648,9 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
_my_tls.unlock ();
}
break;
case WAIT_TIMEOUT:
set_errno (EAGAIN);
break;
default:
__seterrno ();
break;

View File

@ -708,7 +708,7 @@ pthread::cancel ()
* sendto ()
* sigpause ()
* sigsuspend ()
o sigtimedwait ()
* sigtimedwait ()
* sigwait ()
* sigwaitinfo ()
* sleep ()

View File

@ -888,6 +888,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
sigset
sigsetjmp
sigsuspend
sigtimedwait
sigwait
sigwaitinfo
sin
@ -1582,7 +1583,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
pthread_mutex_consistent
putmsg
setnetent
sigtimedwait
timer_getoverrun
ulimit
waitid