Mercurial > hg > nginx
view src/os/unix/ngx_recv.c @ 5885:5a042519bfe7
Upstream: limited next_upstream time and tries when resolving DNS.
When got multiple upstream IP addresses using DNS resolving, the number of
upstreams tries and the maxinum time spent for these tries were not affected.
This patch fixed it.
author | Gu Feng <flygoast@126.com> |
---|---|
date | Mon, 27 Oct 2014 19:52:03 +0800 |
parents | ee78c7705a8e |
children | f01ab2dbcfdc |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> #if (NGX_HAVE_KQUEUE) ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { ssize_t n; ngx_err_t err; ngx_event_t *rev; rev = c->read; if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: eof:%d, avail:%d, err:%d", rev->pending_eof, rev->available, rev->kq_errno); if (rev->available == 0) { if (rev->pending_eof) { rev->ready = 0; rev->eof = 1; if (rev->kq_errno) { rev->error = 1; ngx_set_socket_errno(rev->kq_errno); return ngx_connection_error(c, rev->kq_errno, "kevent() reported about an closed connection"); } return 0; } else { rev->ready = 0; return NGX_AGAIN; } } } do { n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: fd:%d %d of %d", c->fd, n, size); if (n >= 0) { if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { rev->available -= n; /* * rev->available may be negative here because some additional * bytes may be received between kevent() and recv() */ if (rev->available <= 0) { if (!rev->pending_eof) { rev->ready = 0; } if (rev->available < 0) { rev->available = 0; } } if (n == 0) { /* * on FreeBSD recv() may return 0 on closed socket * even if kqueue reported about available data */ rev->ready = 0; rev->eof = 1; rev->available = 0; } return n; } if ((size_t) n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) { rev->ready = 0; } if (n == 0) { rev->eof = 1; } return n; } err = ngx_socket_errno; if (err == NGX_EAGAIN || err == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "recv() not ready"); n = NGX_AGAIN; } else { n = ngx_connection_error(c, err, "recv() failed"); break; } } while (err == NGX_EINTR); rev->ready = 0; if (n == NGX_ERROR) { rev->error = 1; } return n; } #else /* ! NGX_HAVE_KQUEUE */ ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) { ssize_t n; ngx_err_t err; ngx_event_t *rev; rev = c->read; do { n = recv(c->fd, buf, size, 0); ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: fd:%d %d of %d", c->fd, n, size); if (n == 0) { rev->ready = 0; rev->eof = 1; return n; } else if (n > 0) { if ((size_t) n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) { rev->ready = 0; } return n; } err = ngx_socket_errno; if (err == NGX_EAGAIN || err == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "recv() not ready"); n = NGX_AGAIN; } else { n = ngx_connection_error(c, err, "recv() failed"); break; } } while (err == NGX_EINTR); rev->ready = 0; if (n == NGX_ERROR) { rev->error = 1; } return n; } #endif /* NGX_HAVE_KQUEUE */