diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-02-28 20:06:42 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-02-28 20:06:42 +0100 |
commit | bab11d536f278a5856c42b00fa87f8d5b8d29065 (patch) | |
tree | 09dbb65a0f07b88f73d755914eb8b9abbb56d425 | |
parent | 1d7bfa53e29b52afb43d02eed126a37374fa3be9 (diff) |
pfinet: Fix spurious EINTR errors from selectv0.9.git20250304
While sleeping in pthread_hurd_cond_timedwait_np, current->signal will be
overwritten by the management of other RPCs, so we have to give it some
value on wake up.
Also, if we previously got interrupted, we shouldn't ever try to wait again
until exiting from the RPC: an interrupt means we really want to try hard to
finish the RPC.
Thanks Zhaoming Luo <zhmingluo@163.com> for the deep investigation and
draft!
-rw-r--r-- | pfinet/glue-include/linux/sched.h | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/pfinet/glue-include/linux/sched.h b/pfinet/glue-include/linux/sched.h index b91c3edf..31cfecbb 100644 --- a/pfinet/glue-include/linux/sched.h +++ b/pfinet/glue-include/linux/sched.h @@ -113,9 +113,23 @@ interruptible_sleep_on_timeout (struct wait_queue **p, struct timespec *tsp) isroot = current->isroot; /* This is our context that needs switched. */ next_wait = current->next_wait; /* This too, for multiple schedule calls. */ current->next_wait = 0; - err = pthread_hurd_cond_timedwait_np(c, &global_lock, tsp); - if (err == EINTR) - current->signal = 1; /* We got cancelled, mark it for later. */ + + if (current->signal) + /* We already got interrupted previously, keep interrupting the + RPC. */ + err = EINTR; + else + { + /* This is the only place where we sleep within an RPC and release the global + lock while serving it. */ + err = pthread_hurd_cond_timedwait_np(c, &global_lock, tsp); + + if (err == EINTR) + current->signal = 1; /* We got cancelled, mark it for Linux code to bail out. */ + else + current->signal = 0; + } + current->isroot = isroot; /* Switch back to our context. */ current->next_wait = next_wait; return (err == ETIMEDOUT); |