diff options
author | rodri <rgl@antares-labs.eu> | 2023-08-12 05:35:54 +0000 |
---|---|---|
committer | rodri <rgl@antares-labs.eu> | 2023-08-12 05:35:54 +0000 |
commit | 8285721acfc247d57e0831503543dd29290ac4c5 (patch) | |
tree | 7e40088ab8c403d36ff455dc66ab6b8ab5a16904 /btsd.c | |
parent | 7b76e7467822316b699847cbd61a0ecb985882d3 (diff) | |
download | battleship-8285721acfc247d57e0831503543dd29290ac4c5.tar.gz battleship-8285721acfc247d57e0831503543dd29290ac4c5.tar.bz2 battleship-8285721acfc247d57e0831503543dd29290ac4c5.zip |
latest try of player mgmt procedure. (not working)
Diffstat (limited to 'btsd.c')
-rw-r--r-- | btsd.c | 207 |
1 files changed, 178 insertions, 29 deletions
@@ -1,6 +1,5 @@ #include <u.h> #include <libc.h> -#include <bio.h> #include <thread.h> #include <draw.h> #include <mouse.h> @@ -10,44 +9,182 @@ #include "fns.h" int debug; +int mainstacksize = 16*KB; +Playerq playerq; + + +void +pushplayer(Player *p) +{ + qlock(&playerq); + if(++playerq.nplayers > playerq.cap){ + playerq.cap = playerq.nplayers; + playerq.players = erealloc(playerq.players, playerq.cap * sizeof p); + } + playerq.players[playerq.nplayers-1] = p; + qunlock(&playerq); +} + +Player * +popplayer(void) +{ + Player *p; + + p = nil; + if(playerq.nplayers > 0){ + qlock(&playerq); + p = playerq.players[--playerq.nplayers]; + qunlock(&playerq); + } + return p; +} + +void +netrecvthread(void *arg) +{ + Chanpipe *cp; + Ioproc *io; + char buf[256]; + int n; + + cp = arg; + io = ioproc(); + + while((n = ioread(io, cp->fd, buf, sizeof(buf)-1)) > 0){ + buf[n] = 0; + chanprint(cp->c, "%s", buf); + } + chanclose(cp->c); + if(debug) + fprint(2, "[%d] %d lost connection\n", threadpid(threadid()), threadid()); +} void serveproc(void *arg) { - Biobuf *bin, *bout; - NetConnInfo *nci; - char *line; - int fd, linelen; - - fd = *(int*)arg; - nci = getnetconninfo(nil, fd); - if(nci == nil) + NetConnInfo *nci[2]; + Player **m; + Chanpipe *cp; + Alt a[3]; + int i, n0; + char *s; + + threadsetname("serveproc "); + + m = arg; + s = nil; + + nci[0] = getnetconninfo(nil, m[0]->fd); + nci[1] = getnetconninfo(nil, m[1]->fd); + if(nci[0] == nil || nci[1] == nil) sysfatal("getnetconninfo: %r"); - threadsetname("serveproc %s", nci->raddr); - freenetconninfo(nci); - - bin = Bfdopen(fd, OREAD); - bout = Bfdopen(fd, OWRITE); - if(bin == nil || bout == nil) - sysfatal("Bfdopen: %r"); - - while((line = Brdline(bin, '\n')) != nil){ - linelen = Blinelen(bin); - Bwrite(bout, line, linelen); - Bflush(bout); - print("%.*s", linelen, line); + threadsetname("serveproc %s ↔ %s", nci[0]->raddr, nci[1]->raddr); + freenetconninfo(nci[0]); + freenetconninfo(nci[1]); + + cp = emalloc(2*sizeof(Chanpipe)); + cp[0].c = chancreate(sizeof(char*), 1); + cp[0].fd = m[0]->fd; + cp[1].c = chancreate(sizeof(char*), 1); + cp[1].fd = m[1]->fd; + + a[0].c = cp[0].c; a[0].v = &s; a[0].op = CHANRCV; + a[1].c = cp[1].c; a[1].v = &s; a[1].op = CHANRCV; + a[2].op = CHANEND; + + threadcreate(netrecvthread, &cp[0], mainstacksize); + threadcreate(netrecvthread, &cp[1], mainstacksize); + + n0 = truerand(); + write(m[n0%2]->fd, "wait", 4); + write(m[(n0+1)%2]->fd, "play", 4); + + while((i = alt(a)) >= 0){ + if(debug) + fprint(2, "[%d] %d said '%s'\n", threadpid(threadid()), threadid(), s); + if(a[i].err != nil){ + write(m[i^1]->fd, "won", 3); + /* TODO free the player */ + pushplayer(m[i^1]); + goto out; + } + if(write(m[i^1]->fd, s, strlen(s)) != strlen(s)){ + write(m[i]->fd, "won", 3); + /* TODO free the player */ + pushplayer(m[i]); + goto out; + } + free(s); + } +out: + if(debug) + fprint(2, "[%d] serveproc ending\n", threadpid(threadid())); + chanclose(cp[0].c); + chanclose(cp[1].c); + /* TODO make sure this is the last thread to exit */ +// recv(cp[0].done) +// recv(cp[1].done) + free(m); +} + +void +reaper(void *) +{ + Ioproc *io; + char buf[8]; + ulong i; + int n; + + threadsetname("reaper"); + + io = ioproc(); + + for(;;){ + for(i = 0; i < playerq.nplayers; i++){ + n = read(playerq.players[i]->sfd, buf, sizeof buf); + if(n < 0 || strncmp(buf, "Closed", 6) == 0){ + qlock(&playerq); + close(playerq.players[i]->fd); + close(playerq.players[i]->sfd); + free(playerq.players[i]); + memmove(&playerq.players[i], &playerq.players[i+1], (--playerq.nplayers-i)*sizeof(Player*)); + qunlock(&playerq); + } + } + iosleep(io, HZ2MS(3)); } +} + +void +matchmaker(void *) +{ + Player **match; + + threadsetname("matchmaker"); - Bterm(bin); - Bterm(bout); + for(;;){ + if(playerq.nplayers < 2){ + sleep(100); + continue; + } + + match = emalloc(2*sizeof(Player*)); + match[0] = popplayer(); + match[1] = popplayer(); + match[1]->o = match[0]; + match[0]->o = match[1]; + + proccreate(serveproc, match, mainstacksize); + } } void listenthread(void *arg) { - char *addr, adir[40], ldir[40]; - int acfd, lcfd, dfd; + char *addr, adir[40], ldir[40], aux[128], *s; + int acfd, lcfd, dfd, sfd; + Player *p; addr = arg; @@ -57,11 +194,21 @@ listenthread(void *arg) if(debug) fprint(2, "listening on %s\n", addr); - + while((lcfd = listen(adir, ldir)) >= 0){ if((dfd = accept(lcfd, ldir)) >= 0){ - proccreate(serveproc, &dfd, mainstacksize); - close(dfd); + fd2path(dfd, aux, sizeof aux); + s = strrchr(aux, '/'); + *s = 0; + snprint(aux, sizeof aux, "%s/status", aux); + sfd = open(aux, OREAD); + if(sfd < 0) + sysfatal("open: %r"); + + p = emalloc(sizeof *p); + p->fd = dfd; + p->sfd = sfd; + pushplayer(p); } close(lcfd); } @@ -94,5 +241,7 @@ threadmain(int argc, char *argv[]) usage(); threadcreate(listenthread, addr, mainstacksize); + proccreate(matchmaker, nil, mainstacksize); + proccreate(reaper, nil, mainstacksize); yield(); } |