void complete(int how, struct request *req) { struct timeval now, diff; int i, total; long milliseconds; struct event *timeoutev; evtimer_del(&req->timeoutev); switch(how){ case Success: gettimeofday(&now, nil); timersub(&now, &req->starttv, &diff); milliseconds = diff.tv_sec * 1000 + diff.tv_usec / 1000; for(i=0; params.buckets[i]<milliseconds && params.buckets[i]!=0; i++); counts.counters[i]++; counts.successes++; break; case Error: counts.errors++; break; case Timeout: counts.timeouts++; break; } total = counts.successes + counts.errors + counts.timeouts /*+ counts.closes*/; /* enqueue the next one */ if(params.count<0 || total<params.count){ if(params.rpc<0 || params.rpc>req->evcon_reqno){ dispatch(req->evcon, req->evcon_reqno+1); }else{ /* There seems to be a bug in libevent where the connection isn't really * freed until the event loop is unwound. We'll add ourselves back with a * 0-second timeout. */ evhttp_connection_free(req->evcon); timeoutev = mal(sizeof(*timeoutev)); evtimer_set(timeoutev, dispatchcb, (void *)timeoutev); evtimer_add(timeoutev, &zerotv); } }else{ /* We'll count this as a close. I guess that's ok. */ evhttp_connection_free(req->evcon); if(--params.concurrency == 0){ evtimer_del(&reportev); reportcb(0, 0, nil); /* issue a last report */ } } free(req); }
void complete(int how, struct request *req) { struct timeval now, diff; int i, total; long milliseconds; evtimer_del(&req->timeoutev); switch(how){ case Success: gettimeofday(&now, nil); timersub(&now, &req->starttv, &diff); milliseconds = diff.tv_sec * 1000 + diff.tv_usec / 1000; for(i=0; params.buckets[i]<milliseconds && params.buckets[i]!=0; i++); counts.counters[i]++; counts.successes++; break; case Error: counts.errors++; break; case Timeout: counts.timeouts++; break; } total = counts.successes + counts.errors + counts.timeouts /*+ counts.closes*/; /* enqueue the next one */ if(params.count<0 || total<params.count){ if(params.rpc<0 || params.rpc>req->evcon_reqno){ dispatch(req->evcon, req->evcon_reqno + 1); }else{ evhttp_connection_free(req->evcon); dispatch(mkhttp(), 1); } }else{ /* We'll count this as a close. I guess that's ok. */ evhttp_connection_free(req->evcon); if(--params.concurrency == 0){ evtimer_del(&reportev); reportcb(0, 0, nil); /* issue a last report */ } } free(req); }
void complete(int how, runner *run) { struct request *req = run->req; save_request(how, run); evtimer_del(&req->timeoutev); debug("complete(): evtimer_del(&req->timeoutev);\n"); /* enqueue the next one */ if(params.count<0 || counts.conns<params.count){ // re-scheduling is handled by the callback if(!qps_enabled()){ if(!rpc_enabled() || req->evcon_reqno<params.rpc){ dispatch(run, req->evcon_reqno + 1); }else{ // re-establish the connection evhttp_connection_free(run->evcon); mkhttp(run); dispatch(run, 1); } } }else{ /* We'll count this as a close. I guess that's ok. */ evhttp_connection_free(req->evcon); if(--params.concurrency == 0){ evtimer_del(&reportev); debug("last call to reportcb\n"); reportcb(0, 0, nil); /* issue a last report */ } } if(!qps_enabled()) // FIXME possible memory leak free(req); }