void ngx_postgres_upstream_free_connection(ngx_log_t *log, ngx_connection_t *c, PGconn *pgconn, ngx_postgres_upstream_srv_conf_t *pgscf) { ngx_event_t *rev, *wev; dd("entering"); PQfinish(pgconn); if (c) { rev = c->read; wev = c->write; if (rev->timer_set) { ngx_del_timer(rev); } if (wev->timer_set) { ngx_del_timer(wev); } if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (rev->active || rev->disabled) { ngx_del_event(rev, NGX_READ_EVENT, NGX_CLOSE_EVENT); } if (wev->active || wev->disabled) { ngx_del_event(wev, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } if (rev->prev) { ngx_delete_posted_event(rev); } if (wev->prev) { ngx_delete_posted_event(wev); } rev->closed = 1; wev->closed = 1; #if defined(nginx_version) && (nginx_version >= 1001004) if (c->pool) { ngx_destroy_pool(c->pool); } #endif ngx_free_connection(c); } /* free spot in keepalive connection pool */ pgscf->active_conns--; dd("returning"); }
void ngx_zeromq_close(ngx_connection_t *c) { void *zmq; if (c->fd == -1) { return; } zmq = c->data; ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "zmq_close: zmq:%p fd:%d #%d", zmq, c->fd, c->number); if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } if (c->read->prev) { ngx_delete_posted_event(c->read); } if (c->write->prev) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; ngx_reusable_connection(c, 0); ngx_free_connection(c); c->fd = (ngx_socket_t) -1; if (zmq_close(zmq) == -1) { ngx_zeromq_log_error(ngx_cycle->log, "zmq_close()"); } }
// 遍历队列,取出队列里的事件,调用对应的handler // cycle参数只用于记录日志 void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted) { ngx_queue_t *q; ngx_event_t *ev; while (!ngx_queue_empty(posted)) { // 取队列头节点 q = ngx_queue_head(posted); // 获取头节点元素,即事件 ev = ngx_queue_data(q, ngx_event_t, queue); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p", ev); // in ngx_event_posted.h // 函数宏,从队列里移除 ngx_delete_posted_event(ev); // 执行事件的回调函数 ev->handler(ev); } }
static ngx_int_t ngx_rtmp_play_stop(ngx_rtmp_session_t *s) { ngx_rtmp_play_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module); if (ctx == NULL) { return NGX_ERROR; } ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "play: stop"); if (ctx->send_evt.timer_set) { ngx_del_timer(&ctx->send_evt); } if (ctx->send_evt.prev) { ngx_delete_posted_event((&ctx->send_evt)); } if (ctx->fmt && ctx->fmt->stop && ctx->fmt->stop(s, &ctx->file) != NGX_OK) { return NGX_ERROR; } return NGX_OK; }
static void destroy_dummy_conn(ngx_connection_t *c) { if (c == NULL) return ; if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (ngx_del_conn) { ngx_del_conn(c, 0); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, 0); } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, 0); } } if (c->read->prev) { ngx_delete_posted_event(c->read); } if (c->write->prev) { ngx_delete_posted_event(c->write); } close(c->fd); c->fd = -1; c->read->closed = 1; c->write->closed = 1; free(c->read); free(c->write); free(c); }
void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_thread_volatile ngx_event_t **posted) {//延后的处理读写,新连接事件、根据handler进行区分 ngx_event_t *ev; for ( ;; ) { ev = (ngx_event_t *) *posted; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p", ev); if (ev == NULL) { return; } //从链表里面切断, ngx_delete_posted_event(ev); //调用回调函数,监听SOCK为ngx_event_accept,其他的网络SOCK事件回调变化比较大 ev->handler(ev); } }
void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_thread_volatile ngx_event_t **posted) { ngx_event_t *ev; for ( ;; ) { ev = (ngx_event_t *) *posted; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p", ev); if (ev == NULL) { return; } ngx_delete_posted_event(ev); ev->handler(ev); } }
void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted) { ngx_queue_t *q; ngx_event_t *ev; while (!ngx_queue_empty(posted)) { q = ngx_queue_head(posted); ev = ngx_queue_data(q, ngx_event_t, queue); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p", ev); ngx_delete_posted_event(ev); ev->handler(ev); } }
void ngx_event_process_posted(ngx_cycle_t *cycle) { ngx_event_t *ev; for ( ;; ) { ev = (ngx_event_t *) ngx_posted_events; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event " PTR_FMT, ev); if (ev == NULL) { return; } ngx_delete_posted_event(ev); ev->event_handler(ev); } }
static void ngx_live_relay_httpflv_cleanup(void *data) { ngx_rtmp_session_t *s; s = data; ngx_log_error(NGX_LOG_INFO, s->log, 0, "http flv client, cleanup"); if (s) { if (s->close.posted) { ngx_delete_posted_event(&s->close); } if (s->finalize_reason == 0) { s->finalize_reason = NGX_LIVE_FLV_RECV_ERR; } ngx_rtmp_finalize_fake_session(s); } }
/* 处理post队列中的事件 */ void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted) { ngx_queue_t *q; ngx_event_t *ev; /* 判断队列是否为NULL */ while (!ngx_queue_empty(posted)) { q = ngx_queue_head(posted); /* 取出队列中事件 */ ev = ngx_queue_data(q, ngx_event_t, queue); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p", ev); /* 将事件从队列中删除 */ ngx_delete_posted_event(ev); /* 处理事件 */ ev->handler(ev); } }
void ngx_close_connection(ngx_connection_t *c) { ngx_err_t err; ngx_uint_t log_error, level; ngx_socket_t fd; if (c->fd == (ngx_socket_t) -1) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); return; } //首先将连接的读写事件从定时器中取出 if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (ngx_del_conn) { //将读写事件从epoll中移除 ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } if (c->read->posted) { ngx_delete_posted_event(c->read); } if (c->write->posted) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; ngx_reusable_connection(c, 0); log_error = c->log_error; //调用ngx_free_connection方法把表示连接的ngx_connection_t结构体归还给ngx_cycle_t核心结构体的空闲连接池 ngx_free_connection(c); fd = c->fd; c->fd = (ngx_socket_t) -1; if (ngx_close_socket(fd) == -1) { //系统调用close err = ngx_socket_errno; if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) { switch (log_error) { case NGX_ERROR_INFO: level = NGX_LOG_INFO; break; case NGX_ERROR_ERR: level = NGX_LOG_ERR; break; default: level = NGX_LOG_CRIT; } } else { level = NGX_LOG_CRIT; } /* we use ngx_cycle->log because c->log was in c->pool */ ngx_log_error(level, ngx_cycle->log, err, ngx_close_socket_n " %d failed", fd); } }
ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle) { ngx_event_t *ev; for ( ;; ) { ev = (ngx_event_t *) ngx_posted_events; for ( ;; ) { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p", ev); if (ev == NULL) { return NGX_OK; } if (ngx_trylock(ev->lock) == 0) { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p is busy", ev); ev = ev->next; continue; } if (ev->lock != ev->own_lock) { if (*(ev->own_lock)) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "the own lock of the posted event %p is busy", ev); ngx_unlock(ev->lock); ev = ev->next; continue; } *(ev->own_lock) = 1; } ngx_delete_posted_event(ev); ev->locked = 1; ev->ready |= ev->posted_ready; ev->timedout |= ev->posted_timedout; ev->pending_eof |= ev->posted_eof; #if (NGX_HAVE_KQUEUE) ev->kq_errno |= ev->posted_errno; #endif if (ev->posted_available) { ev->available = ev->posted_available; } ev->posted_ready = 0; ev->posted_timedout = 0; ev->posted_eof = 0; #if (NGX_HAVE_KQUEUE) ev->posted_errno = 0; #endif ev->posted_available = 0; ngx_mutex_unlock(ngx_posted_events_mutex); ev->handler(ev); ngx_mutex_lock(ngx_posted_events_mutex); if (ev->locked) { ngx_unlock(ev->lock); if (ev->lock != ev->own_lock) { ngx_unlock(ev->own_lock); } } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "posted event %p is done", ev); break; } } }
void ngx_close_connection(ngx_connection_t *c) { ngx_socket_t fd; if (c->pool == NULL) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); return; } #if (NGX_OPENSSL) if (c->ssl) { if (ngx_ssl_shutdown(c) == NGX_AGAIN) { c->read->event_handler = ngx_ssl_close_handler; c->write->event_handler = ngx_ssl_close_handler; return; } } #endif if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } #if (NGX_THREADS) /* * we have to clean the connection information before the closing * because another thread may reopen the same file descriptor * before we clean the connection */ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_OK) { if (c->read->prev) { ngx_delete_posted_event(c->read); } if (c->write->prev) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; if (c->single_connection) { ngx_unlock(&c->lock); c->read->locked = 0; c->write->locked = 0; } ngx_mutex_unlock(ngx_posted_events_mutex); } #else if (c->read->prev) { ngx_delete_posted_event(c->read); } if (c->write->prev) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; #endif fd = c->fd; c->fd = (ngx_socket_t) -1; c->data = NULL; ngx_destroy_pool(c->pool); if (ngx_close_socket(fd) == -1) { /* we use ngx_cycle->log because c->log was in c->pool */ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, ngx_close_socket_n " failed"); } }
void ngx_zeromq_close(ngx_zeromq_connection_t *zc) { ngx_connection_t *c; c = &zc->connection; if (c->fd == -1) { return; } ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, "zmq_close: fd:%d #%d zc:%p zmq:%p", c->fd, c->number, zc, zc->socket); if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } #if (nginx_version >= 1007005) if (c->read->posted) { #else if (c->read->prev) { #endif ngx_delete_posted_event(c->read); } #if (nginx_version >= 1007005) if (c->write->posted) { #else if (c->write->prev) { #endif ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; ngx_reusable_connection(zc->connection_ptr, 0); ngx_free_connection(zc->connection_ptr); c->fd = (ngx_socket_t) -1; zc->connection_ptr->fd = (ngx_socket_t) -1; if (zmq_close(zc->socket) == -1) { ngx_zeromq_log_error(ngx_cycle->log, "zmq_close()"); } zc->socket = NULL; } static void ngx_zeromq_event_handler(ngx_event_t *ev) { ngx_zeromq_connection_t *zc; ngx_connection_t *c; void *zmq; int events; size_t esize; /* * ZeroMQ notifies us about new events in edge-triggered fashion * by changing state of the notification socket to read-ready. * * Write-readiness doesn't indicate anything and can be ignored. */ if (ev->write) { return; } zc = ev->data; zc = zc->send; esize = sizeof(int); #if (NGX_DEBUG) if (zc->recv != zc->send) { zmq = zc->request_sent ? zc->socket : zc->recv->socket; if (zmq_getsockopt(zmq, ZMQ_EVENTS, &events, &esize) == -1) { ngx_zeromq_log_error(ev->log, "zmq_getsockopt(ZMQ_EVENTS)"); ev->error = 1; return; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "zmq_event: %s:%d (ignored)", zc->request_sent ? "send" : "recv", events); } #endif zmq = zc->request_sent ? zc->recv->socket : zc->socket; if (zmq_getsockopt(zmq, ZMQ_EVENTS, &events, &esize) == -1) { ngx_zeromq_log_error(ev->log, "zmq_getsockopt(ZMQ_EVENTS)"); ev->error = 1; return; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "zmq_event: %s:%d", zc->request_sent ? "recv" : "send", events); c = &zc->connection; if (zc->request_sent) { c->read->ready = events & ZMQ_POLLIN ? 1 : 0; if (c->read->ready) { zc->handler(c->read); } } else { c->write->ready = events & ZMQ_POLLOUT ? 1 : 0; if (c->write->ready) { zc->handler(c->write); } } } static ssize_t ngx_zeromq_sendmsg(void *zmq, ngx_event_t *ev, zmq_msg_t *msg, int flags) { size_t size; size = zmq_msg_size(msg); for (;;) { if (zmq_msg_send(msg, zmq, ZMQ_DONTWAIT|flags) == -1) { if (ngx_errno == NGX_EAGAIN) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "zmq_send: not ready"); ev->ready = 0; return NGX_AGAIN; } if (ngx_errno == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "zmq_send: interrupted"); ev->ready = 0; continue; } ngx_zeromq_log_error(ev->log, "zmq_msg_send()"); ev->error = 1; return NGX_ERROR; } break; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "zmq_send: %uz eom:%d", size, flags != ZMQ_SNDMORE); return size; }
void ngx_close_connection(ngx_connection_t *c) { ngx_err_t err; ngx_uint_t log_error, level; ngx_socket_t fd; if (c->fd == (ngx_socket_t) -1) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); return; } if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (!c->shared) { if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } } if (c->read->posted) { ngx_delete_posted_event(c->read); } if (c->write->posted) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; ngx_reusable_connection(c, 0); log_error = c->log_error; ngx_free_connection(c); fd = c->fd; c->fd = (ngx_socket_t) -1; if (c->shared) { return; } if (ngx_close_socket(fd) == -1) { err = ngx_socket_errno; if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) { switch (log_error) { case NGX_ERROR_INFO: level = NGX_LOG_INFO; break; case NGX_ERROR_ERR: level = NGX_LOG_ERR; break; default: level = NGX_LOG_CRIT; } } else { level = NGX_LOG_CRIT; } ngx_log_error(level, c->log, err, ngx_close_socket_n " %d failed", fd); } }
void ngx_close_connection(ngx_connection_t *c) { ngx_err_t err; ngx_uint_t log_error, level; ngx_socket_t fd; if (c->fd == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); return; } if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (ngx_del_conn) { ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } #if (NGX_THREADS) /* * we have to clean the connection information before the closing * because another thread may reopen the same file descriptor * before we clean the connection */ ngx_mutex_lock(ngx_posted_events_mutex); if (c->read->prev) { ngx_delete_posted_event(c->read); } if (c->write->prev) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; if (c->single_connection) { ngx_unlock(&c->lock); c->read->locked = 0; c->write->locked = 0; } ngx_mutex_unlock(ngx_posted_events_mutex); #else if (c->read->prev) { ngx_delete_posted_event(c->read); } if (c->write->prev) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; #endif ngx_reusable_connection(c, 0); log_error = c->log_error; ngx_free_connection(c); fd = c->fd; c->fd = (ngx_socket_t) -1; if (ngx_close_socket(fd) == -1) { err = ngx_socket_errno; if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) { switch (log_error) { case NGX_ERROR_INFO: level = NGX_LOG_INFO; break; case NGX_ERROR_ERR: level = NGX_LOG_ERR; break; default: level = NGX_LOG_CRIT; } } else { level = NGX_LOG_CRIT; } /* we use ngx_cycle->log because c->log was in c->pool */ ngx_log_error(level, ngx_cycle->log, err, ngx_close_socket_n " %d failed", fd); } }
/* ngx_http_close_request方法是更高层的用于关闭请求的方法,当然,HTTP模块一般也不会直接调用它的。在上面几节中反复提到的引用计数, 就是由ngx_http_close_request方法负责检测的,同时它会在引用计数清零时正式调用ngx_http_free_request方法和ngx_http_close_connection(ngx_close_connection) 方法来释放请求、关闭连接,见ngx_http_close_request */ void ngx_close_connection(ngx_connection_t *c) { ngx_err_t err; ngx_uint_t log_error, level; ngx_socket_t fd; if (c->fd == (ngx_socket_t) -1) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); return; } /* 首先将连接的读/写事件从定时器中取出。实际上就是检查读/写事件的time_set标志位,如果为1,则证明事件在定时器中,那么需要调 用ngx_del_timer方法把事件从定时器中移除。 */ if (c->read->timer_set) { ngx_del_timer(c->read, NGX_FUNC_LINE); } if (c->write->timer_set) { ngx_del_timer(c->write, NGX_FUNC_LINE); } /* 调用ngx_del_conn宏(或者ngx_del_event宏)将读/写事件从epoll中移除。实际上就是调用ngx_event_actions_t接口 中的del_conn方法,当事件模块是epoll模块时,就是从epoll中移除这个连接的读/写事件。同时,如果这个事件在ngx_posted_accept_events或 者ngx_posted_events队列中,还需要调用ngx_delete_posted_event宏把事件从post事件队列中移除。 */ if (ngx_del_conn) { //ngx_epoll_del_connection ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) { ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); //ngx_epoll_del_event } if (c->write->active || c->write->disabled) { ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); } } if (c->read->posted) { ngx_delete_posted_event(c->read); } if (c->write->posted) { ngx_delete_posted_event(c->write); } c->read->closed = 1; c->write->closed = 1; ngx_reusable_connection(c, 0); log_error = c->log_error; /* 调用ngx_free_connection方法把表示连接的ngx_connection-t结构体归还给ngx_ cycle_t核心结构体的空闲连接池free connections。 */ ngx_free_connection(c); fd = c->fd; c->fd = (ngx_socket_t) -1; ngx_log_debugall(ngx_cycle->log, 0, "close socket:%d", fd); //调用系统提供的close方法关闭这个TCP连接套接字。 if (ngx_close_socket(fd) == -1) { err = ngx_socket_errno; if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) { switch (log_error) { case NGX_ERROR_INFO: level = NGX_LOG_INFO; break; case NGX_ERROR_ERR: level = NGX_LOG_ERR; break; default: level = NGX_LOG_CRIT; } } else { level = NGX_LOG_CRIT; } /* we use ngx_cycle->log because c->log was in c->pool */ //由于c已经在前面释放了,因此不能再用C->log了 ngx_log_error(level, ngx_cycle->log, err, ngx_close_socket_n " %d failed", fd); } }