summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--emu/port/dis.c12
-rw-r--r--include/interp.h10
-rw-r--r--include/version.h2
-rw-r--r--os/port/dis.c17
5 files changed, 38 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES
index 291a0857..425b4d0f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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;
}