diff options
author | Igor Sysoev <igor@sysoev.ru> | 2003-06-11 19:28:34 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2003-06-11 19:28:34 +0400 |
commit | 239baac646073cab7bbaf537ba2d6ca844f2c992 (patch) | |
tree | c7c3f61213697a68dc95898d27a730c08abce049 /src/os | |
parent | e4a2526e5ccd4f3f5f160656c1a7b6f865ac44c8 (diff) |
nginx-0.0.1-2003-06-11-19:28:34 import
Diffstat (limited to 'src/os')
-rw-r--r-- | src/os/unix/ngx_aio_read.c | 1 | ||||
-rw-r--r-- | src/os/unix/ngx_aio_write.c | 3 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_config.h | 19 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_sendfile_chain.c | 5 | ||||
-rw-r--r-- | src/os/unix/ngx_linux_config.h | 13 | ||||
-rw-r--r-- | src/os/unix/ngx_readv_chain.c | 1 | ||||
-rw-r--r-- | src/os/unix/ngx_recv.c | 1 | ||||
-rw-r--r-- | src/os/unix/ngx_socket.c | 3 | ||||
-rw-r--r-- | src/os/unix/ngx_solaris_config.h | 3 | ||||
-rw-r--r-- | src/os/unix/ngx_writev_chain.c | 13 | ||||
-rw-r--r-- | src/os/win32/ngx_errno.c | 44 | ||||
-rw-r--r-- | src/os/win32/ngx_os_init.h | 2 | ||||
-rw-r--r-- | src/os/win32/ngx_socket.h | 8 | ||||
-rw-r--r-- | src/os/win32/ngx_types.h | 1 | ||||
-rw-r--r-- | src/os/win32/ngx_win32_init.c (renamed from src/os/win32/ngx_init.c) | 53 | ||||
-rw-r--r-- | src/os/win32/ngx_wsarecv.c | 90 | ||||
-rw-r--r-- | src/os/win32/ngx_wsasend_chain.c | 181 |
17 files changed, 396 insertions, 45 deletions
diff --git a/src/os/unix/ngx_aio_read.c b/src/os/unix/ngx_aio_read.c index 4896af9ce..bc5055860 100644 --- a/src/os/unix/ngx_aio_read.c +++ b/src/os/unix/ngx_aio_read.c @@ -1,6 +1,7 @@ #include <ngx_config.h> #include <ngx_core.h> +#include <ngx_event.h> #include <ngx_aio.h> #if (HAVE_KQUEUE) diff --git a/src/os/unix/ngx_aio_write.c b/src/os/unix/ngx_aio_write.c index 918535aa7..3a4d8e0b4 100644 --- a/src/os/unix/ngx_aio_write.c +++ b/src/os/unix/ngx_aio_write.c @@ -1,6 +1,7 @@ #include <ngx_config.h> #include <ngx_core.h> +#include <ngx_event.h> #include <ngx_aio.h> #if (HAVE_KQUEUE) @@ -29,6 +30,7 @@ ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size) ngx_log_debug(ev->log, "aio: ev->ready: %d" _ ev->ready); ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb); +#if 0 if (ev->timedout) { ngx_set_socket_errno(NGX_ETIMEDOUT); ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_write() timed out"); @@ -46,6 +48,7 @@ ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb); ev->ready = 1; } +#endif first = 0; diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h index 0a7eedd10..6fd0a694e 100644 --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -22,9 +22,22 @@ #include <osreldate.h> -#define QD_FMT "%qd" -#define QX_FMT "%qx" -#define OFF_FMT "%qd" +/* STUB */ +#define QD_FMT "%lld" +#define QX_FMT "%llx" +/**/ + +#if (i386) +#define OFF_FMT "%lld" +#define SIZE_FMT "%d" +#define SIZEX_FMT "%x" +#else +#define OFF_FMT "%ld" +#define SIZE_FMT "%ld" +#define SIZEX_FMT "%lx" +#endif + +#define PID_FMT "%d" #ifndef HAVE_SELECT diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c index a888c3613..a3c813e38 100644 --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -15,7 +15,8 @@ Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush the pending data that less than MSS and the data sent with 5 second delay. - So we use TCP_NOPUSH on FreeBSD 4.5+ only. + So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection + is not needed not keepalive. */ @@ -23,7 +24,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) { int rc, eintr, tcp_nopush; char *prev; - size_t hsize, size; + ssize_t hsize, size; off_t sent; struct iovec *iov; struct sf_hdtr hdtr; diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h index 96e1d8856..27fa317bc 100644 --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -29,14 +29,11 @@ #include <netdb.h> -typedef unsigned int u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; - -#define QD_FMT "%qd" -#define QX_FMT "%qx" -#define OFF_FMT "%qd" +#define QD_FMT "%qd" +#define QX_FMT "%qx" +#define OFF_FMT "%qd" +#define PID_FMT "%d" #ifndef HAVE_SELECT @@ -63,7 +60,7 @@ typedef unsigned char u_char; #ifndef HAVE_FIONBIO -#define HAVE_FIONBIO 1 +#define HAVE_FIONBIO 1 #endif diff --git a/src/os/unix/ngx_readv_chain.c b/src/os/unix/ngx_readv_chain.c index 8432f0c8d..744bf99bc 100644 --- a/src/os/unix/ngx_readv_chain.c +++ b/src/os/unix/ngx_readv_chain.c @@ -1,6 +1,7 @@ #include <ngx_config.h> #include <ngx_core.h> +#include <ngx_event.h> ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry) diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c index 98607d0c7..154565413 100644 --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -1,6 +1,7 @@ #include <ngx_config.h> #include <ngx_core.h> +#include <ngx_event.h> static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err); diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c index 941fc8cd1..48016cb10 100644 --- a/src/os/unix/ngx_socket.c +++ b/src/os/unix/ngx_socket.c @@ -55,8 +55,7 @@ int ngx_tcp_push(ngx_socket_t s) (const void *) &tcp_nopush, sizeof(int)); } -#else - +#else int ngx_tcp_nopush(ngx_socket_t s) { diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h index e7946449d..78eeb7213 100644 --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -30,6 +30,7 @@ typedef uint32_t u_int32_t; #define QD_FMT "%lld" #define QX_FMT "%llx" #define OFF_FMT "%lld" +#define PID_FMT "%ld" #ifndef HAVE_SELECT @@ -62,7 +63,7 @@ typedef uint32_t u_int32_t; #ifndef HAVE_FIONBIO -#define HAVE_FIONBIO 1 +#define HAVE_FIONBIO 1 #endif diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c index b667bc507..32b2dd48d 100644 --- a/src/os/unix/ngx_writev_chain.c +++ b/src/os/unix/ngx_writev_chain.c @@ -6,15 +6,14 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in) { char *prev; - size_t size; - ssize_t n; + ssize_t n, size; off_t sent; struct iovec *iov; ngx_err_t err; - ngx_array_t io; + ngx_array_t iovecs; ngx_chain_t *ce; - ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); + ngx_init_array(iovecs, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); prev = NULL; iov = NULL; @@ -27,14 +26,14 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in) prev = ce->hunk->last; } else { - ngx_test_null(iov, ngx_push_array(&io), NGX_CHAIN_ERROR); + ngx_test_null(iov, ngx_push_array(&iovecs), NGX_CHAIN_ERROR); iov->iov_base = ce->hunk->pos; iov->iov_len = ce->hunk->last - ce->hunk->pos; prev = ce->hunk->last; } } - n = writev(c->fd, (struct iovec *) io.elts, io.nelts); + n = writev(c->fd, iovecs.elts, iovecs.nelts); if (n == -1) { err = ngx_errno; @@ -93,7 +92,7 @@ ngx_log_debug(c->log, "SIZE: %d" _ size); break; } - ngx_destroy_array(&io); + ngx_destroy_array(&iovecs); return ce; } diff --git a/src/os/win32/ngx_errno.c b/src/os/win32/ngx_errno.c index d0cff7b73..30c1b9315 100644 --- a/src/os/win32/ngx_errno.c +++ b/src/os/win32/ngx_errno.c @@ -9,9 +9,29 @@ #include <ngx_core.h> +ngx_str_t wsa_errors[] = { + ngx_string("Invalid argument"), /* 10022 */ + ngx_null_string, /* 10023 */ + ngx_null_string, /* 10024 */ + ngx_null_string, /* 10025 */ + ngx_null_string, /* 10026 */ + ngx_null_string, /* 10027 */ + ngx_null_string, /* 10028 */ + ngx_null_string, /* 10029 */ + ngx_null_string, /* 10030 */ + ngx_null_string, /* 10031 */ + ngx_null_string, /* 10032 */ + ngx_null_string, /* 10033 */ + ngx_null_string, /* 10034 */ + ngx_string("Resource temporarily unavailable") /* 10035 */ +}; + + int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size) { - int len; + int n; + u_int len; + ngx_err_t format_error; len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -19,12 +39,28 @@ int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size) MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errstr, size, NULL); - /* add WSA error messages */ - if (len == 0) { + format_error = GetLastError(); + + if (format_error == ERROR_MR_MID_NOT_FOUND) { + n = err - WSABASEERR - 22; + + if (n >= 0 && n < 14) { + len = wsa_errors[n].len; + + if (len) { + if (len > size) { + len = size; + } + + ngx_memcpy(errstr, wsa_errors[n].data, len); + return len; + } + } + } len = ngx_snprintf(errstr, size, - "FormatMessage error:(%d)", GetLastError()); + "FormatMessage() error:(%d)", format_error); return len; } diff --git a/src/os/win32/ngx_os_init.h b/src/os/win32/ngx_os_init.h index 4a00a3a05..8ab820694 100644 --- a/src/os/win32/ngx_os_init.h +++ b/src/os/win32/ngx_os_init.h @@ -8,5 +8,7 @@ int ngx_os_init(ngx_log_t *log); +ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size); + #endif /* _NGX_OS_INIT_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h index f86a39aff..55629a1a9 100644 --- a/src/os/win32/ngx_socket.h +++ b/src/os/win32/ngx_socket.h @@ -16,6 +16,7 @@ typedef int socklen_t; #define ngx_socket(af, type, proto, flags) \ WSASocket(af, type, proto, NULL, 0, flags) + #define ngx_socket_n "WSASocket()" int ngx_nonblocking(ngx_socket_t s); @@ -36,4 +37,11 @@ extern LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs; extern LPFN_TRANSMITFILE transmitfile; +ngx_inline int ngx_tcp_push(s) { + return 0; +} + +#define ngx_tcp_push_n "tcp_push()" + + #endif /* _NGX_SOCKET_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h index 1c4ff0c02..b858faee9 100644 --- a/src/os/win32/ngx_types.h +++ b/src/os/win32/ngx_types.h @@ -19,6 +19,7 @@ typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t; #define QD_FMT "%I64d" #define QX_FMT "%I64x" #define OFF_FMT "%I64d" +#define PID_FMT "%d" #endif /* _NGX_TYPES_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_init.c b/src/os/win32/ngx_win32_init.c index c57ce6c9d..6bc69e4c9 100644 --- a/src/os/win32/ngx_init.c +++ b/src/os/win32/ngx_win32_init.c @@ -2,15 +2,23 @@ #include <ngx_config.h> #include <ngx_core.h> +/* STUB */ +ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size); +ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in); +/* */ + +int ngx_win32_version; int ngx_max_sockets; +int ngx_inherited_nonblocking = 1; ngx_os_io_t ngx_os_io = { ngx_wsarecv, NULL, NULL, - NULL + ngx_wsasend_chain, + 0 }; @@ -26,7 +34,7 @@ static GUID tf_guid = WSAID_TRANSMITFILE; int ngx_os_init(ngx_log_t *log) { - u_int sp; + u_int osviex; DWORD bytes; SOCKET s; WSADATA wsd; @@ -34,14 +42,14 @@ int ngx_os_init(ngx_log_t *log) /* get Windows version */ - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + ngx_memzero(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); osviex = GetVersionEx((OSVERSIONINFO *) &osvi); if (osviex == 0) { osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - if (GetVersionEx((OSVERSIONINFO *) &osvi) == 0) + if (GetVersionEx((OSVERSIONINFO *) &osvi) == 0) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "GetVersionEx() failed"); return NGX_ERROR; @@ -49,27 +57,36 @@ int ngx_os_init(ngx_log_t *log) } /* - * Windows 95 1400 - * Windows 98 1410 - * Windows ME 1490 - * Windows NT 3.51 2351 - * Windows NT 4.0 2400 - * Windows 2000 2500 - * Windows XP 2501 - * Windows 2003 2502 + * Windows 95 140000 + * Windows 98 141000 + * Windows ME 149000 + * Windows NT 3.51 235100 + * Windows NT 4.0 240000 + * Windows NT 4.0 SP5 240050 + * Windows 2000 250000 + * Windows XP 250100 + * Windows 2003 250200 */ - ngx_win32_version = osvi.dwPlatformId * 1000 - + osvi.dwMajorVersion * 100 - + osvi.dwMinorVersion; + ngx_win32_version = osvi.dwPlatformId * 100000 + + osvi.dwMajorVersion * 10000 + + osvi.dwMinorVersion * 100; if (osviex) { - sp = osvi.wServicePackMajor * 100 + osvi.wServicePackMinor; + ngx_win32_version += osvi.wServicePackMajor * 10 + + osvi.wServicePackMinor; + + ngx_log_error(NGX_LOG_INFO, log, 0, + "OS: %u build:%u, %s, suite:%x, type:%u", + ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion, + osvi.wReserved[0], osvi.wReserved[1]); +#if 0 ngx_log_error(NGX_LOG_INFO, log, 0, - "OS: %u build:%u, %s, SP:%u, suite:%x, type:%u", + "OS: %u build:%u, %s, suite:%x, type:%u", ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion, - sp, osvi.wSuiteMask, osvi.wProductType); + osvi.wSuiteMask, osvi.wProductType); +#endif } else { ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %u build:%u, %s", diff --git a/src/os/win32/ngx_wsarecv.c b/src/os/win32/ngx_wsarecv.c new file mode 100644 index 000000000..038554a68 --- /dev/null +++ b/src/os/win32/ngx_wsarecv.c @@ -0,0 +1,90 @@ + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_event.h> + + +ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size) +{ + int rc; + u_int flags; + size_t bytes; + WSABUF wsabuf[1]; + ngx_err_t err; + ngx_event_t *rev; + LPWSAOVERLAPPED ovlp; + + rev = c->read; + bytes = 0; + + if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) && rev->ready) { + rev->ready = 0; + + /* the overlapped WSARecv() completed */ + + if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { + if (rev->ovlp.error) { + ngx_log_error(NGX_LOG_ERR, c->log, rev->ovlp.error, + "WSARecv() failed"); + return NGX_ERROR; + } + + return rev->available; + } + + if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp, + &bytes, 0, NULL) == 0) { + err = ngx_socket_errno; + ngx_log_error(NGX_LOG_CRIT, c->log, err, + "WSARecv() or WSAGetOverlappedResult() failed"); + + return NGX_ERROR; + } + + return bytes; + } + + if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { + ovlp = (LPWSAOVERLAPPED) &c->read->ovlp; + ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); + + } else { + ovlp = NULL; + } + + wsabuf[0].buf = buf; + wsabuf[0].len = size; + flags = 0; + + rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL); + + ngx_log_debug(c->log, "WSARecv: %d:%d" _ rc _ bytes); + + if (rc == -1) { + err = ngx_socket_errno; + if (err == WSA_IO_PENDING) { + return NGX_AGAIN; + + } else if (err == WSAEWOULDBLOCK) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "WSARecv() EAGAIN"); + return NGX_AGAIN; + + } else { + ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSARecv() failed"); + return NGX_ERROR; + } + } + + if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { + + /* + * If a socket was bound with I/O completion port + * then GetQueuedCompletionStatus() would anyway return its status + * despite that WSARecv() was already completed. + */ + + return NGX_AGAIN; + } + + return bytes; +} diff --git a/src/os/win32/ngx_wsasend_chain.c b/src/os/win32/ngx_wsasend_chain.c new file mode 100644 index 000000000..ebaa77e96 --- /dev/null +++ b/src/os/win32/ngx_wsasend_chain.c @@ -0,0 +1,181 @@ + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_event.h> + + +ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in) +{ + int rc; + char *prev; + size_t size, sent; + LPWSABUF wsabuf; + ngx_err_t err; + ngx_event_t *wev; + ngx_array_t wsabufs; + ngx_chain_t *ce; + LPWSAOVERLAPPED ovlp; + +#if 0 + +iocp: + if ready + get result + update chain + return if done; + wsasend + +non-block + for ( ;; ) { + wsasend + if no again + update chain + return if done; + } + + + for ( ;; ) { + + make buffers and limit data for both ovlp and nonblocked, + configured in events module + + if (iocp && ready) { + get result + + } else { + if (file) + transmitfile + else + wsasend + + if (iocp) + return chain + return chain if again + here is result + } + + if (result) + update chain; + return chain if done + } + } + + +#endif + + wev = c->write; + + if (((ngx_event_flags & NGX_HAVE_AIO_EVENT) && !wev->ready) + || ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0)) + { + /* + * WSABUFs must be 4-byte aligned otherwise + * WSASend() will return undocumented WSAEINVAL error. + */ + + ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR); + + prev = NULL; + wsabuf = NULL; + + /* create the WSABUF and coalesce the neighbouring chain entries */ + for (ce = in; ce; ce = ce->next) { + + if (prev == ce->hunk->pos) { + wsabuf->len += ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; + + } else { + ngx_test_null(wsabuf, ngx_push_array(&wsabufs), + NGX_CHAIN_ERROR); + wsabuf->buf = ce->hunk->pos; + wsabuf->len = ce->hunk->last - ce->hunk->pos; + prev = ce->hunk->last; + } + } + + if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { + ovlp = (LPWSAOVERLAPPED) &c->write->ovlp; + ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); + + } else { + ovlp = NULL; + } + + rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL); + + if (rc == -1) { + err = ngx_errno; + if (err == WSA_IO_PENDING) { + sent = 0; + + } else if (err == WSAEWOULDBLOCK) { + sent = 0; + ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN"); + + } else { + ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed"); + return NGX_CHAIN_ERROR; + } + + } else { + + if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { + + /* + * If a socket was bound with I/O completion port then + * GetQueuedCompletionStatus() would anyway return its status + * despite that WSASend() was already completed. + */ + + sent = 0; + } + } + + } else { + if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) { + wev->ready = 0; + + /* the overlapped WSASend() completed */ + + if (wev->ovlp.error) { + ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error, + "WSASend() failed"); + return NGX_CHAIN_ERROR; + } + + sent = wev->available; + } + } + +#if (NGX_DEBUG_WRITE_CHAIN) + ngx_log_debug(c->log, "WSASend(): %d" _ sent); +#endif + + c->sent += sent; + + for (ce = in; ce && sent > 0; ce = ce->next) { + + size = ce->hunk->last - ce->hunk->pos; + + if (sent >= size) { + sent -= size; + + if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { + ce->hunk->pos = ce->hunk->last; + } + + continue; + } + + if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { + ce->hunk->pos += sent; + } + + break; + } + + ngx_destroy_array(&wsabufs); + + return ce; +} |