Annotation of embedaddon/nginx/src/os/unix/ngx_recv.c, revision 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>