aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmavect <amavect@gmail.com>2023-09-07 02:38:36 +0000
committerrodri <rgl@antares-labs.eu>2023-09-07 02:38:36 +0000
commite29fc9d0f23c62085114cb479032e07b0fb29abb (patch)
tree2244c0208dd48d98f30eb68f85ac7e148e212167
parent2723bb6ff3e339f7f56a6276fa1c7c9f28d63871 (diff)
downloadbattleship-e29fc9d0f23c62085114cb479032e07b0fb29abb.tar.gz
battleship-e29fc9d0f23c62085114cb479032e07b0fb29abb.tar.bz2
battleship-e29fc9d0f23c62085114cb479032e07b0fb29abb.zip
inline spawned threads to threadmain.
Pointers to automatic variables become invalid when threadmain exits. Solution is to reuse threadmain. Use nbsend to avoid deadlock to the draw channel. Input struct is no longer needed, inline it.
-rw-r--r--bts.c102
-rw-r--r--btsd.c10
-rw-r--r--dat.h7
3 files changed, 46 insertions, 73 deletions
diff --git a/bts.c b/bts.c
index 093b4fe..f272239 100644
--- a/bts.c
+++ b/bts.c
@@ -344,7 +344,7 @@ resize(void)
}
}
- send(drawchan, nil);
+ nbsend(drawchan, nil);
}
void
@@ -500,7 +500,7 @@ lmb(Mousectl *mc)
}
break;
}
- send(drawchan, nil);
+ nbsend(drawchan, nil);
}
void
@@ -536,7 +536,7 @@ mmb(Mousectl *mc)
if(rectXarmada(curship->bbox))
curship->bbox = ZR;
- send(drawchan, nil);
+ nbsend(drawchan, nil);
}
}
@@ -584,7 +584,7 @@ rmb(Mousectl *mc)
layoutdone++;
break;
}
- send(drawchan, nil);
+ nbsend(drawchan, nil);
}
void
@@ -605,7 +605,7 @@ mouse(Mousectl *mc)
if(rectinrect(newbbox, localboard.bbox) && !rectXarmada(newbbox)){
curship->p = toboard(&localboard, mc->xy);
curship->bbox = newbbox;
- send(drawchan, nil);
+ nbsend(drawchan, nil);
}
}
@@ -639,44 +639,6 @@ key(Rune r)
}
void
-bobross(void *)
-{
- while(recv(drawchan, nil) > 0)
- redraw();
- sysfatal("painter died");
-}
-
-void
-inputthread(void *arg)
-{
- Input *in;
- Rune r;
- Alt a[4];
-
- in = arg;
-
- a[0].c = in->mc->c; a[0].v = &in->mc->Mouse; a[0].op = CHANRCV;
- a[1].c = in->mc->resizec; a[1].v = nil; a[1].op = CHANRCV;
- a[2].c = in->kc->c; a[2].v = &r; a[2].op = CHANRCV;
- a[3].op = CHANEND;
-
- for(;;)
- switch(alt(a)){
- case -1:
- sysfatal("input thread interrupted");
- case 0:
- mouse(in->mc);
- break;
- case 1:
- resize();
- break;
- case 2:
- key(r);
- break;
- }
-}
-
-void
celebrate(void)
{
static Image *c;
@@ -762,7 +724,7 @@ processcmd(char *cmd)
}
break;
}
- send(drawchan, nil);
+ nbsend(drawchan, nil);
}
void
@@ -821,15 +783,10 @@ void
threadmain(int argc, char *argv[])
{
char *addr;
- /*
- * TODO
- * if it's not static it messes with in.mc->xy later, probably
- * because of an stack overflow somewhere. have to investigate
- * with wpset("w", &in.mc->xy, sizeof(Point*)); in acid(1)
- */
- static char *user;
+ char *user;
int fd;
- Input in;
+ Mousectl *mc;
+ Keyboardctl *kc;
GEOMfmtinstall();
ARGBEGIN{
@@ -856,15 +813,15 @@ threadmain(int argc, char *argv[])
sysfatal("newwindow: %r");
if(initdraw(nil, deffont, "bts") < 0)
sysfatal("initdraw: %r");
- if((in.mc = initmouse(nil, screen)) == nil)
+ if((mc = initmouse(nil, screen)) == nil)
sysfatal("initmouse: %r");
- if((in.kc = initkeyboard(nil)) == nil)
+ if((kc = initkeyboard(nil)) == nil)
sysfatal("initkeyboard: %r");
display->locking = 1;
unlockdisplay(display);
- mctl = in.mc;
+ mctl = mc;
if((user = getenv("user")) == nil)
user = getuser();
snprint(uid, sizeof uid, "%s", user);
@@ -880,13 +837,38 @@ threadmain(int argc, char *argv[])
game.state = Waiting0;
csetcursor(mctl, &patrolcursor);
- drawchan = chancreate(sizeof(void*), 0);
+ drawchan = chancreate(sizeof(void*), 1);
ingress = chancreate(sizeof(char*), 1);
egress = chancreate(sizeof(char*), 1);
- threadcreate(bobross, nil, mainstacksize);
- threadcreate(inputthread, &in, mainstacksize);
threadcreate(netrecvthread, &fd, mainstacksize);
threadcreate(netsendthread, &fd, mainstacksize);
- send(drawchan, nil);
- yield();
+ nbsend(drawchan, nil);
+
+ Rune r;
+ enum {MOUSE, RESIZE, KEYS, DRAW, NONE};
+ Alt a[] = {
+ [MOUSE] = {mc->c, &mc->Mouse, CHANRCV},
+ [RESIZE] = {mc->resizec, nil, CHANRCV},
+ [KEYS] = {kc->c, &r, CHANRCV},
+ [DRAW] = {drawchan, nil, CHANRCV},
+ [NONE] = {nil, nil, CHANEND}
+ };
+
+ for(;;)
+ switch(alt(a)){
+ default:
+ sysfatal("input thread interrupted");
+ case MOUSE:
+ mouse(mc);
+ break;
+ case RESIZE:
+ resize();
+ break;
+ case KEYS:
+ key(r);
+ break;
+ case DRAW:
+ redraw();
+ break;
+ }
}
diff --git a/btsd.c b/btsd.c
index 5a722d2..861add4 100644
--- a/btsd.c
+++ b/btsd.c
@@ -299,14 +299,12 @@ matchmaker(void *)
}
void
-listenthread(void *arg)
+listenthread(char *addr)
{
- char *addr, adir[40], ldir[40], aux[128], *s;
+ char adir[40], ldir[40], aux[128], *s;
int acfd, lcfd, dfd, sfd;
Player *p;
- addr = arg;
-
acfd = announce(addr, adir);
if(acfd < 0)
sysfatal("announce: %r");
@@ -357,12 +355,12 @@ threadmain(int argc, char *argv[])
case 'a':
addr = EARGF(usage());
break;
+ default: usage();
}ARGEND
if(argc != 0)
usage();
proccreate(matchmaker, nil, mainstacksize);
proccreate(reaper, nil, mainstacksize);
- threadcreate(listenthread, addr, mainstacksize);
- yield();
+ listenthread(addr);
}
diff --git a/dat.h b/dat.h
index a4a5df3..a85a177 100644
--- a/dat.h
+++ b/dat.h
@@ -31,7 +31,6 @@ enum {
KB = 1024,
};
-typedef struct Input Input;
typedef struct Ship Ship;
typedef struct Map Map;
typedef struct Board Board;
@@ -40,12 +39,6 @@ typedef struct Playerq Playerq;
typedef struct Match Match;
typedef struct Chanpipe Chanpipe;
-struct Input
-{
- Mousectl *mc;
- Keyboardctl *kc;
-};
-
struct Ship
{
Point2 p; /* board cell */