hurd: Fix implementation of setitimer.

The preemptor sigcode doesn't match since the POSIX sigcode SI_TIMER is
used when SIGALRM is sent. In addition, The inline version of
hurd_preempt_signals doesn't update _hurdsig_preempted_set. For these
reasons, the preemptor would be skipped by post_signal.

    * sysdeps/mach/hurd/setitimer.c (setitimer_locked): Fix preemptor setup.
This commit is contained in:
Samuel Thibault 2019-08-30 01:04:17 +02:00
parent 4b068090a0
commit f0e84494b1
2 changed files with 13 additions and 8 deletions

View File

@ -2,6 +2,7 @@
* hurd/hurdselect.c (_hurd_select): Always call __io_select with no * hurd/hurdselect.c (_hurd_select): Always call __io_select with no
timeout. timeout.
* sysdeps/mach/hurd/setitimer.c (setitimer_locked): Fix preemptor setup.
2019-08-29 Mihailo Stojanovic <mihailo.stojanovic@rt-rk.com> 2019-08-29 Mihailo Stojanovic <mihailo.stojanovic@rt-rk.com>

View File

@ -128,7 +128,8 @@ timer_thread (void)
/* Forward declaration. */ /* Forward declaration. */
static int setitimer_locked (const struct itimerval *new, static int setitimer_locked (const struct itimerval *new,
struct itimerval *old, void *crit); struct itimerval *old, void *crit,
int hurd_siglocked);
static sighandler_t static sighandler_t
restart_itimer (struct hurd_signal_preemptor *preemptor, restart_itimer (struct hurd_signal_preemptor *preemptor,
@ -142,7 +143,7 @@ restart_itimer (struct hurd_signal_preemptor *preemptor,
/* Either reload or disable the itimer. */ /* Either reload or disable the itimer. */
__spin_lock (&_hurd_itimer_lock); __spin_lock (&_hurd_itimer_lock);
it.it_value = it.it_interval = _hurd_itimerval.it_interval; it.it_value = it.it_interval = _hurd_itimerval.it_interval;
setitimer_locked (&it, NULL, NULL); setitimer_locked (&it, NULL, NULL, 1);
/* Continue with normal delivery (or hold, etc.) of SIGALRM. */ /* Continue with normal delivery (or hold, etc.) of SIGALRM. */
return SIG_ERR; return SIG_ERR;
@ -154,7 +155,7 @@ restart_itimer (struct hurd_signal_preemptor *preemptor,
static int static int
setitimer_locked (const struct itimerval *new, struct itimerval *old, setitimer_locked (const struct itimerval *new, struct itimerval *old,
void *crit) void *crit, int hurd_siglocked)
{ {
struct itimerval newval; struct itimerval newval;
struct timeval now, remaining, elapsed; struct timeval now, remaining, elapsed;
@ -192,16 +193,19 @@ setitimer_locked (const struct itimerval *new, struct itimerval *old,
run `restart_itimer' each time a SIGALRM would arrive. */ run `restart_itimer' each time a SIGALRM would arrive. */
static struct hurd_signal_preemptor preemptor = static struct hurd_signal_preemptor preemptor =
{ {
__sigmask (SIGALRM), 0, 0, __sigmask (SIGALRM), SI_TIMER, SI_TIMER,
&restart_itimer, &restart_itimer,
}; };
__mutex_lock (&_hurd_siglock); if (!hurd_siglocked)
__mutex_lock (&_hurd_siglock);
if (! preemptor.next && _hurdsig_preemptors != &preemptor) if (! preemptor.next && _hurdsig_preemptors != &preemptor)
{ {
preemptor.next = _hurdsig_preemptors; preemptor.next = _hurdsig_preemptors;
_hurdsig_preemptors = &preemptor; _hurdsig_preemptors = &preemptor;
_hurdsig_preempted_set |= preemptor.signals;
} }
__mutex_unlock (&_hurd_siglock); if (!hurd_siglocked)
__mutex_unlock (&_hurd_siglock);
if (_hurd_itimer_port == MACH_PORT_NULL) if (_hurd_itimer_port == MACH_PORT_NULL)
{ {
@ -349,7 +353,7 @@ __setitimer (enum __itimer_which which, const struct itimerval *new,
crit = _hurd_critical_section_lock (); crit = _hurd_critical_section_lock ();
__spin_lock (&_hurd_itimer_lock); __spin_lock (&_hurd_itimer_lock);
return setitimer_locked (new, old, crit); return setitimer_locked (new, old, crit, 0);
} }
static void static void
@ -364,7 +368,7 @@ fork_itimer (void)
it = _hurd_itimerval; it = _hurd_itimerval;
it.it_value = it.it_interval; it.it_value = it.it_interval;
setitimer_locked (&it, NULL, NULL); setitimer_locked (&it, NULL, NULL, 0);
(void) &fork_itimer; /* Avoid gcc optimizing out the function. */ (void) &fork_itimer; /* Avoid gcc optimizing out the function. */
} }