static ALWAYS_INLINE void spawn_coro(lwan_connection_t *conn, coro_switcher_t *switcher, struct death_queue_t *dq) { assert(!conn->coro); assert(!(conn->flags & CONN_IS_ALIVE)); assert(!(conn->flags & CONN_SHOULD_RESUME_CORO)); conn->coro = coro_new(switcher, process_request_coro, conn); death_queue_insert(dq, conn); conn->flags |= (CONN_IS_ALIVE | CONN_SHOULD_RESUME_CORO); conn->flags &= ~CONN_WRITE_EVENTS; }
static void death_queue_move_to_last(struct death_queue_t *dq, lwan_connection_t *conn) { /* * If the connection isn't keep alive, it might have a coroutine that * should be resumed. If that's the case, schedule for this request to * die according to the keep alive timeout. * * If it's not a keep alive connection, or the coroutine shouldn't be * resumed -- then just mark it to be reaped right away. */ conn->time_to_die = dq->time + dq->keep_alive_timeout * (unsigned)!!(conn->flags & (CONN_KEEP_ALIVE | CONN_SHOULD_RESUME_CORO)); death_queue_remove(dq, conn); death_queue_insert(dq, conn); }
static ALWAYS_INLINE void spawn_or_reset_coro_if_needed(lwan_connection_t *conn, coro_switcher_t *switcher, struct death_queue_t *dq) { if (conn->coro) { if (conn->flags & CONN_SHOULD_RESUME_CORO) return; coro_reset(conn->coro, process_request_coro, conn); } else { conn->coro = coro_new(switcher, process_request_coro, conn); death_queue_insert(dq, conn); conn->flags |= CONN_IS_ALIVE; } conn->flags |= CONN_SHOULD_RESUME_CORO; conn->flags &= ~CONN_WRITE_EVENTS; }