/*ARGSUSED*/ static int addtostats(const prod_info *infop, const void *datap, void *xprod, size_t size, void *notused) { struct timeval tv; pq_ctimestamp(pq, &tv); if(tvIsNone(tv)) tv = TS_ZERO; if(ulogIsVerbose()) uinfo("%s", s_prod_info(NULL, 0, infop, ulogIsDebug())); binstats(infop, &tv); return 0; }
static int expire(pqueue *epq, const unsigned interval, const double age) { int status = ENOERR; static timestampt now; static prod_class eclss; static prod_spec spec; timestampt ts; timestampt cursor; double diff = 0.; double max_latency = 0.; size_t nr; if(eclss.psa.psa_val == 0) { /* first time */ eclss.from = TS_ZERO; eclss.psa.psa_len = 1; eclss.psa.psa_val = &spec; spec.feedtype = ANY; spec.pattern = ".*"; regcomp(&spec.rgx, spec.pattern, REG_EXTENDED|REG_NOSUB); } (void) set_timestamp(&now); if(d_diff_timestamp(&now, &eclss.to) < interval + age) { /* only run this routine every interval seconds */ udebug("not yet"); return ENOERR; } /* else */ eclss.to = now; eclss.to.tv_sec -= age; if(ulogIsDebug()) { char cp[64]; sprint_timestampt(cp, sizeof(cp), &eclss.to); udebug("to %s", cp); } pq_cset(epq, &TS_ZERO); while(exitIfDone(0) && !stats_req) { nr = 0; status = pq_seqdel(epq, TV_GT, &eclss, 0, &nr, &ts); switch(status) { case ENOERR: pq_ctimestamp(epq, &cursor); diff = d_diff_timestamp(&cursor, &ts); if(diff > max_latency) { max_latency = diff; udebug("max_latency %.3f", max_latency); } if(nr == 0) { diff = d_diff_timestamp(&cursor, &eclss.to); udebug("diff %.3f", diff); if(diff > interval + max_latency) { udebug("heuristic depth break"); break; } } continue; /* N.B., other cases break and return */ case PQUEUE_END: udebug("expire: End of Queue"); break; case EAGAIN: case EACCES: udebug("Hit a lock"); break; #if defined(EDEADLOCK) && EDEADLOCK != EDEADLK case EDEADLOCK: #endif case EDEADLK: uerror("%s", strerror(status)); break; default: uerror("pq_seqdel failed: %s (errno = %d)", strerror(status), status); break; } break; } return status; }