aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib9/rendez-signal.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/lib9/rendez-signal.c b/src/lib9/rendez-signal.c
index 320bd11a..6c15e7ec 100644
--- a/src/lib9/rendez-signal.c
+++ b/src/lib9/rendez-signal.c
@@ -45,6 +45,7 @@ struct Vous
Vous *link;
Lock lk;
int pid;
+ int wakeup;
ulong val;
ulong tag;
};
@@ -149,8 +150,20 @@ rendezvous(ulong tag, ulong val)
sigaddset(&mask, SIGUSR1);
sigprocmask(SIG_SETMASK, &mask, NULL);
sigdelset(&mask, SIGUSR1);
+ v->wakeup = 0;
unlock(&v->lk);
- sigsuspend(&mask);
+ for(;;){
+ /*
+ * There may well be random signals flying around,
+ * so we can't be sure why we woke up. If we weren't
+ * properly awakened, we need to go back to sleep.
+ */
+ sigsuspend(&mask);
+ lock(&v->lk); /* do some memory synchronization */
+ unlock(&v->lk);
+ if(v->wakeup == 1)
+ break;
+ }
rval = v->val;
if(DBG)fprint(2, "pid is %d, awake\n", me);
putvous(v);
@@ -169,6 +182,7 @@ rendezvous(ulong tag, ulong val)
lock(&v->lk);
rval = v->val;
v->val = val;
+ v->wakeup = 1;
unlock(&v->lk);
if(kill(vpid, SIGUSR1) < 0){
if(DBG)fprint(2, "pid is %d, kill %d failed: %r\n", me, vpid);