summaryrefslogtreecommitdiff
path: root/sys/src/9/port/proc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2022-08-17 15:21:22 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2022-08-17 15:21:22 +0000
commitc8e25d2a18c0395431abc5818a1d2f0561b0181f (patch)
treea087f5850d7374b5cfd624244237e97b7937d5fe /sys/src/9/port/proc.c
parent7828ffb8a486e188b61394436a434e8cae4fd487 (diff)
kernel: simplify notify() adding common popnote() function
Handlin notes is common for all architectures except how the note has to be pushed on the user stack. This change adds a popnote() function that returns only the note string or nil if the process should not be notified (no notes or user notes hold off). Popnote() also handles common errors like notify during note handling or missing note handler and will suicide the process in that case.
Diffstat (limited to 'sys/src/9/port/proc.c')
-rw-r--r--sys/src/9/port/proc.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
index 1fad45853..f0822f575 100644
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -899,6 +899,48 @@ wakeup(Rendez *r)
}
/*
+ * pop a note from the calling process or suicide if theres
+ * no note handler or notify during note handling.
+ * Called from notify() with up->debug lock held.
+ */
+char*
+popnote(Ureg *u)
+{
+ assert(!canqlock(&up->debug));
+
+ up->notepending = 0;
+ if(up->nnote == 0)
+ return nil;
+ assert(up->nnote > 0);
+
+ /* hold off user notes during note handling */
+ if(up->notified && up->note[0].flag == NUser)
+ return nil;
+
+ memmove(&up->lastnote, &up->note[0], sizeof(Note));
+ if(--up->nnote)
+ memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
+
+ if(u != nil && strncmp(up->lastnote.msg, "sys:", 4) == 0){
+ int l = strlen(up->lastnote.msg);
+ assert(l < ERRMAX);
+ snprint(up->lastnote.msg+l, ERRMAX-l, " pc=%#p", u->pc);
+ }
+
+ if(up->notify == nil || up->notified){
+ qunlock(&up->debug);
+ if(up->lastnote.flag == NDebug){
+ up->fpstate &= ~FPillegal;
+ pprint("suicide: %s\n", up->lastnote.msg);
+ }
+ pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
+ }
+ up->notified = 1;
+
+ return up->lastnote.msg;
+}
+
+/*
* if waking a sleeping process, this routine must hold both
* p->rlock and r->lock. However, it can't know them in
* the same order as wakeup causing a possible lock ordering