commit 1c39bb59193d68cb6119a053260d1381d303b24d
parent 52aeb2f9b9c67c777b683206afaa12050251a689
Author: rsc <devnull@localhost>
Date: Thu, 20 May 2004 21:39:24 +0000
fix race.
Diffstat:
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git 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);