diff options
| -rw-r--r-- | CHANGES | 6 | ||||
| -rw-r--r-- | emu/port/dis.c | 12 | ||||
| -rw-r--r-- | include/interp.h | 10 | ||||
| -rw-r--r-- | include/version.h | 2 | ||||
| -rw-r--r-- | os/port/dis.c | 17 |
5 files changed, 38 insertions, 9 deletions
@@ -1,6 +1,8 @@ +20081106 + os/port/dis.c prevent new spawns during killgrp + also synchronise two killgrps of the same group 20081105 - emu/port/dis.c change to killgrp to prevent new spawns during kill [#117] - (will do os/port/dis.c later) + emu/port/dis.c prevent new spawns during killgrp [#117] 20081022 sh: ignore leading white space in fail: strings, and change empty tail to "failed" /emu/port/devfs-posix.c don't call readdir after it has returned end of file diff --git a/emu/port/dis.c b/emu/port/dis.c index 72fd52ab..7f8db7b2 100644 --- a/emu/port/dis.c +++ b/emu/port/dis.c @@ -238,10 +238,8 @@ delprog(Prog *p, char *msg) } p->state = 0xdeadbeef; free(o->user); - if(p->killstr) - free(p->killstr); - if(p->exstr) - free(p->exstr); + free(p->killstr); + free(p->exstr); free(p); } @@ -558,8 +556,12 @@ killgrp(Prog *p, char *msg) /* interpreter has been acquired */ g = p->group; - if(g == nil || g->head == nil || g->flags & Pkilled) + if(g == nil || g->head == nil) return 0; + while(g->flags & Pkilled){ + release(); + acquire(); + } npid = 0; for(f = g->head; f != nil; f = f->grpnext) if(f->group != g) diff --git a/include/interp.h b/include/interp.h index ab417ae5..15b7068c 100644 --- a/include/interp.h +++ b/include/interp.h @@ -45,6 +45,7 @@ typedef struct Alt Alt; typedef struct Channel Channel; typedef struct Progq Progq; typedef struct Import Import; +typedef struct ILock ILock; typedef struct Inst Inst; typedef struct Module Module; typedef struct Modlink Modlink; @@ -66,6 +67,13 @@ typedef struct Altc Altc; typedef struct Except Except; typedef struct Handler Handler; +struct ILock +{ + int lk; + int pid; + void* ql; +}; + struct Frame { Inst* lr; /* REGLINK isa.h */ @@ -403,6 +411,8 @@ extern void destroylinks(Module*); extern void destroystack(REG*); extern void drawmodinit(void); extern int dynldable(int); +extern void iqlock(ILock*); +extern void iqunlock(ILock*); extern void loadermodinit(void); extern Type* dtype(void (*)(Heap*, int), int, uchar*, int); extern Module* dupmod(Module*); diff --git a/include/version.h b/include/version.h index d1540b2f..cc952732 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define VERSION "Fourth Edition (20081105)" +#define VERSION "Fourth Edition (20081106)" diff --git a/os/port/dis.c b/os/port/dis.c index 2b5ac937..8859a1b9 100644 --- a/os/port/dis.c +++ b/os/port/dis.c @@ -134,6 +134,14 @@ newprog(Prog *p, Modlink *m) Osenv *on, *op; static int pidnum; + if(p != nil){ + if(p->group != nil) + p->flags |= p->group->flags & Pkilled; + if(p->kill != nil) + error(p->kill); + if(p->flags & Pkilled) + error(""); + } n = malloc(sizeof(Prog)+sizeof(Osenv)); if(n == 0){ if(p == nil) @@ -564,20 +572,26 @@ killgrp(Prog *p, char *msg) g = p->group; if(g == nil || g->head == nil) return 0; + while(g->flags & Pkilled){ + release(); + acquire(); + } npid = 0; for(f = g->head; f != nil; f = f->grpnext) if(f->group != g) panic("killgrp"); else npid++; - /* use pids not Prog* because state can change during killprog */ + /* use pids not Prog* because state can change during killprog (eg, in delprog) */ pids = malloc(npid*sizeof(int)); if(pids == nil) error(Enomem); npid = 0; for(f = g->head; f != nil; f = f->grpnext) pids[npid++] = f->pid; + g->flags |= Pkilled; if(waserror()) { + g->flags &= ~Pkilled; free(pids); nexterror(); } @@ -587,6 +601,7 @@ killgrp(Prog *p, char *msg) killprog(f, msg); } poperror(); + g->flags &= ~Pkilled; free(pids); return 1; } |
