implement Handler; include "sys.m"; sys: Sys; sprint: import sys; include "arg.m"; arg: Arg; include "bufio.m"; include "exception.m"; include "http.m"; http: Http; HConn: import http; nexthandler: Handler; excgetter: chan of (int, chan of (int, string, string)); init(m: Http, args: list of string) { sys = load Sys Sys->PATH; arg = load Arg Arg->PATH; http = m; arg->init(args); arg->setusage(sprint("%s handler [args ...]", arg->progname())); args = arg->argv(); if(len args < 1) arg->usage(); if((nexthandler = http->loadhandler(hd args)) == nil) { sys->fprint(sys->fildes(2), "%s: loadhandler %s\n", arg->progname(), hd args); raise "fail:loadhandler"; } nexthandler->init(http, args); sync := chan of chan of (int, chan of (int, string, string)); spawn excgetproc(sync); excgetter = <-sync; } handle(h: ref HConn) { { nexthandler->handle(h); } exception { "*" => (pc, mod, e) := getexc(); sys->fprint(sys->fildes(2), "%s: %d %d %s: %d %s\n", arg->progname(), h.seq, sys->pctl(0, nil), mod, pc, e); h.err(500, e); } } excgetproc(sync: chan of chan of (int, chan of (int, string, string))) { exc := load Exception Exception->PATH; if(exc == nil) { sys->fprint(sys->fildes(2), "%s: load exc: %r\n", arg->progname()); raise "fail:load exc"; } reqs := chan of (int, chan of (int, string, string)); sync <-= reqs; for(;;) { (pid, resp) := <-reqs; resp <-= exc->getexc(pid); } } getexc(): (int, string, string) { pid := sys->pctl(0, nil); resp := chan of (int, string, string); excgetter <-= (pid, resp); return <-resp; }