void twaitinit(void) { threadwaitchan(); /* allocate it before returning */ twaitchan = chancreate(sizeof(Waitreq), 10); threadcreate(waitthread, nil, 128*1024); }
Waitmsg* runprocfd(char *file, char **v, int fd[3]) { int pid, i; threadwaitchan(); pid = threadspawn(fd, file, v); for(i=0; i<3; i++) close(fd[i]); if(pid < 0) return nil; return procwait(pid); }
void threadmain(int argc, char *argv[]) { int i; char *p, *loadfile; Column *c; int ncol; Display *d; rfork(RFENVG|RFNAMEG); ncol = -1; loadfile = nil; ARGBEGIN{ case 'D': {extern int _threaddebuglevel; _threaddebuglevel = ~0; } break; case 'a': globalautoindent = TRUE; break; case 'b': bartflag = TRUE; break; case 'c': p = ARGF(); if(p == nil) goto Usage; ncol = atoi(p); if(ncol <= 0) goto Usage; break; case 'f': fontnames[0] = ARGF(); if(fontnames[0] == nil) goto Usage; break; case 'F': fontnames[1] = ARGF(); if(fontnames[1] == nil) goto Usage; break; case 'l': loadfile = ARGF(); if(loadfile == nil) goto Usage; break; case 'm': mtpt = ARGF(); if(mtpt == nil) goto Usage; break; case 'r': swapscrollbuttons = TRUE; break; case 'W': winsize = ARGF(); if(winsize == nil) goto Usage; break; default: Usage: fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n"); threadexitsall("usage"); }ARGEND fontnames[0] = estrdup(fontnames[0]); fontnames[1] = estrdup(fontnames[1]); quotefmtinstall(); fmtinstall('t', timefmt); cputype = getenv("cputype"); objtype = getenv("objtype"); home = getenv("HOME"); acmeshell = getenv("acmeshell"); if(acmeshell && *acmeshell == '\0') acmeshell = nil; p = getenv("tabstop"); if(p != nil){ maxtab = strtoul(p, nil, 0); free(p); } if(maxtab == 0) maxtab = 4; if(loadfile) rowloadfonts(loadfile); putenv("font", fontnames[0]); snarffd = open("/dev/snarf", OREAD|OCEXEC); /* if(cputype){ sprint(buf, "/acme/bin/%s", cputype); bind(buf, "/bin", MBEFORE); } bind("/acme/bin", "/bin", MBEFORE); */ getwd(wdir, sizeof wdir); /* if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){ fprint(2, "acme: can't open display: %r\n"); threadexitsall("geninitdraw"); } */ if(initdraw(derror, fontnames[0], "acme") < 0){ fprint(2, "acme: can't open display: %r\n"); threadexitsall("initdraw"); } d = display; font = d->defaultfont; /*assert(font); */ reffont.f = font; reffonts[0] = &reffont; incref(&reffont.ref); /* one to hold up 'font' variable */ incref(&reffont.ref); /* one to hold up reffonts[0] */ fontcache = emalloc(sizeof(Reffont*)); nfontcache = 1; fontcache[0] = &reffont; iconinit(); timerinit(); rxinit(); cwait = threadwaitchan(); ccommand = chancreate(sizeof(Command**), 0); ckill = chancreate(sizeof(Rune*), 0); cxfidalloc = chancreate(sizeof(Xfid*), 0); cxfidfree = chancreate(sizeof(Xfid*), 0); cnewwindow = chancreate(sizeof(Channel*), 0); cerr = chancreate(sizeof(char*), 0); cedit = chancreate(sizeof(int), 0); cexit = chancreate(sizeof(int), 0); cwarn = chancreate(sizeof(void*), 1); if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){ fprint(2, "acme: can't create initial channels: %r\n"); threadexitsall("channels"); } chansetname(ccommand, "ccommand"); chansetname(ckill, "ckill"); chansetname(cxfidalloc, "cxfidalloc"); chansetname(cxfidfree, "cxfidfree"); chansetname(cnewwindow, "cnewwindow"); chansetname(cerr, "cerr"); chansetname(cedit, "cedit"); chansetname(cexit, "cexit"); chansetname(cwarn, "cwarn"); mousectl = initmouse(nil, screen); if(mousectl == nil){ fprint(2, "acme: can't initialize mouse: %r\n"); threadexitsall("mouse"); } mouse = &mousectl->m; keyboardctl = initkeyboard(nil); if(keyboardctl == nil){ fprint(2, "acme: can't initialize keyboard: %r\n"); threadexitsall("keyboard"); } mainpid = getpid(); startplumbing(); /* plumbeditfd = plumbopen("edit", OREAD|OCEXEC); if(plumbeditfd < 0) fprint(2, "acme: can't initialize plumber: %r\n"); else{ cplumb = chancreate(sizeof(Plumbmsg*), 0); threadcreate(plumbproc, nil, STACK); } plumbsendfd = plumbopen("send", OWRITE|OCEXEC); */ fsysinit(); #define WPERCOL 8 disk = diskinit(); if(!loadfile || !rowload(&row, loadfile, TRUE)){ rowinit(&row, screen->clipr); if(ncol < 0){ if(argc == 0) ncol = 2; else{ ncol = (argc+(WPERCOL-1))/WPERCOL; if(ncol < 2) ncol = 2; } } if(ncol == 0) ncol = 2; for(i=0; i<ncol; i++){ c = rowadd(&row, nil, -1); if(c==nil && i==0) error("initializing columns"); } c = row.col[row.ncol-1]; if(argc == 0) readfile(c, wdir); else for(i=0; i<argc; i++){ p = utfrrune(argv[i], '/'); if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol) readfile(c, argv[i]); else readfile(row.col[i/WPERCOL], argv[i]); } } flushimage(display, 1); acmeerrorinit(); threadcreate(keyboardthread, nil, STACK); threadcreate(mousethread, nil, STACK); threadcreate(waitthread, nil, STACK); threadcreate(xfidallocthread, nil, STACK); threadcreate(newwindowthread, nil, STACK); /* threadcreate(shutdownthread, nil, STACK); */ threadnotify(shutdown, 1); recvul(cexit); killprocs(); threadexitsall(nil); }
/* * watch the exiting children */ Channel *twaitchan; /* chan(Waitreq) */ void waitthread(void *v) { Alt a[3]; Waitmsg *w, **wq; Waitreq *rq, r; int i, nrq, nwq; threadsetname("waitthread"); a[0].c = threadwaitchan(); a[0].v = &w; a[0].op = CHANRCV; a[1].c = twaitchan; a[1].v = &r; a[1].op = CHANRCV; a[2].op = CHANEND; nrq = 0; nwq = 0; rq = nil; wq = nil; dprint("wait: start\n"); for(;;){ cont2:; dprint("wait: alt\n"); switch(alt(a)){ case 0: dprint("wait: pid %d exited\n", w->pid); for(i=0; i<nrq; i++){ if(rq[i].pid == w->pid){ dprint("wait: match with rq chan %p\n", rq[i].c); sendp(rq[i].c, w); rq[i] = rq[--nrq]; goto cont2; } } if(i == nrq){ dprint("wait: queueing waitmsg\n"); wq = erealloc(wq, (nwq+1)*sizeof(wq[0])); wq[nwq++] = w; } break; case 1: dprint("wait: req for pid %d chan %p\n", r.pid, r.c); for(i=0; i<nwq; i++){ if(w->pid == r.pid){ dprint("wait: match with waitmsg\n"); sendp(r.c, w); wq[i] = wq[--nwq]; goto cont2; } } if(i == nwq){ dprint("wait: queueing req\n"); rq = erealloc(rq, (nrq+1)*sizeof(rq[0])); rq[nrq] = r; dprint("wait: queueing req pid %d chan %p\n", rq[nrq].pid, rq[nrq].c); nrq++; } break; } } }
void threadmain(int argc, char *argv[]) { int i; char *p, *loadfile; char buf[256]; Column *c; int ncol; Display *d; static void *arg[1]; rfork(RFENVG|RFNAMEG); ncol = -1; loadfile = nil; ARGBEGIN{ case 'a': globalautoindent = TRUE; break; case 'b': bartflag = TRUE; break; case 'c': p = ARGF(); if(p == nil) goto Usage; ncol = atoi(p); if(ncol <= 0) goto Usage; break; case 'f': fontnames[0] = ARGF(); if(fontnames[0] == nil) goto Usage; break; case 'F': fontnames[1] = ARGF(); if(fontnames[1] == nil) goto Usage; break; case 'l': loadfile = ARGF(); if(loadfile == nil) goto Usage; break; default: Usage: fprint(2, "usage: acme [-ab] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n"); exits("usage"); }ARGEND if(fontnames[0] == nil) fontnames[0] = getenv("font"); if(fontnames[0] == nil) fontnames[0] = "/lib/font/bit/vga/unicode.font"; if(access(fontnames[0], 0) < 0){ fprint(2, "acme: can't access %s: %r\n", fontnames[0]); exits("font open"); } if(fontnames[1] == nil) fontnames[1] = fontnames[0]; fontnames[0] = estrdup(fontnames[0]); fontnames[1] = estrdup(fontnames[1]); quotefmtinstall(); cputype = getenv("cputype"); objtype = getenv("objtype"); home = getenv("home"); p = getenv("tabstop"); if(p != nil){ maxtab = strtoul(p, nil, 0); free(p); } if(maxtab == 0) maxtab = 4; if(loadfile) rowloadfonts(loadfile); putenv("font", fontnames[0]); snarffd = open("/dev/snarf", OREAD|OCEXEC); if(cputype){ sprint(buf, "/acme/bin/%s", cputype); bind(buf, "/bin", MBEFORE); } bind("/acme/bin", "/bin", MBEFORE); getwd(wdir, sizeof wdir); if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){ fprint(2, "acme: can't open display: %r\n"); exits("geninitdraw"); } d = display; font = d->defaultfont; reffont.f = font; reffonts[0] = &reffont; incref(&reffont); /* one to hold up 'font' variable */ incref(&reffont); /* one to hold up reffonts[0] */ fontcache = emalloc(sizeof(Reffont*)); nfontcache = 1; fontcache[0] = &reffont; iconinit(); timerinit(); rxinit(); cwait = threadwaitchan(); ccommand = chancreate(sizeof(Command**), 0); ckill = chancreate(sizeof(Rune*), 0); cxfidalloc = chancreate(sizeof(Xfid*), 0); cxfidfree = chancreate(sizeof(Xfid*), 0); cnewwindow = chancreate(sizeof(Channel*), 0); cerr = chancreate(sizeof(char*), 0); cedit = chancreate(sizeof(int), 0); cexit = chancreate(sizeof(int), 0); cwarn = chancreate(sizeof(void*), 1); if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){ fprint(2, "acme: can't create initial channels: %r\n"); threadexitsall("channels"); } mousectl = initmouse(nil, screen); if(mousectl == nil){ fprint(2, "acme: can't initialize mouse: %r\n"); threadexitsall("mouse"); } mouse = mousectl; keyboardctl = initkeyboard(nil); if(keyboardctl == nil){ fprint(2, "acme: can't initialize keyboard: %r\n"); threadexitsall("keyboard"); } mainpid = getpid(); plumbeditfd = plumbopen("edit", OREAD|OCEXEC); if(plumbeditfd >= 0){ cplumb = chancreate(sizeof(Plumbmsg*), 0); proccreate(plumbproc, nil, STACK); } plumbsendfd = plumbopen("send", OWRITE|OCEXEC); fsysinit(); #define WPERCOL 8 disk = diskinit(); if(!loadfile || !rowload(&row, loadfile, TRUE)){ rowinit(&row, screen->clipr); if(ncol < 0){ if(argc == 0) ncol = 2; else{ ncol = (argc+(WPERCOL-1))/WPERCOL; if(ncol < 2) ncol = 2; } } if(ncol == 0) ncol = 2; for(i=0; i<ncol; i++){ c = rowadd(&row, nil, -1); if(c==nil && i==0) error("initializing columns"); } c = row.col[row.ncol-1]; if(argc == 0) readfile(c, wdir); else for(i=0; i<argc; i++){ p = utfrrune(argv[i], '/'); if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol) readfile(c, argv[i]); else readfile(row.col[i/WPERCOL], argv[i]); } } flushimage(display, 1); acmeerrorinit(); threadcreate(keyboardthread, nil, STACK); threadcreate(mousethread, nil, STACK); threadcreate(waitthread, nil, STACK); threadcreate(xfidallocthread, nil, STACK); threadcreate(newwindowthread, nil, STACK); threadnotify(shutdown, 1); recvul(cexit); killprocs(); threadexitsall(nil); }
void threadmain(int argc, char **argv) { int i; int nofork; char *prog; Job *j; ventilogging = 1; ventifmtinstall(); #ifdef PLAN9PORT bin = unsharp("#9/bin/venti"); #else bin = "/bin/venti"; #endif nofork = 0; ARGBEGIN{ case 'b': bin = EARGF(usage()); break; case 's': nofork = 1; break; default: usage(); }ARGEND if(argc != 1) usage(); if(rdconf(argv[0], &conf) < 0) sysfatal("reading config: %r"); if(conf.httpaddr == nil) sysfatal("config has no httpaddr"); if(conf.smtp != nil && conf.mailfrom == nil) sysfatal("config has smtp but no mailfrom"); if(conf.smtp != nil && conf.mailto == nil) sysfatal("config has smtp but no mailto"); if((mirrorprog = regcomp(mirrorregexp)) == nil) sysfatal("mirrorregexp did not complete"); if((verifyprog = regcomp(verifyregexp)) == nil) sysfatal("verifyregexp did not complete"); if(conf.nverify > 0 && conf.verifyfreq == 0) sysfatal("config has no verifyfreq"); if(conf.nmirror > 0 && conf.mirrorfreq == 0) sysfatal("config has no mirrorfreq"); time0 = time(0); // sendmail("startup", "mgr is starting\n"); logbuf = vtmalloc(LogSize+1); // +1 for NUL errlog = vtlogopen("errors", LogSize); job = vtmalloc((conf.nmirror+conf.nverify)*sizeof job[0]); prog = smprint("%s/mirrorarenas", bin); for(i=0; i<conf.nmirror; i++) { // job: /bin/venti/mirrorarenas -v src dst // filter output j = &job[njob++]; mkjob(j, prog, "-v", conf.mirror[i].src, conf.mirror[i].dst, nil); j->name = smprint("mirror %s %s", conf.mirror[i].src, conf.mirror[i].dst); j->ok = mirrorok; j->freq = conf.mirrorfreq; // 4 hours // TODO: put in config j->offset = (double)i/conf.nmirror; } prog = smprint("%s/verifyarena", bin); for(i=0; i<conf.nverify; i++) { // job: /bin/venti/verifyarena -b 64M -s 1000 -v arena // filter output j = &job[njob++]; mkjob(j, prog, "-b64M", "-s1000", conf.verify[i], nil); j->name = smprint("verify %s", conf.verify[i]); j->ok = verifyok; j->freq = conf.verifyfreq; j->offset = (double)i/conf.nverify; } httpdobj("/mgr", hmanager); httpdobj("/log", xlog); vtproc(httpdproc, conf.httpaddr); vtproc(waitproc, threadwaitchan()); if(nofork) manager(nil); else vtproc(manager, nil); }
void threadmain(int argc, char **argv) { int p[2], fd[3], pid[2]; char *a[4], *devdraw; ARGBEGIN{}ARGEND if(argc != 1) usage(); // Make sure we don't kill our parent whilst killing // our children. setsid(); if(pipe(p) < 0) sysfatal("pipe: %r"); fd[0] = dup(p[0], -1); fd[1] = dup(p[0], -1); fd[2] = dup(2, -1); a[0] = "rc"; a[1] = "-c"; a[2] = argv[0]; a[3] = nil; if((pid[0] = threadspawn(fd, a[0], a)) < 0) sysfatal("threadspawn: %r"); fd[0] = dup(p[1], -1); fd[1] = dup(p[1], -1); fd[2] = dup(2, -1); putenv("NOLIBTHREADDAEMONIZE", "1"); devdraw = getenv("DEVDRAW"); if(devdraw == nil) devdraw = "devdraw"; if((pid[1] = threadspawnl(fd, devdraw, devdraw, "(devdraw)", nil)) < 0) sysfatal("threadspawnl: %r"); close(p[0]); close(p[1]); recvp(threadwaitchan()); postnote(PNGROUP, pid[0], "hangup"); postnote(PNGROUP, pid[1], "hangup"); //recvp(threadwaitchan()); threadexitsall(""); /* if ((pid = fork()) < 0) sysfatal("fork: %r"); switch(pid){ case 0: close(p[0]); dup(p[1], 0); dup(p[1], 1); a[0] = "rc"; a[1] = "-c"; a[2] = argv[0]; a[3] = nil; if(exec("rc", a) < 0) sysfatal("execl: %r"); default: close(p[1]); dup(p[0], 0); dup(p[0], 1); putenv("NOLIBTHREADDAEMONIZE", "1"); devdraw = getenv("DEVDRAW"); if(devdraw == nil) devdraw = "devdraw"; if(execl(devdraw, devdraw, "(devdraw)", nil) < 0) sysfatal("execl: %r"); } exits(0); */ }