static void ngx_http_drizzle_keepalive_close_handler(ngx_event_t *ev) { ngx_http_upstream_drizzle_srv_conf_t *dscf; ngx_http_drizzle_keepalive_cache_t *item; int n; char buf[1]; ngx_connection_t *c; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "drizzle: keepalive close handler"); c = ev->data; if (c->close) { goto close; } n = recv(c->fd, buf, 1, MSG_PEEK); if (n == -1 && ngx_socket_errno == NGX_EAGAIN) { /* stale event */ #if 0 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { goto close; } #endif return; } close: item = c->data; dscf = item->srv_conf; dd("closing fd %d", c->fd); ngx_http_upstream_drizzle_free_connection(ev->log, c, item->drizzle_con, dscf); ngx_queue_remove(&item->queue); ngx_queue_insert_head(&dscf->free, &item->queue); }
static void ngx_http_drizzle_keepalive_close_handler(ngx_event_t *ev) { ngx_http_upstream_drizzle_srv_conf_t *dscf; ngx_http_drizzle_keepalive_cache_t *item; ngx_connection_t *c; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "drizzle: keepalive close handler"); c = ev->data; item = c->data; dscf = item->srv_conf; ngx_queue_remove(&item->queue); ngx_http_upstream_drizzle_free_connection(ev->log, item->connection, item->drizzle_con, dscf); ngx_queue_insert_head(&dscf->free, &item->queue); }
void ngx_http_drizzle_keepalive_free_peer(ngx_peer_connection_t *pc, ngx_http_upstream_drizzle_peer_data_t *dp, ngx_http_upstream_drizzle_srv_conf_t *dscf, ngx_uint_t state) { ngx_uint_t status; ngx_http_drizzle_keepalive_cache_t *item; ngx_queue_t *q; ngx_connection_t *c; ngx_http_upstream_t *u; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "drizzle: free keepalive peer"); if (state & NGX_PEER_FAILED) { dp->failed = 1; } u = dp->upstream; status = u->headers_in.status_n; dd("dp failed: %d", (int) dp->failed); dd("pc->connection: %p", pc->connection); dd("status = %d", (int) status); if (!dp->failed && pc->connection != NULL && (status == NGX_HTTP_NOT_FOUND || status == NGX_HTTP_GONE || (status == NGX_HTTP_OK && u->header_sent && u->length == 0))) { c = pc->connection; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "drizzle: free keepalive peer: saving connection %p", c); if (ngx_queue_empty(&dscf->free)) { /* connection pool is already full */ dd("caching connection forcibly and the pool is already full"); q = ngx_queue_last(&dscf->cache); ngx_queue_remove(q); item = ngx_queue_data(q, ngx_http_drizzle_keepalive_cache_t, queue); ngx_http_upstream_drizzle_free_connection(pc->log, item->connection, item->drizzle_con, dscf); } else { dd("caching idle connection to the pool"); q = ngx_queue_head(&dscf->free); ngx_queue_remove(q); item = ngx_queue_data(q, ngx_http_drizzle_keepalive_cache_t, queue); } item->connection = c; ngx_queue_insert_head(&dscf->cache, q); pc->connection = NULL; if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } c->write->handler = ngx_http_drizzle_keepalive_dummy_handler; c->read->handler = ngx_http_drizzle_keepalive_close_handler; c->data = item; c->idle = 1; c->log = ngx_cycle->log; c->read->log = ngx_cycle->log; c->write->log = ngx_cycle->log; item->socklen = pc->socklen; ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen); item->drizzle_con = dp->drizzle_con; item->has_set_names = dp->has_set_names; item->name.data = dp->name.data; item->name.len = dp->name.len; item->used = ++dp->used; } }