mirror of
https://github.com/nginx/nginx.git
synced 2024-12-27 17:31:35 -06:00
nginx-0.0.1-2003-11-14-10:20:34 import
This commit is contained in:
parent
45890ea8c1
commit
7f9d894e10
@ -77,6 +77,15 @@ ngx_module_t ngx_iocp_module = {
|
||||
};
|
||||
|
||||
|
||||
ngx_os_io_t ngx_iocp_io = {
|
||||
ngx_overlapped_wsarecv,
|
||||
NULL,
|
||||
NULL,
|
||||
ngx_wsasend_chain,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static HANDLE iocp;
|
||||
|
||||
|
||||
@ -225,6 +234,7 @@ ngx_log_debug(log, "iocp ev: %08x" _ ev);
|
||||
|
||||
switch (key) {
|
||||
case NGX_IOCP_IO:
|
||||
ev->complete = 1;
|
||||
ev->ready = 1;
|
||||
break;
|
||||
|
||||
|
@ -140,9 +140,7 @@ int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
|
||||
retry = 0;
|
||||
|
||||
for ( ;; ) {
|
||||
if (ngx_rename_file(temp_file->data, ctx->file.name.data)
|
||||
!= NGX_FILE_ERROR)
|
||||
{
|
||||
if (ngx_rename_file(temp_file, (&ctx->file.name), r->pool) == NGX_OK) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -25,12 +25,12 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
|
||||
rev = c->read;
|
||||
|
||||
if (!rev->ready) {
|
||||
ngx_log_error(NGX_LOG_ALERT, rev->log, 0, "SECOND AIO POST");
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "SECOND AIO POST");
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_log_debug(rev->log, "rev->complete: %d" _ rev->complete);
|
||||
ngx_log_debug(rev->log, "aio size: %d" _ size);
|
||||
ngx_log_debug(c->log, "rev->complete: %d" _ rev->complete);
|
||||
ngx_log_debug(c->log, "aio size: %d" _ size);
|
||||
|
||||
if (!rev->complete) {
|
||||
ngx_memzero(&rev->aiocb, sizeof(struct aiocb));
|
||||
@ -52,7 +52,7 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug(rev->log, "aio_read: #%d OK" _ c->fd);
|
||||
ngx_log_debug(c->log, "aio_read: #%d OK" _ c->fd);
|
||||
|
||||
rev->active = 1;
|
||||
rev->ready = 0;
|
||||
@ -62,7 +62,7 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
|
||||
|
||||
n = aio_error(&rev->aiocb);
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, rev->log, ngx_errno, "aio_error() failed");
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "aio_error() failed");
|
||||
rev->error = 1;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -70,14 +70,14 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
|
||||
if (n != 0) {
|
||||
if (n == NGX_EINPROGRESS) {
|
||||
if (rev->ready) {
|
||||
ngx_log_error(NGX_LOG_ALERT, rev->log, n,
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, n,
|
||||
"aio_read() still in progress");
|
||||
rev->ready = 0;
|
||||
}
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, rev->log, n, "aio_read() failed");
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, n, "aio_read() failed");
|
||||
rev->error = 1;
|
||||
rev->ready = 0;
|
||||
return NGX_ERROR;
|
||||
@ -85,7 +85,7 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
|
||||
|
||||
n = aio_return(&rev->aiocb);
|
||||
if (n == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, rev->log, ngx_errno,
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
||||
"aio_return() failed");
|
||||
|
||||
rev->error = 1;
|
||||
|
@ -45,7 +45,7 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
|
||||
off_t offset, ngx_pool_t *pool);
|
||||
|
||||
|
||||
#define ngx_rename_file rename
|
||||
#define ngx_rename_file(from, to, pool) rename(from->data, to->data)
|
||||
#define ngx_rename_file_n "rename"
|
||||
|
||||
|
||||
|
@ -35,6 +35,8 @@ typedef struct {
|
||||
int ngx_os_init(ngx_log_t *log);
|
||||
int ngx_daemon(ngx_log_t *log);
|
||||
int ngx_posix_init(ngx_log_t *log);
|
||||
int ngx_posix_post_conf_init(ngx_log_t *log);
|
||||
|
||||
|
||||
ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
|
||||
ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
|
||||
|
@ -40,6 +40,8 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
||||
}
|
||||
|
||||
do {
|
||||
rev->ready = 1;
|
||||
|
||||
n = recv(c->fd, buf, size, 0);
|
||||
|
||||
ngx_log_debug(c->log, "recv: %d:%d" _ n _ size);
|
||||
@ -78,11 +80,14 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
||||
}
|
||||
|
||||
rev->ready = 0;
|
||||
rev->error = 1;
|
||||
n = ngx_unix_recv_error(rev, ngx_socket_errno);
|
||||
|
||||
} while (n == NGX_EINTR);
|
||||
|
||||
if (n == NGX_ERROR){
|
||||
rev->error = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -96,6 +101,8 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
||||
rev = c->read;
|
||||
|
||||
do {
|
||||
rev->ready = 1;
|
||||
|
||||
n = recv(c->fd, buf, size, 0);
|
||||
|
||||
ngx_log_debug(c->log, "recv: %d:%d" _ n _ size);
|
||||
@ -113,11 +120,14 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
||||
}
|
||||
|
||||
rev->ready = 0;
|
||||
rev->error = 1;
|
||||
n = ngx_unix_recv_error(rev, ngx_socket_errno);
|
||||
|
||||
} while (n == NGX_EINTR);
|
||||
|
||||
if (n == NGX_ERROR){
|
||||
rev->error = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -3,17 +3,19 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
#if 0
|
||||
/* STUB */
|
||||
ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
|
||||
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in);
|
||||
int ngx_posix_init(ngx_log_t *log);
|
||||
int ngx_posix_post_conf_init(ngx_log_t *log);
|
||||
/* */
|
||||
#endif
|
||||
|
||||
|
||||
ngx_os_io_t ngx_os_io = {
|
||||
ngx_unix_recv,
|
||||
NULL,
|
||||
ngx_readv_chain,
|
||||
NULL,
|
||||
ngx_writev_chain,
|
||||
NGX_HAVE_ZEROCOPY
|
||||
|
@ -24,6 +24,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
iov = NULL;
|
||||
|
||||
/* create the iovec and coalesce the neighbouring hunks */
|
||||
|
||||
for (cl = in; cl; cl = cl->next) {
|
||||
|
||||
if (prev == cl->hunk->pos) {
|
||||
@ -57,7 +58,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
sent = n > 0 ? n : 0;
|
||||
|
||||
#if (NGX_DEBUG_WRITE_CHAIN)
|
||||
ngx_log_debug(c->log, "writev: %qd" _ sent);
|
||||
ngx_log_debug(c->log, "writev: " OFF_FMT _ sent);
|
||||
#endif
|
||||
|
||||
c->sent += sent;
|
||||
@ -75,12 +76,6 @@ ngx_log_debug(c->log, "SIZE: %d" _ size);
|
||||
cl->hunk->pos = cl->hunk->last;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (cl->hunk->type & NGX_HUNK_FILE) {
|
||||
cl->hunk->file_pos = cl->hunk->file_last;
|
||||
}
|
||||
#endif
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -88,12 +83,6 @@ ngx_log_debug(c->log, "SIZE: %d" _ size);
|
||||
cl->hunk->pos += sent;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (cl->hunk->type & NGX_HUNK_FILE) {
|
||||
cl->hunk->file_pos += sent;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -6,13 +6,11 @@
|
||||
ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
{
|
||||
size_t n;
|
||||
long high_offset;
|
||||
ngx_err_t err;
|
||||
OVERLAPPED ovlp, *povlp;
|
||||
|
||||
#if (WIN9X)
|
||||
|
||||
if (ngx_win32_version < NGX_WIN_NT) {
|
||||
long high_offset;
|
||||
ngx_err_t err;
|
||||
|
||||
/*
|
||||
* in Win9X the overlapped pointer must be NULL
|
||||
@ -47,8 +45,6 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
povlp = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
#endif
|
||||
ovlp.Internal = 0;
|
||||
ovlp.InternalHigh = 0;
|
||||
ovlp.Offset = (DWORD) offset;
|
||||
@ -56,10 +52,7 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
ovlp.hEvent = NULL;
|
||||
|
||||
povlp = &ovlp;
|
||||
|
||||
#if (WIN9X)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ReadFile(file->fd, buf, size, &n, povlp) == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "ReadFile() failed");
|
||||
@ -75,13 +68,11 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
{
|
||||
size_t n;
|
||||
long high_offset;
|
||||
ngx_err_t err;
|
||||
OVERLAPPED ovlp, *povlp;
|
||||
|
||||
#if (WIN9X)
|
||||
|
||||
if (ngx_win32_version < NGX_WIN_NT) {
|
||||
long high_offset;
|
||||
ngx_err_t err;
|
||||
|
||||
/*
|
||||
* in Win9X the overlapped pointer must be NULL
|
||||
@ -116,9 +107,6 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
povlp = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
#endif
|
||||
|
||||
ovlp.Internal = 0;
|
||||
ovlp.InternalHigh = 0;
|
||||
ovlp.Offset = (DWORD) offset;
|
||||
@ -126,10 +114,7 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
ovlp.hEvent = NULL;
|
||||
|
||||
povlp = &ovlp;
|
||||
|
||||
#if (WIN9X)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (WriteFile(file->fd, buf, size, &n, povlp) == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "WriteFile() failed");
|
||||
@ -142,15 +127,103 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
|
||||
}
|
||||
|
||||
|
||||
ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
|
||||
off_t offset, ngx_pool_t *pool)
|
||||
{
|
||||
char *buf, *prev;
|
||||
size_t size;
|
||||
ssize_t total, n;
|
||||
|
||||
total = 0;
|
||||
|
||||
while (cl) {
|
||||
buf = cl->hunk->pos;
|
||||
prev = buf;
|
||||
size = 0;
|
||||
|
||||
/* coalesce the neighbouring hunks */
|
||||
|
||||
while (cl && prev == cl->hunk->pos) {
|
||||
size += cl->hunk->last - cl->hunk->pos;
|
||||
prev = cl->hunk->last;
|
||||
cl = cl->next;
|
||||
}
|
||||
|
||||
n = ngx_write_file(file, buf, size, offset);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
total += n;
|
||||
offset += n;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
int ngx_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool)
|
||||
{
|
||||
int rc, collision;
|
||||
u_int num;
|
||||
char *name;
|
||||
ngx_err_t err;
|
||||
|
||||
name = ngx_palloc(pool, to->len + 1 + 10 + 1 + sizeof("DELETE"));
|
||||
ngx_memcpy(name, to->data, to->len);
|
||||
|
||||
collision = 0;
|
||||
|
||||
/* mutex_lock() (per cache or single ?) */
|
||||
|
||||
do {
|
||||
num = ngx_next_temp_number(collision);
|
||||
|
||||
ngx_snprintf(name + to->len, 1 + 10 + 1 + sizeof("DELETE"),
|
||||
".%010u.DELETE", num);
|
||||
|
||||
if (MoveFile(to->data, name) == 0) {
|
||||
err = ngx_errno;
|
||||
if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
collision = 1;
|
||||
ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno,
|
||||
"MoveFile() failed");
|
||||
}
|
||||
|
||||
} while (collision);
|
||||
|
||||
if (ngx_win32_version >= NGX_WIN_NT) {
|
||||
if (DeleteFile(name) == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno,
|
||||
"DeleteFile() failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (MoveFile(from->data, to->data) == 0) {
|
||||
rc = NGX_ERROR;
|
||||
|
||||
} else {
|
||||
rc = NGX_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno, "MoveFile() failed");
|
||||
}
|
||||
|
||||
/* mutex_unlock() */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int ngx_file_append_mode(ngx_fd_t fd)
|
||||
{
|
||||
ngx_err_t err;
|
||||
|
||||
if (SetFilePointer(fd, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) {
|
||||
err = ngx_errno;
|
||||
if (err != NO_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ERR, file->log, err,
|
||||
"SeekFilePointer() failed");
|
||||
if (ngx_errno != NO_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,7 @@ int ngx_file_append_mode(ngx_fd_t fd);
|
||||
#define ngx_close_file CloseHandle
|
||||
#define ngx_close_file_n "CloseHandle()"
|
||||
|
||||
/* STUB */
|
||||
#define ngx_rename_file MoveFile
|
||||
int ngx_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool);
|
||||
#define ngx_rename_file_n "MoveFile()"
|
||||
|
||||
#define ngx_mkdir(name) CreateDirectory(name, NULL)
|
||||
|
@ -1,4 +1,4 @@
|
||||
ifndef _NGX_OS_H_INCLUDED_
|
||||
#ifndef _NGX_OS_H_INCLUDED_
|
||||
#define _NGX_OS_H_INCLUDED_
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ typedef struct {
|
||||
|
||||
int ngx_os_init(ngx_log_t *log);
|
||||
|
||||
ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size);
|
||||
ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, char *buf, size_t size);
|
||||
ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in);
|
||||
ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in);
|
||||
|
||||
|
||||
extern ngx_os_io_t ngx_os_io;
|
||||
extern int ngx_max_sockets;
|
||||
|
@ -1,14 +0,0 @@
|
||||
#ifndef _NGX_OS_INIT_H_INCLUDED_
|
||||
#define _NGX_OS_INIT_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
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_ */
|
@ -1,93 +0,0 @@
|
||||
|
||||
#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;
|
||||
ngx_err_t err;
|
||||
WSABUF wsabuf[1];
|
||||
ngx_event_t *ev;
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE handler;
|
||||
|
||||
ev = c->read;
|
||||
|
||||
/* DEBUG */ bytes = 0;
|
||||
|
||||
if (ev->timedout) {
|
||||
ngx_set_socket_errno(NGX_ETIMEDOUT);
|
||||
ngx_log_error(NGX_LOG_ERR, ev->log, 0, "WSARecv() timed out");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ev->ready) {
|
||||
ev->ready = 0;
|
||||
|
||||
#if (HAVE_IOCP_EVENT) /* iocp */
|
||||
|
||||
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
|
||||
if (ev->ovlp.error) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, ev->ovlp.error,
|
||||
"WSARecv() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return ev->available;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &ev->ovlp,
|
||||
&bytes, 0, NULL) == 0) {
|
||||
err = ngx_socket_errno;
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, err,
|
||||
"WSARecv() or WSAGetOverlappedResult() failed");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
ngx_memzero(&ev->ovlp, sizeof(WSAOVERLAPPED));
|
||||
wsabuf[0].buf = buf;
|
||||
wsabuf[0].len = size;
|
||||
flags = 0;
|
||||
|
||||
#if 0
|
||||
handler = ev->handler;
|
||||
#else
|
||||
handler = NULL;
|
||||
#endif
|
||||
|
||||
rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags,
|
||||
(LPWSAOVERLAPPED) &ev->ovlp, handler);
|
||||
|
||||
ngx_log_debug(ev->log, "WSARecv: %d:%d" _ rc _ bytes);
|
||||
|
||||
if (rc == -1) {
|
||||
err = ngx_socket_errno;
|
||||
if (err == WSA_IO_PENDING) {
|
||||
return NGX_AGAIN;
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, err, "WSARecv() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if (HAVE_IOCP_EVENT) /* iocp */
|
||||
|
||||
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return bytes;
|
||||
}
|
@ -2,11 +2,6 @@
|
||||
#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;
|
||||
|
@ -4,6 +4,149 @@
|
||||
#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;
|
||||
|
||||
wsabuf[0].buf = buf;
|
||||
wsabuf[0].len = size;
|
||||
flags = 0;
|
||||
bytes = 0;
|
||||
|
||||
rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);
|
||||
|
||||
ngx_log_debug(c->log, "WSARecv: %d:%d" _ rc _ bytes);
|
||||
|
||||
rev = c->read;
|
||||
|
||||
if (rc == -1) {
|
||||
rev->ready = 0;
|
||||
err = ngx_socket_errno;
|
||||
|
||||
if (err == WSAEWOULDBLOCK) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, err, "WSARecv() EAGAIN");
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
rev->error = 1;
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSARecv() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (bytes < size) {
|
||||
rev->ready = 0;
|
||||
}
|
||||
|
||||
if (bytes == 0) {
|
||||
rev->eof = 1;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
ssize_t ngx_overlapped_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;
|
||||
|
||||
if (!rev->ready) {
|
||||
ngx_log_error(NGX_LOG_ALERT, rev->log, 0, "SECOND WSA POST");
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_log_debug(c->log, "rev->complete: %d" _ rev->complete);
|
||||
|
||||
if (rev->complete) {
|
||||
rev->complete = 0;
|
||||
|
||||
if (ngx_event_flags & NGX_USE_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) {
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
|
||||
"WSARecv() or WSAGetOverlappedResult() failed");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
|
||||
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
|
||||
wsabuf[0].buf = buf;
|
||||
wsabuf[0].len = size;
|
||||
flags = 0;
|
||||
bytes = 0;
|
||||
|
||||
rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
|
||||
|
||||
rev->complete = 0;
|
||||
|
||||
ngx_log_debug(c->log, "WSARecv: %d:%d" _ rc _ bytes);
|
||||
|
||||
if (rc == -1) {
|
||||
err = ngx_socket_errno;
|
||||
if (err == WSA_IO_PENDING) {
|
||||
rev->active = 1;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
rev->error = 1;
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSARecv() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
|
||||
|
||||
/*
|
||||
* if a socket was bound with I/O completion port
|
||||
* then GetQueuedCompletionStatus() would anyway return its status
|
||||
* despite that WSARecv() was already complete
|
||||
*/
|
||||
|
||||
rev->active = 1;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (bytes == 0) {
|
||||
rev->eof = 1;
|
||||
rev->ready = 0;
|
||||
|
||||
} else {
|
||||
rev->ready = 1;
|
||||
}
|
||||
|
||||
rev->active = 0;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* DELELTE IT WHEN ABOVE FUNC WOULD BE TESTED */
|
||||
|
||||
ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
|
||||
{
|
||||
int rc;
|
||||
@ -88,3 +231,5 @@ ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4,6 +4,249 @@
|
||||
#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 *cl;
|
||||
|
||||
wev = c->write;
|
||||
|
||||
if (!wev->ready) {
|
||||
return in;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 bufs */
|
||||
|
||||
for (cl = in; cl; cl = cl->next) {
|
||||
|
||||
if (prev == cl->hunk->pos) {
|
||||
wsabuf->len += cl->hunk->last - cl->hunk->pos;
|
||||
prev = cl->hunk->last;
|
||||
|
||||
} else {
|
||||
ngx_test_null(wsabuf, ngx_push_array(&wsabufs), NGX_CHAIN_ERROR);
|
||||
wsabuf->buf = cl->hunk->pos;
|
||||
wsabuf->len = cl->hunk->last - cl->hunk->pos;
|
||||
prev = cl->hunk->last;
|
||||
}
|
||||
}
|
||||
|
||||
rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, NULL, NULL);
|
||||
|
||||
if (rc == -1) {
|
||||
err = ngx_errno;
|
||||
|
||||
if (err == WSAEWOULDBLOCK) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN");
|
||||
wev->ready = 0;
|
||||
return in;
|
||||
|
||||
} else {
|
||||
wev->error = 1;
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed");
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG_WRITE_CHAIN)
|
||||
ngx_log_debug(c->log, "WSASend(): %d" _ sent);
|
||||
#endif
|
||||
|
||||
c->sent += sent;
|
||||
|
||||
for (cl = in; cl && sent > 0; cl = cl->next) {
|
||||
|
||||
size = cl->hunk->last - cl->hunk->pos;
|
||||
|
||||
if (sent >= size) {
|
||||
sent -= size;
|
||||
|
||||
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
|
||||
cl->hunk->pos = cl->hunk->last;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
|
||||
cl->hunk->pos += sent;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (cl) {
|
||||
wev->ready = 0;
|
||||
}
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
||||
|
||||
ngx_chain_t *ngx_overlapped_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 *cl;
|
||||
LPWSAOVERLAPPED ovlp;
|
||||
|
||||
wev = c->write;
|
||||
|
||||
if (!wev->ready) {
|
||||
return in;
|
||||
}
|
||||
|
||||
if (!wev->complete) {
|
||||
|
||||
/* post the overlapped WSASend() */
|
||||
|
||||
/*
|
||||
* 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 bufs */
|
||||
|
||||
for (cl = in; cl; cl = cl->next) {
|
||||
|
||||
if (prev == cl->hunk->pos) {
|
||||
wsabuf->len += cl->hunk->last - cl->hunk->pos;
|
||||
prev = cl->hunk->last;
|
||||
|
||||
} else {
|
||||
ngx_test_null(wsabuf, ngx_push_array(&wsabufs),
|
||||
NGX_CHAIN_ERROR);
|
||||
wsabuf->buf = cl->hunk->pos;
|
||||
wsabuf->len = cl->hunk->last - cl->hunk->pos;
|
||||
prev = cl->hunk->last;
|
||||
}
|
||||
}
|
||||
|
||||
ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
|
||||
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
|
||||
|
||||
rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL);
|
||||
|
||||
wev->complete = 0;
|
||||
|
||||
if (rc == -1) {
|
||||
err = ngx_errno;
|
||||
|
||||
if (err == WSA_IO_PENDING) {
|
||||
wev->active = 1;
|
||||
return in;
|
||||
|
||||
} else {
|
||||
wev->error = 1;
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed");
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
|
||||
|
||||
/*
|
||||
* if a socket was bound with I/O completion port then
|
||||
* GetQueuedCompletionStatus() would anyway return its status
|
||||
* despite that WSASend() was already complete
|
||||
*/
|
||||
|
||||
wev->active = 1;
|
||||
return in;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* the overlapped WSASend() complete */
|
||||
|
||||
wev->complete = 0;
|
||||
wev->active = 0;
|
||||
|
||||
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
|
||||
if (wev->ovlp.error) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error,
|
||||
"WSASend() failed");
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
|
||||
sent = wev->available;
|
||||
|
||||
} else {
|
||||
if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp,
|
||||
&sent, 0, NULL) == 0) {
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
|
||||
"WSASend() or WSAGetOverlappedResult() failed");
|
||||
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG_WRITE_CHAIN)
|
||||
ngx_log_debug(c->log, "WSASend(): %d" _ sent);
|
||||
#endif
|
||||
|
||||
c->sent += sent;
|
||||
|
||||
for (cl = in; cl && sent > 0; cl = cl->next) {
|
||||
|
||||
size = cl->hunk->last - cl->hunk->pos;
|
||||
|
||||
if (sent >= size) {
|
||||
sent -= size;
|
||||
|
||||
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
|
||||
cl->hunk->pos = cl->hunk->last;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
|
||||
cl->hunk->pos += sent;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (cl) {
|
||||
wev->ready = 0;
|
||||
|
||||
} else {
|
||||
wev->ready = 1;
|
||||
}
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
{
|
||||
int rc;
|
||||
@ -175,7 +418,7 @@ non-block
|
||||
break;
|
||||
}
|
||||
|
||||
ngx_destroy_array(&wsabufs);
|
||||
|
||||
return ce;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user