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);
}
Exemplo n.º 2
0
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;
    }
}