summaryrefslogtreecommitdiff
path: root/pfinet/glue-include/linux/sched.h
diff options
context:
space:
mode:
Diffstat (limited to 'pfinet/glue-include/linux/sched.h')
-rw-r--r--pfinet/glue-include/linux/sched.h20
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);