Annotation of embedaddon/nginx/src/os/unix/ngx_recv.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: #include <ngx_config.h>
                      9: #include <ngx_core.h>
                     10: #include <ngx_event.h>
                     11: 
                     12: 
                     13: #if (NGX_HAVE_KQUEUE)
                     14: 
                     15: ssize_t
                     16: ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
                     17: {
                     18:     ssize_t       n;
                     19:     ngx_err_t     err;
                     20:     ngx_event_t  *rev;
                     21: 
                     22:     rev = c->read;
                     23: 
                     24:     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
                     25:         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
                     26:                        "recv: eof:%d, avail:%d, err:%d",
                     27:                        rev->pending_eof, rev->available, rev->kq_errno);
                     28: 
                     29:         if (rev->available == 0) {
                     30:             if (rev->pending_eof) {
                     31:                 rev->ready = 0;
                     32:                 rev->eof = 1;
                     33: 
                     34:                 if (rev->kq_errno) {
                     35:                     rev->error = 1;
                     36:                     ngx_set_socket_errno(rev->kq_errno);
                     37: 
                     38:                     return ngx_connection_error(c, rev->kq_errno,
                     39:                                "kevent() reported about an closed connection");
                     40:                 }
                     41: 
                     42:                 return 0;
                     43: 
                     44:             } else {
                     45:                 rev->ready = 0;
                     46:                 return NGX_AGAIN;
                     47:             }
                     48:         }
                     49:     }
                     50: 
                     51:     do {
                     52:         n = recv(c->fd, buf, size, 0);
                     53: 
                     54:         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
                     55:                        "recv: fd:%d %d of %d", c->fd, n, size);
                     56: 
                     57:         if (n >= 0) {
                     58:             if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
                     59:                 rev->available -= n;
                     60: 
                     61:                 /*
                     62:                  * rev->available may be negative here because some additional
                     63:                  * bytes may be received between kevent() and recv()
                     64:                  */
                     65: 
                     66:                 if (rev->available <= 0) {
                     67:                     if (!rev->pending_eof) {
                     68:                         rev->ready = 0;
                     69:                     }
                     70: 
                     71:                     if (rev->available < 0) {
                     72:                         rev->available = 0;
                     73:                     }
                     74:                 }
                     75: 
                     76:                 if (n == 0) {
                     77: 
                     78:                     /*
                     79:                      * on FreeBSD recv() may return 0 on closed socket
                     80:                      * even if kqueue reported about available data
                     81:                      */
                     82: 
                     83:                     rev->eof = 1;
                     84:                     rev->available = 0;
                     85:                 }
                     86: 
                     87:                 return n;
                     88:             }
                     89: 
                     90:             if ((size_t) n < size) {
                     91:                 rev->ready = 0;
                     92:             }
                     93: 
                     94:             if (n == 0) {
                     95:                 rev->eof = 1;
                     96:             }
                     97: 
                     98:             return n;
                     99:         }
                    100: 
                    101:         err = ngx_socket_errno;
                    102: 
                    103:         if (err == NGX_EAGAIN || err == NGX_EINTR) {
                    104:             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
                    105:                            "recv() not ready");
                    106:             n = NGX_AGAIN;
                    107: 
                    108:         } else {
                    109:             n = ngx_connection_error(c, err, "recv() failed");
                    110:             break;
                    111:         }
                    112: 
                    113:     } while (err == NGX_EINTR);
                    114: 
                    115:     rev->ready = 0;
                    116: 
                    117:     if (n == NGX_ERROR) {
                    118:         rev->error = 1;
                    119:     }
                    120: 
                    121:     return n;
                    122: }
                    123: 
                    124: #else /* ! NGX_HAVE_KQUEUE */
                    125: 
                    126: ssize_t
                    127: ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
                    128: {
                    129:     ssize_t       n;
                    130:     ngx_err_t     err;
                    131:     ngx_event_t  *rev;
                    132: 
                    133:     rev = c->read;
                    134: 
                    135:     do {
                    136:         n = recv(c->fd, buf, size, 0);
                    137: 
                    138:         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
                    139:                        "recv: fd:%d %d of %d", c->fd, n, size);
                    140: 
                    141:         if (n == 0) {
                    142:             rev->ready = 0;
                    143:             rev->eof = 1;
                    144:             return n;
                    145: 
                    146:         } else if (n > 0) {
                    147: 
                    148:             if ((size_t) n < size
                    149:                 && !(ngx_event_flags & NGX_USE_GREEDY_EVENT))
                    150:             {
                    151:                 rev->ready = 0;
                    152:             }
                    153: 
                    154:             return n;
                    155:         }
                    156: 
                    157:         err = ngx_socket_errno;
                    158: 
                    159:         if (err == NGX_EAGAIN || err == NGX_EINTR) {
                    160:             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
                    161:                            "recv() not ready");
                    162:             n = NGX_AGAIN;
                    163: 
                    164:         } else {
                    165:             n = ngx_connection_error(c, err, "recv() failed");
                    166:             break;
                    167:         }
                    168: 
                    169:     } while (err == NGX_EINTR);
                    170: 
                    171:     rev->ready = 0;
                    172: 
                    173:     if (n == NGX_ERROR) {
                    174:         rev->error = 1;
                    175:     }
                    176: 
                    177:     return n;
                    178: }
                    179: 
                    180: #endif /* NGX_HAVE_KQUEUE */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>