static void session2_on_timeout(uv_timer_t *timer)
{
- defer_sample_start(NULL);
struct session2 *s = timer->data;
session2_event(s, s->timer_event, NULL);
- defer_sample_stop(NULL, false);
}
int session2_timer_start(struct session2 *s, enum protolayer_event_type event, uint64_t timeout, uint64_t repeat)
void session2_event(struct session2 *s, enum protolayer_event_type event, void *baton)
{
+ /* Events may be sent from inside or outside of already measured code.
+ * From inside: close by us, statistics, ...
+ * From outside: timeout, EOF, close by external reasons, ... */
+ bool defer_accounting_here = false;
+ if (!defer_sample_is_accounting() && s->stream && !s->outgoing) {
+ defer_sample_start(NULL);
+ defer_accounting_here = true;
+ }
+
session2_event_unwrap(s, 0, event, baton);
+
+ if (defer_accounting_here)
+ defer_sample_stop(NULL, false);
}
void session2_event_after(struct session2 *s, enum protolayer_type protocol,
static int send_waiting(struct session2 *session)
{
+ if (session2_waitinglist_is_empty(session))
+ return 0;
+
+ defer_sample_state_t defer_prev_sample_state;
+ defer_sample_start(&defer_prev_sample_state);
int ret = 0;
- while (!session2_waitinglist_is_empty(session)) {
+ do {
struct qr_task *t = session2_waitinglist_get(session);
+ if (t->ctx->source.session)
+ defer_sample_addr(&t->ctx->source.addr, t->ctx->source.session->stream);
ret = qr_task_send(t, session, NULL, NULL);
+ defer_sample_restart();
if (ret != 0) {
struct sockaddr *peer = session2_get_peer(session);
session2_waitinglist_finalize(session, KR_STATE_FAIL);
break;
}
session2_waitinglist_pop(session, true);
- }
+ } while (!session2_waitinglist_is_empty(session));
+ defer_sample_stop(&defer_prev_sample_state, true);
+
return ret;
}
} else {
/* Normally it should not happen,
* but better to check if there anything in this list. */
- while (!session2_waitinglist_is_empty(s)) {
- struct qr_task *t = session2_waitinglist_pop(s, false);
- worker_task_finalize(t, KR_STATE_FAIL);
- worker_task_unref(t);
- the_worker->stats.timeout += 1;
- if (s->closing)
- return PROTOLAYER_EVENT_PROPAGATE;
+ if (!session2_waitinglist_is_empty(s)) {
+ defer_sample_state_t defer_prev_sample_state;
+ defer_sample_start(&defer_prev_sample_state);
+ do {
+ struct qr_task *t = session2_waitinglist_pop(s, false);
+ worker_task_finalize(t, KR_STATE_FAIL);
+ worker_task_unref(t);
+ the_worker->stats.timeout += 1;
+ if (s->closing)
+ return PROTOLAYER_EVENT_PROPAGATE;
+ defer_sample_restart();
+ } while (!session2_waitinglist_is_empty(s));
+ defer_sample_stop(&defer_prev_sample_state, true);
}
uint64_t idle_in_timeout = the_network->tcp.in_idle_timeout;
uint64_t idle_time = kr_now() - s->last_activity;
stream->connected = false;
+ if (session2_is_empty(session))
+ return PROTOLAYER_EVENT_PROPAGATE;
+
+ defer_sample_state_t defer_prev_sample_state;
+ if (session->outgoing)
+ defer_sample_start(&defer_prev_sample_state);
+
while (!session2_waitinglist_is_empty(session)) {
struct qr_task *task = session2_waitinglist_pop(session, false);
kr_assert(task->refs > 1);
qry->flags.TCP = false;
}
qr_task_step(task, NULL, NULL);
+ defer_sample_restart();
} else {
kr_assert(task->ctx->source.session == session);
task->ctx->source.session = NULL;
qry->flags.TCP = false;
}
qr_task_step(task, NULL, NULL);
+ defer_sample_restart();
} else {
kr_assert(task->ctx->source.session == session);
task->ctx->source.session = NULL;
worker_task_unref(task);
}
+ if (session->outgoing)
+ defer_sample_stop(&defer_prev_sample_state, true);
+
return PROTOLAYER_EVENT_PROPAGATE;
}