void yodestroy(struct yo *yo) { struct o *o = (struct o *)yo; oclear(o); if (unlikely(!pool_put(o))) yfree(o); }
static void pool_clear(void) { struct o *o; while ((o = pool_get())) { oclear(o); yfree(o); } }
// wrapper around cmd_plan, fork here static int start_plan(struct myfile *req,int do_fork) { int rv; char logname[1024]; char filename[1024]; char *file,*ext; int pid; search src; oclear(src); file = strrchr(req->name,'/'); if (file) file++; else file = req->name; ext = strrchr(req->name,'.'); if (ext) fmtstring(filename,"%.*s",(ub4)(ext - file),file); else strcopy(filename,file); if (do_fork) { pid = fork(); if (pid == -1) { oserror(0,"Cannot fork from %u for %s",globs.pid,filename); return -1; } else if (pid) { info(0,"create process %u for %s",pid,filename); return pid; } globs.pid = getpid(); fmtstring(logname,"log/%s_%u.log",filename,globs.pid); setmsglog(globs.netdir,logname,1); } gnet *net = getgnet(); rv = cmd_plan(net,req,&src); if (rv) info(0,"plan returned %d",rv); if (do_fork) { eximsg(0); exit(rv); } else return rv; }
static int cmd_geo(struct myfile *req) { struct myfile rep; char *vp,*lp = req->buf; ub4 n,pos = 0,len = (ub4)req->len; ub4 ival; ub4 varstart,varend,varlen,valstart,valend,type; ub4 lat = 0,lon = 0,scale = 1; int rv; enum Vars { Cnone, Clat, Clon, Cscale } var; if (len == 0) return 1; oclear(rep); while (pos < len && lp[pos] >= 'a' && lp[pos] <= 'z') { ival = 0; varstart = varend = pos; while (varend < len && lp[varend] >= 'a' && lp[varend] <= 'z') varend++; varlen = varend - varstart; pos = varend; if (varlen == 0) break; while (pos < len && lp[pos] == ' ') pos++; if (pos == len) break; type = lp[pos++]; if (type == '\n' || pos == len) break; while (pos < len && lp[pos] == ' ') pos++; lp[varend] = 0; valstart = valend = pos; while (valend < len && lp[valend] != '\n') valend++; if (valend == len) break; pos = valend; while (pos < len && lp[pos] != '\n') pos++; if (lp[pos] == '\n') pos++; if (pos == len) break; lp[valend] = 0; if (type == 'i') { n = str2ub4(lp + valstart,&ival); if (n == 0) return error(0,"expected integer for %s, found '%.*s'",lp + varstart,valend - valstart,lp + valstart); } vp = lp + varstart; vrb0(0,"len %u %.*s",varlen,varlen,vp); if (varlen == 3 && memeq(vp,"lat",3)) var = Clat; else if (varlen == 3 && memeq(vp,"lon",3)) var = Clon; else if (varlen == 5 && memeq(vp,"scale",5)) var = Cscale; else { warn(0,"ignoring unknown var '%s'",vp); var = Cnone; } switch (var) { case Cnone: break; case Clat: lat = ival; break; case Clon: lon = ival; break; case Cscale: scale = ival; break; } } rv = geocode(lat,lon,scale,&rep); rv |= setqentry(req,&rep,".rep"); return rv; }
// parse parameters and invoke actual planning. Runs in separate process // to be elaborated: temporary simple interface static int cmd_plan(gnet *net,struct myfile *req,search *src) { struct myfile rep; char *vp,*lp = req->buf; ub4 n,pos = 0,len = (ub4)req->len; ub4 ival; ub4 varstart,varend,varlen,valstart,valend,type; ub4 portcnt = net->portcnt; ub4 sportcnt = net->sportcnt; ub4 dep = 0,arr = 0,lostop = 0,histop = 3,tdep = 0,ttdep = 0,utcofs=2200; ub4 plusday = 1,minday = 0; ub4 costperstop = 1; ub4 mintt = globs.mintt; ub4 maxtt = globs.maxtt; ub4 walklimit = globs.walklimit; ub4 sumwalklimit = globs.sumwalklimit; ub4 nethistop = hi32; ub4 delay = 0; ub4 testiter = 0; int rv; enum Vars { Cnone, Cdep, Carr, Ctdep, Cttdep, Cplusday, Cminday, Clostop, Chistop, Cmintt, Cmaxtt, Ccostperstop, Cwalklimit, Csumwalklimit, Cnethistop, Cutcofs, Cdelay, Ctestiter } var; ub4 *evpool; if (len == 0) return 1; oclear(rep); while (pos < len && lp[pos] >= 'a' && lp[pos] <= 'z') { ival = 0; varstart = varend = pos; while (varend < len && lp[varend] >= 'a' && lp[varend] <= 'z') varend++; varlen = varend - varstart; pos = varend; if (varlen == 0) break; while (pos < len && lp[pos] == ' ') pos++; if (pos == len) break; type = lp[pos++]; if (type == '\n' || pos == len) break; while (pos < len && lp[pos] == ' ') pos++; lp[varend] = 0; valstart = valend = pos; while (valend < len && lp[valend] != '\n') valend++; if (valend == len) break; pos = valend; while (pos < len && lp[pos] != '\n') pos++; if (lp[pos] == '\n') pos++; if (pos == len) break; lp[valend] = 0; if (type == 'i') { n = str2ub4(lp + valstart,&ival); if (n == 0) return error(0,"expected integer for %s, found '%.*s'",lp + varstart,valend - valstart,lp + valstart); } vp = lp + varstart; if (varlen == 3 && memeq(vp,"dep",3)) var = Cdep; else if (varlen == 3 && memeq(vp,"arr",3)) var = Carr; else if (varlen == 7 && memeq(vp,"deptmin",7)) var = Ctdep; else if (varlen == 8 && memeq(vp,"depttmin",8)) var = Cttdep; else if (varlen == 7 && memeq(vp,"plusday",7)) var = Cplusday; else if (varlen == 6 && memeq(vp,"minday",6)) var = Cminday; else if (varlen == 6 && memeq(vp,"lostop",6)) var = Clostop; else if (varlen == 6 && memeq(vp,"histop",6)) var = Chistop; else if (varlen == 5 && memeq(vp,"mintt",5)) var = Cmintt; else if (varlen == 5 && memeq(vp,"maxtt",5)) var = Cmaxtt; else if (varlen == 11 && memeq(vp,"costperstop",11)) var = Ccostperstop; else if (varlen == 9 && memeq(vp,"walklimit",9)) var = Cwalklimit; else if (varlen == 12 && memeq(vp,"sumwalklimit",12)) var = Csumwalklimit; else if (varlen == 9 && memeq(vp,"nethistop",9)) var = Cnethistop; else if (varlen == 6 && memeq(vp,"utcofs",6)) var = Cutcofs; else if (varlen == 5 && memeq(vp,"delay",5)) var = Cdelay; else if (varlen == 8 && memeq(vp,"testiter",8)) var = Ctestiter; else { warn(0,"ignoring unknown var '%s'",vp); var = Cnone; } switch (var) { case Cnone: break; case Cdep: dep = ival; break; case Carr: arr = ival; break; case Ctdep: tdep = ival; break; case Cttdep: ttdep = ival; break; case Cplusday: plusday = ival; break; case Cminday: minday = ival; break; case Clostop: lostop = ival; break; case Chistop: histop = ival; break; case Cmintt: mintt = ival; break; case Cmaxtt: maxtt = ival; break; case Ccostperstop: costperstop = ival; break; case Cwalklimit: walklimit = ival; break; case Csumwalklimit: sumwalklimit = ival; break; case Cnethistop: nethistop = ival; break; case Cutcofs: utcofs = ival; break; case Cdelay: delay = ival; break; case Ctestiter: testiter = ival; break; } } if (mintt > maxtt) { warn(0,"min transfer time %u cannot be above max %u",mintt,maxtt); maxtt = mintt + 2; } if (sumwalklimit < walklimit) { warn(0,"max distance for single go walk %u above summed max %u",walklimit,sumwalklimit); sumwalklimit = walklimit; } if (dep > portcnt && dep - portcnt >= sportcnt) return error(0,"dep %u not in %u member net",dep - portcnt,sportcnt); if (arr > portcnt && arr - portcnt >= sportcnt) return error(0,"arr %u not in %u member net",arr - portcnt,sportcnt); if (dep == arr) warning(0,"dep %u equal to arr",dep); evpool = src->evpool; clear(src); src->evpool = evpool; src->depttmin_cd = ttdep; src->deptmin_cd = tdep; src->utcofs12 = utcofs; src->plusday = plusday; src->minday = minday; src->nethistop = min(nethistop,histop); src->mintt = mintt; src->maxtt = maxtt; src->costperstop = costperstop; src->walklimit = m2geo(walklimit); src->sumwalklimit = m2geo(sumwalklimit); // invoke actual plan here info(0,"plan %u to %u in %u to %u stop\as from %u.%u for +%u -%u days",dep,arr,lostop,histop,tdep,ttdep,plusday,minday); info(0,"mintt %u maxtt %u maxwalk %u costperstop %u",mintt,maxtt,walklimit,costperstop); info(0,"utcofs %u",utcofs); rv = plantrip(src,req->name,dep,arr,lostop,histop); // prepare reply rep.buf = rep.localbuf; if (rv) len = fmtstring(rep.localbuf,"reply plan %u-%u error code %d\n",dep,arr,rv); else if (src->reslen) { len = min(src->reslen,sizeof(rep.localbuf)); memcpy(rep.localbuf,src->resbuf,len); } else len = fmtstring(rep.localbuf,"reply plan %u-%u : no trip found\n",dep,arr); vrb0(0,"reply len %u",len); rep.len = len; if (delay) osmillisleep(delay); rv |= setqentry(req,&rep,".rep"); if (testiter == 0 || dep == arr) return rv; ub4 iter = 0; while (iter < testiter) { if (++arr == portcnt) { arr = 0; if (++dep == portcnt) dep = 0; } if (dep == arr) continue; iter++; rv = plantrip(src,req->name,dep,arr,lostop,histop); if (rv) return rv; } ub4 iv,cnt,cumcnt = 0; cnt = src->notrips; infocc(cnt,0,"%u of %u trips not found",cnt,testiter); info(0,"max dur %lu msec for dep %u arr %u",src->querymaxdur / 1000,src->querymaxdep,src->querymaxarr); info(0,"query times in msec for %u iters",testiter); for (iv = 0; iv < Elemcnt(src->querydurs); iv++) { cnt = src->querydurs[iv]; cumcnt += cnt; infocc(cnt,0,"%02u: %u %u",iv,cnt,cumcnt); } return 0; }