diff options
Diffstat (limited to 'src/os/win32')
-rw-r--r-- | src/os/win32/nginx.ico | bin | 0 -> 518 bytes | |||
-rw-r--r-- | src/os/win32/nginx.rc | 16 | ||||
-rw-r--r-- | src/os/win32/ngx_alloc.c | 5 | ||||
-rw-r--r-- | src/os/win32/ngx_atomic.h | 2 | ||||
-rw-r--r-- | src/os/win32/ngx_errno.c | 130 | ||||
-rw-r--r-- | src/os/win32/ngx_errno.h | 2 | ||||
-rw-r--r-- | src/os/win32/ngx_files.c | 20 | ||||
-rw-r--r-- | src/os/win32/ngx_gui.c | 85 | ||||
-rw-r--r-- | src/os/win32/ngx_gui.h | 27 | ||||
-rw-r--r-- | src/os/win32/ngx_os.h | 2 | ||||
-rw-r--r-- | src/os/win32/ngx_process.h | 1 | ||||
-rw-r--r-- | src/os/win32/ngx_process_cycle.c | 207 | ||||
-rw-r--r-- | src/os/win32/ngx_socket.h | 8 | ||||
-rw-r--r-- | src/os/win32/ngx_thread.c | 68 | ||||
-rw-r--r-- | src/os/win32/ngx_thread.h | 39 | ||||
-rw-r--r-- | src/os/win32/ngx_win32_config.h | 15 | ||||
-rw-r--r-- | src/os/win32/ngx_win32_init.c | 102 | ||||
-rw-r--r-- | src/os/win32/ngx_wsarecv.c | 105 | ||||
-rw-r--r-- | src/os/win32/ngx_wsasend_chain.c | 203 | ||||
-rw-r--r-- | src/os/win32/tray.ico | bin | 0 -> 198 bytes |
20 files changed, 750 insertions, 287 deletions
diff --git a/src/os/win32/nginx.ico b/src/os/win32/nginx.ico Binary files differnew file mode 100644 index 000000000..6fb330b51 --- /dev/null +++ b/src/os/win32/nginx.ico diff --git a/src/os/win32/nginx.rc b/src/os/win32/nginx.rc new file mode 100644 index 000000000..7a2e24133 --- /dev/null +++ b/src/os/win32/nginx.rc @@ -0,0 +1,16 @@ + +// Copyright (C) Igor Sysoev + +#include <ngx_gui.h> + +nginx icon discardable "src\\os\\win32\\nginx.ico" +tray icon discardable "src\\os\\win32\\tray.ico" + +nginx menu discardable +begin + popup "&nginx" + begin + menuitem "&Exit", NGX_WM_EXIT + menuitem "&About", NGX_WM_ABOUT + end +end diff --git a/src/os/win32/ngx_alloc.c b/src/os/win32/ngx_alloc.c index ea36cad57..e73aa32af 100644 --- a/src/os/win32/ngx_alloc.c +++ b/src/os/win32/ngx_alloc.c @@ -17,11 +17,10 @@ void *ngx_alloc(size_t size, ngx_log_t *log) if (!(p = malloc(size))) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, - "malloc() " SIZE_T_FMT " bytes failed", size); + "malloc() %uz bytes failed", size); } - ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, - "malloc: " PTR_FMT ":" SIZE_T_FMT, p, size); + ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "malloc: %p:%uz", p, size); return p; } diff --git a/src/os/win32/ngx_atomic.h b/src/os/win32/ngx_atomic.h index 3ef150996..b4915d0a2 100644 --- a/src/os/win32/ngx_atomic.h +++ b/src/os/win32/ngx_atomic.h @@ -18,7 +18,7 @@ #define ngx_atomic_inc(p) InterlockedIncrement((long *) p) -#if defined( __WATCOMC__ ) || defined( __BORLANDC__ ) +#if defined( __WATCOMC__ ) || defined( __BORLANDC__ ) || ( _MSC_VER >= 1300 ) /* the new SDK headers */ diff --git a/src/os/win32/ngx_errno.c b/src/os/win32/ngx_errno.c index 6f8d2da5b..8e9280d92 100644 --- a/src/os/win32/ngx_errno.c +++ b/src/os/win32/ngx_errno.c @@ -15,64 +15,101 @@ static 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 */ - ngx_null_string, /* 10036 */ - ngx_null_string, /* 10037 */ - ngx_null_string, /* 10038 */ - ngx_null_string, /* 10039 */ - ngx_null_string, /* 10040 */ - ngx_null_string, /* 10041 */ - ngx_null_string, /* 10042 */ - ngx_null_string, /* 10043 */ - ngx_null_string, /* 10044 */ - ngx_null_string, /* 10045 */ - ngx_null_string, /* 10046 */ - ngx_null_string, /* 10047 */ - ngx_null_string, /* 10048 */ - ngx_null_string, /* 10049 */ - ngx_null_string, /* 10050 */ - ngx_null_string, /* 10051 */ - ngx_null_string, /* 10052 */ - ngx_null_string, /* 10053 */ - ngx_null_string, /* 10054 */ - ngx_null_string, /* 10055 */ - ngx_null_string, /* 10056 */ - ngx_string("Socket is not connected") /* 10057 */ + ngx_string("An invalid argument was supplied"), /* WSAEINVAL 10022 */ + ngx_string("Too many open sockets"), /* WSAEMFILE 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 */ + + /* WSAEWOULDBLOCK 10035 */ + ngx_string("A non-blocking socket operation could not be completed " + "immediately"), + + ngx_null_string, /* 10036 */ + ngx_null_string, /* 10037 */ + + /* WSAENOTSOCK 10038 */ + ngx_string("An operation was attempted on something that is not a socket"), + + ngx_null_string, /* 10039 */ + ngx_null_string, /* 10040 */ + ngx_null_string, /* 10041 */ + ngx_null_string, /* 10042 */ + ngx_null_string, /* 10043 */ + ngx_null_string, /* 10044 */ + ngx_null_string, /* 10045 */ + ngx_null_string, /* 10046 */ + ngx_null_string, /* 10047 */ + ngx_null_string, /* 10048 */ + ngx_null_string, /* 10049 */ + ngx_null_string, /* 10050 */ + ngx_null_string, /* 10051 */ + ngx_null_string, /* 10052 */ + ngx_null_string, /* 10053 */ + + /* WSAECONNRESET 10054 */ + ngx_string("An existing connection was forcibly closed by the remote host"), + + /* WSAENOBUFS 10055 */ + ngx_string("An operation on a socket could not be performed because " + "the system lacked sufficient buffer space or " + "because a queue was full"), + + /* WSAEISCONN 10056 */ + ngx_string("A connect request was made on an already connected socket"), + + /* WSAENOTCONN 10057 */ + ngx_string("A request to send or receive data was disallowed because" + "the socket is not connected and (when sending on a datagram " + "socket using a sendto call) no address was supplied"), + + ngx_null_string, /* 10058 */ + ngx_null_string, /* 10059 */ + + /* WSAETIMEDOUT 10060 */ + ngx_string("A connection attempt failed because the connected party " + "did not properly respond after a period of time, " + "or established connection failed because connected host " + "has failed to respond"), + + /* WSAECONNREFUSED 10061 */ + ngx_string("No connection could be made because the target machine " + "actively refused it") }; -int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size) +u_char *ngx_strerror_r(ngx_err_t err, u_char *errstr, size_t size) { int n; u_int len; ngx_err_t format_error; + if (size == 0) { + return errstr; + } + len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - errstr, size, NULL); + (char *) errstr, size, NULL); if (len == 0) { format_error = GetLastError(); if (format_error == ERROR_MR_MID_NOT_FOUND) { - n = err - WSABASEERR - 22; + n = err - WSAEINVAL; - if (n >= 0 && n <= 35) { + if (n >= 0 && n <= WSAECONNREFUSED - WSAEINVAL) { len = wsa_errors[n].len; if (len) { @@ -81,21 +118,22 @@ int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size) } ngx_memcpy(errstr, wsa_errors[n].data, len); - return len; + + return errstr + len; } } } - len = ngx_snprintf(errstr, size, - "FormatMessage() error:(%d)", format_error); - return len; - + return ngx_snprintf(errstr, size, + "FormatMessage() error:(%d)", format_error); } /* remove ".\r\n\0" */ while (errstr[len] == '\0' || errstr[len] == CR || errstr[len] == LF || errstr[len] == '.') + { --len; + } - return ++len; + return &errstr[++len]; } diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h index f60ea74e1..863dce879 100644 --- a/src/os/win32/ngx_errno.h +++ b/src/os/win32/ngx_errno.h @@ -38,7 +38,7 @@ typedef DWORD ngx_err_t; #define NGX_EALREADY WSAEALREADY #define NGX_EINVAL WSAEINVAL -int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size); +u_char *ngx_strerror_r(ngx_err_t err, u_char *errstr, size_t size); #endif /* _NGX_ERRNO_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c index dea310698..ffd52c9bd 100644 --- a/src/os/win32/ngx_files.c +++ b/src/os/win32/ngx_files.c @@ -18,19 +18,20 @@ ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) if (ngx_win32_version < NGX_WIN_NT) { /* - * in Win9X the overlapped pointer must be NULL - * so we need to use SetFilePointer() to set the offset + * under Win9X the overlapped pointer must be NULL + * so we have to use SetFilePointer() to set the offset */ if (file->offset != offset) { /* - * the maximum file size on FAT16 is 2G, but on FAT32 - * the size is 4G so we need to use high_offset + * the maximum file size on the FAT16 is 2G, but on the FAT32 + * the size is 4G so we have to use the high_offset * because a single offset is signed value */ high_offset = (long) (offset >> 32); + if (SetFilePointer(file->fd, (long) offset, &high_offset, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { @@ -81,15 +82,15 @@ ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) if (ngx_win32_version < NGX_WIN_NT) { /* - * in Win9X the overlapped pointer must be NULL - * so we need to use SetFilePointer() to set the offset + * under Win9X the overlapped pointer must be NULL + * so we have to use SetFilePointer() to set the offset */ if (file->offset != offset) { /* - * the maximum file size on FAT16 is 2G, but on FAT32 - * the size is 4G so we need to use high_offset + * the maximum file size on the FAT16 is 2G, but on the FAT32 + * the size is 4G so we have to use high_offset * because a single offset is signed value */ @@ -189,8 +190,7 @@ int ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool) do { num = ngx_next_temp_number(collision); - ngx_snprintf((char *) name + to->len, 1 + 10 + 1 + sizeof("DELETE"), - ".%010u.DELETE", num); + ngx_sprintf(name + to->len, ".%010u.DELETE", num); if (MoveFile((const char *) to->data, (const char *) name) == 0) { collision = 1; diff --git a/src/os/win32/ngx_gui.c b/src/os/win32/ngx_gui.c new file mode 100644 index 000000000..5673820d2 --- /dev/null +++ b/src/os/win32/ngx_gui.c @@ -0,0 +1,85 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +#define NGX_MAX_TEXT 2048 + + +void ngx_message_box(char *title, ngx_uint_t type, ngx_err_t err, + const char *fmt, ...) +{ + va_list args; + u_char text[NGX_MAX_TEXT], *p, *last; + + last = text + NGX_MAX_TEXT; + + va_start(args, fmt); + p = ngx_vsnprintf(text, NGX_MAX_TEXT, fmt, args); + va_end(args); + + if (err) { + + if (p > last - 50) { + + /* leave a space for an error code */ + + p = last - 50; + *p++ = '.'; + *p++ = '.'; + *p++ = '.'; + } + + if ((unsigned) err >= 0x80000000) { + p = ngx_snprintf(p, last - p, " (%Xd: ", err); + + } else { + p = ngx_snprintf(p, last - p, " (%d: ", err); + } + + p = ngx_strerror_r(err, p, last - p); + + if (p < last) { + *p++ = ')'; + } + } + + if (p == last) { + p--; + } + + *p = '\0'; + + MessageBox(NULL, (char *) text, title, type); +} + + +ngx_int_t ngx_system_tray_icon(HWND window, u_long action, + HICON icon, u_char *tip) +{ + NOTIFYICONDATA ni; + + ni.cbSize = sizeof(NOTIFYICONDATA); + ni.hWnd = window; + ni.uID = 0; + ni.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; + ni.uCallbackMessage = NGX_WM_TRAY; + ni.hIcon = icon; + + if (tip) { + ngx_cpystrn((u_char *) ni.szTip, tip, 64); + } else { + ni.szTip[0] = '\0'; + } + + if (Shell_NotifyIcon(action, &ni) == 0) { + return NGX_ERROR; + } + + return NGX_OK; +} diff --git a/src/os/win32/ngx_gui.h b/src/os/win32/ngx_gui.h new file mode 100644 index 000000000..1c2fd9b43 --- /dev/null +++ b/src/os/win32/ngx_gui.h @@ -0,0 +1,27 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#ifndef _NGX_GUI_H_INCLUDED_ +#define _NGX_GUI_H_INCLUDED_ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +#define NGX_WM_TRAY WM_USER +#define NGX_WM_EXIT WM_USER + 1 +#define NGX_WM_ABOUT WM_USER + 2 + + +void ngx_message_box(char *title, ngx_uint_t type, ngx_err_t err, + const char *fmt, ...); + +ngx_int_t ngx_system_tray_icon(HWND window, u_long action, + HICON icon, u_char *tip); + + +#endif /* _NGX_GUI_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_os.h b/src/os/win32/ngx_os.h index 98c8e15c2..c27f8a80a 100644 --- a/src/os/win32/ngx_os.h +++ b/src/os/win32/ngx_os.h @@ -10,6 +10,7 @@ #include <ngx_config.h> #include <ngx_core.h> +#include <ngx_gui.h> #define NGX_IO_SENDFILE 1 #define NGX_IO_ZEROCOPY 2 @@ -56,6 +57,7 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, extern ngx_os_io_t ngx_os_io; extern ngx_uint_t ngx_ncpu; +extern ngx_uint_t ngx_max_wsabufs; extern ngx_int_t ngx_max_sockets; extern ngx_uint_t ngx_inherited_nonblocking; extern ngx_uint_t ngx_win32_version; diff --git a/src/os/win32/ngx_process.h b/src/os/win32/ngx_process.h index b9b4aeb80..a282d17ad 100644 --- a/src/os/win32/ngx_process.h +++ b/src/os/win32/ngx_process.h @@ -29,6 +29,7 @@ typedef struct { ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx); +#define ngx_debug_point() #define ngx_sched_yield() Sleep(0) diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c index 843c3111e..e0635a5eb 100644 --- a/src/os/win32/ngx_process_cycle.c +++ b/src/os/win32/ngx_process_cycle.c @@ -7,8 +7,13 @@ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> +#include <nginx.h> +static void *ngx_worker_thread_cycle(void *data); +static long __stdcall ngx_window_procedure(HWND window, u_int message, + u_int wparam, long lparam); + #if 0 ngx_pid_t ngx_new_binary; @@ -37,6 +42,8 @@ sig_atomic_t ngx_change_binary; #endif +static HMENU ngx_menu; + void ngx_master_process_cycle(ngx_cycle_t *cycle) { @@ -48,7 +55,17 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle) void ngx_single_process_cycle(ngx_cycle_t *cycle) { - ngx_int_t i; + int rc; + ngx_int_t i; + ngx_err_t err; + ngx_tid_t tid; + MSG message; + HWND window; + HMENU menu; + HICON icon,tray; + WNDCLASS wc; + HINSTANCE instance; + ngx_core_conf_t *ccf; ngx_init_temp_number(); @@ -61,9 +78,197 @@ void ngx_single_process_cycle(ngx_cycle_t *cycle) } } + + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + if (ngx_init_threads(ngx_threads_n, + ccf->thread_stack_size, cycle) == NGX_ERROR) + { + /* fatal */ + exit(2); + } + + err = ngx_thread_key_create(&ngx_core_tls_key); + if (err != 0) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, err, + ngx_thread_key_create_n " failed"); + /* fatal */ + exit(2); + } + + + instance = GetModuleHandle(NULL); + + icon = LoadIcon(instance, "nginx"); + if (icon == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "LoadIcon(\"nginx\") failed"); + /* fatal */ + exit(2); + } + + tray = LoadIcon(instance, "tray"); + if (icon == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "LoadIcon(\"tray\") failed"); + /* fatal */ + exit(2); + } + + menu = LoadMenu(instance, "nginx"); + if (menu == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "LoadMenu() failed"); + /* fatal */ + exit(2); + } + + ngx_menu = GetSubMenu(menu, 0); + if (ngx_menu == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "GetSubMenu() failed"); + /* fatal */ + exit(2); + } + + + wc.style = CS_HREDRAW|CS_VREDRAW; + wc.lpfnWndProc = ngx_window_procedure; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = instance; + wc.hIcon = icon; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "nginx"; + + if (RegisterClass(&wc) == 0) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "RegisterClass() failed"); + /* fatal */ + exit(2); + } + + + window = CreateWindow("nginx", "nginx", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, instance, NULL); + + if (window == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "CreateWindow() failed"); + /* fatal */ + exit(2); + } + + + if (ngx_system_tray_icon(window, NIM_ADD, tray, (u_char *) " nginx") + == NGX_ERROR) + { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "Shell_NotifyIcon(NIM_ADD) failed"); + /* fatal */ + exit(2); + } + + + if (ngx_create_thread(&tid, ngx_worker_thread_cycle, NULL, cycle->log) != 0) + { + /* fatal */ + exit(2); + } + + + for ( ;; ) { + rc = GetMessage(&message, NULL, 0, 0); + + if (rc == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "GetMessage() failed"); + continue; + } + + if (rc == 0) { + exit(0); + } + + TranslateMessage(&message); + DispatchMessage(&message); + } +} + + +static void *ngx_worker_thread_cycle(void *data) +{ + ngx_cycle_t *cycle; + + cycle = (ngx_cycle_t *) ngx_cycle; + for ( ;; ) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); ngx_process_events(cycle); } + + return NULL; +} + + +static long __stdcall ngx_window_procedure(HWND window, u_int message, + u_int wparam, long lparam) +{ + POINT mouse; + + switch (message) { + + case NGX_WM_TRAY: + if (lparam == WM_RBUTTONDOWN) { + if (GetCursorPos(&mouse) == 0) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "GetCursorPos() failed"); + return 0; + } + + if (SetForegroundWindow(window) == 0) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "SetForegroundWindow() failed"); + return 0; + } + + if (TrackPopupMenu(ngx_menu, TPM_RIGHTBUTTON, + mouse.x, mouse.y, 0, window, NULL) == 0) + { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "TrackPopupMenu() failed"); + return 0; + } + } + + return 0; + + case WM_COMMAND: + if (wparam == NGX_WM_ABOUT) { + ngx_message_box("nginx", MB_OK, 0, + NGINX_VER CRLF "(C) 2002-2004 Igor Sysoev"); + return 0; + } + + if (wparam == NGX_WM_EXIT) { + if (ngx_system_tray_icon(window, NIM_DELETE, NULL, NULL) + == NGX_ERROR) + { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, + "Shell_NotifyIcon(NIM_DELETE) failed"); + } + } + + PostQuitMessage(0); + + return 0; + + default: + return DefWindowProc(window, message, wparam, lparam); + } } diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h index 4ce60a7f3..d49ad2c15 100644 --- a/src/os/win32/ngx_socket.h +++ b/src/os/win32/ngx_socket.h @@ -19,12 +19,8 @@ typedef SOCKET ngx_socket_t; typedef int socklen_t; -#define ngx_socket(af, type, proto, flags) socket(af, type, proto) - -#if 0 -#define ngx_socket(af, type, proto, flags) \ - WSASocket(af, type, proto, NULL, 0, flags) -#endif +#define ngx_socket(af, type, proto) \ + WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED) #define ngx_socket_n "WSASocket()" diff --git a/src/os/win32/ngx_thread.c b/src/os/win32/ngx_thread.c new file mode 100644 index 000000000..8fae0e379 --- /dev/null +++ b/src/os/win32/ngx_thread.c @@ -0,0 +1,68 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +ngx_int_t ngx_threads_n; + + +static size_t stack_size; + + +ngx_err_t ngx_create_thread(ngx_tid_t *tid, void* (*func)(void *arg), void *arg, + ngx_log_t *log) +{ + ngx_err_t err; + + *tid = CreateThread(NULL, stack_size, + (LPTHREAD_START_ROUTINE) func, arg, 0, NULL); + + if (*tid != NULL) { + return 0; + } + + err = ngx_errno; + ngx_log_error(NGX_LOG_ALERT, log, err, "CreateThread() failed"); + return err; +} + + +ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle) +{ + stack_size = size; + + return NGX_OK; +} + + +ngx_err_t ngx_thread_key_create(ngx_tls_key_t *key) +{ + *key = TlsAlloc(); + + if (*key == TLS_OUT_OF_INDEXES) { + return ngx_errno; + } + + return 0; +} + + +ngx_err_t ngx_thread_set_tls(ngx_tls_key_t *key, void *data) +{ + if (TlsSetValue(*key, data) == 0) { + return ngx_errno; + } + + return 0; +} + + +ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags) +{ + return (ngx_mutex_t *) 1; +} diff --git a/src/os/win32/ngx_thread.h b/src/os/win32/ngx_thread.h index b3b6e67cd..5b3c4da98 100644 --- a/src/os/win32/ngx_thread.h +++ b/src/os/win32/ngx_thread.h @@ -12,21 +12,46 @@ #include <ngx_core.h> -#if (NGX_THREADS) +typedef HANDLE ngx_tid_t; +typedef DWORD ngx_tls_key_t; + + +typedef struct { + HANDLE mutex; + ngx_log_t *log; +} ngx_mutex_t; + + +ngx_err_t ngx_create_thread(ngx_tid_t *tid, void* (*func)(void *arg), void *arg, + ngx_log_t *log); +ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle); + +ngx_err_t ngx_thread_key_create(ngx_tls_key_t *key); +#define ngx_thread_key_create_n "TlsAlloc()" +ngx_err_t ngx_thread_set_tls(ngx_tls_key_t *key, void *data); +#define ngx_thread_set_tls_n "TlsSetValue()" +#define ngx_thread_get_tls TlsGetValue + #define ngx_thread_volatile volatile -#else /* !NGX_THREADS */ +#define ngx_log_tid GetCurrentThreadId() +#define NGX_TID_T_FMT "%ud" + -#define ngx_thread_volatile +ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags); -#define ngx_log_tid 0 -#define TID_T_FMT "%d" -#define ngx_mutex_lock(m) NGX_OK +/* STUB */ +#define NGX_MUTEX_LIGHT 0 + +#define ngx_mutex_lock(m) NGX_OK +#define ngx_mutex_trylock(m) NGX_OK #define ngx_mutex_unlock(m) +/* */ + -#endif +extern ngx_int_t ngx_threads_n; #endif /* _NGX_THREAD_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h index a6c336d7a..e7d3086e8 100644 --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -8,8 +8,6 @@ #define _NGX_WIN32_CONFIG_H_INCLUDED_ -#define WIN32 1 - #define STRICT #define WIN32_LEAN_AND_MEAN @@ -25,6 +23,7 @@ #include <winsock2.h> #include <mswsock.h> +#include <shellapi.h> #include <stddef.h> /* offsetof() */ #include <stdio.h> #include <stdlib.h> @@ -96,8 +95,10 @@ #ifdef _MSC_VER typedef unsigned __int32 uint32_t; +typedef __int32 int32_t; #else /* __WATCOMC__ */ typedef unsigned int uint32_t; +typedef int int32_t; #endif typedef __int64 int64_t; @@ -115,17 +116,13 @@ typedef uint32_t ngx_atomic_t; #define TIME_T_LEN sizeof("-2147483648") - 1 -#define OFF_T_FMT "%I64d" -#define SIZE_T_FMT "%d" -#define SIZE_T_X_FMT "%x" -#define PID_T_FMT "%d" -#define TIME_T_FMT "%lu" -#define PTR_FMT "%08X" - #define NGX_WIN_NT 200000 +#define NGX_THREADS 1 + + #ifndef HAVE_INHERITED_NONBLOCK #define HAVE_INHERITED_NONBLOCK 1 #endif diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c index ea1cfd1b5..cb8c93128 100644 --- a/src/os/win32/ngx_win32_init.c +++ b/src/os/win32/ngx_win32_init.c @@ -10,6 +10,7 @@ ngx_uint_t ngx_win32_version; ngx_uint_t ngx_ncpu; +ngx_uint_t ngx_max_wsabufs; ngx_int_t ngx_max_sockets; ngx_uint_t ngx_inherited_nonblocking = 1; ngx_fd_t ngx_stderr_fileno; @@ -31,6 +32,9 @@ typedef struct { } ngx_osviex_stub_t; +static u_int osviex; +static OSVERSIONINFOEX osvi; + /* Should these pointers be per protocol ? */ LPFN_ACCEPTEX acceptex; LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs; @@ -43,13 +47,10 @@ static GUID tf_guid = WSAID_TRANSMITFILE; ngx_int_t ngx_os_init(ngx_log_t *log) { - u_int osviex; - DWORD bytes; - SOCKET s; - WSADATA wsd; - SYSTEM_INFO si; - OSVERSIONINFOEX osvi; - ngx_osviex_stub_t *osviex_stub; + DWORD bytes; + SOCKET s; + WSADATA wsd; + SYSTEM_INFO si; /* get Windows version */ @@ -90,43 +91,6 @@ ngx_int_t ngx_os_init(ngx_log_t *log) if (osviex) { ngx_win32_version += osvi.wServicePackMajor * 10 + osvi.wServicePackMinor; - - /* - * the MSVC 6.0 SP2 defines wSuiteMask and wProductType - * as WORD wReserved[2] - */ - osviex_stub = (ngx_osviex_stub_t *) &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, - osviex_stub->wSuiteMask, osviex_stub->wProductType); - - } else { - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { - - /* Win9x build */ - - ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %u build:%u.%u.%u, \"%s\"", - ngx_win32_version, - osvi.dwBuildNumber >> 24, - (osvi.dwBuildNumber >> 16) & 0xff, - osvi.dwBuildNumber & 0xffff, - osvi.szCSDVersion); - - } else { - - /* - * VER_PLATFORM_WIN32_NT - * - * we do not currently support VER_PLATFORM_WIN32_CE - * and we do not support VER_PLATFORM_WIN32s at all - */ - - ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %u build:%u, \"%s\"", - ngx_win32_version, osvi.dwBuildNumber, - osvi.szCSDVersion); - } } GetSystemInfo(&si); @@ -143,15 +107,19 @@ ngx_int_t ngx_os_init(ngx_log_t *log) } if (ngx_win32_version < NGX_WIN_NT) { + ngx_max_wsabufs = 16; return NGX_OK; } + /* STUB: ngx_uint_t max */ + ngx_max_wsabufs = 1024 * 1024; + /* get AcceptEx(), GetAcceptExSockAddrs() and TransmitFile() addresses */ - s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0); + s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (s == -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, - ngx_socket_n " %s falied"); + ngx_socket_n " falied"); return NGX_ERROR; } @@ -194,4 +162,46 @@ ngx_int_t ngx_os_init(ngx_log_t *log) void ngx_os_status(ngx_log_t *log) { + ngx_osviex_stub_t *osviex_stub; + + if (osviex) { + + /* + * the MSVC 6.0 SP2 defines wSuiteMask and wProductType + * as WORD wReserved[2] + */ + osviex_stub = (ngx_osviex_stub_t *) &osvi.wServicePackMinor; + + ngx_log_error(NGX_LOG_INFO, log, 0, + "OS: %ud build:%ud, \"%s\", suite:%Xd, type:%ud", + ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion, + osviex_stub->wSuiteMask, osviex_stub->wProductType); + + } else { + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + + /* Win9x build */ + + ngx_log_error(NGX_LOG_INFO, log, 0, + "OS: %u build:%ud.%ud.%ud, \"%s\"", + ngx_win32_version, + osvi.dwBuildNumber >> 24, + (osvi.dwBuildNumber >> 16) & 0xff, + osvi.dwBuildNumber & 0xffff, + osvi.szCSDVersion); + + } else { + + /* + * VER_PLATFORM_WIN32_NT + * + * we do not currently support VER_PLATFORM_WIN32_CE + * and we do not support VER_PLATFORM_WIN32s at all + */ + + ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %ud build:%ud, \"%s\"", + ngx_win32_version, osvi.dwBuildNumber, + osvi.szCSDVersion); + } + } } diff --git a/src/os/win32/ngx_wsarecv.c b/src/os/win32/ngx_wsarecv.c index bb0e5566c..ac7a5c4c9 100644 --- a/src/os/win32/ngx_wsarecv.c +++ b/src/os/win32/ngx_wsarecv.c @@ -25,7 +25,7 @@ ssize_t ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size) rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL); ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "WSARecv: fd:%d rc:%d %d of %d", c->fd, rc, bytes, size); + "WSARecv: fd:%d rc:%d %ul of %z", c->fd, rc, bytes, size); rev = c->read; @@ -85,6 +85,10 @@ ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size) return NGX_ERROR; } + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "WSARecv ovlp: fd:%d %ul of %z", + c->fd, rev->available, size); + return rev->available; } @@ -95,6 +99,9 @@ ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size) return NGX_ERROR; } + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "WSARecv: fd:%d %ul of %z", c->fd, bytes, size); + return bytes; } @@ -110,12 +117,15 @@ ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size) rev->complete = 0; ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "WSARecv: fd:%d rc:%d %d of %d", c->fd, rc, bytes, size); + "WSARecv ovlp: fd:%d rc:%d %ul of %z", + c->fd, rc, bytes, size); if (rc == -1) { err = ngx_socket_errno; if (err == WSA_IO_PENDING) { rev->active = 1; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "WSARecv() posted"); return NGX_AGAIN; } @@ -148,94 +158,3 @@ ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size) 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; - 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_USE_AIO_EVENT) && rev->ready) { - rev->ready = 0; - - /* the overlapped WSARecv() completed */ - - 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) { - 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_USE_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_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 completed. - */ - - return NGX_AGAIN; - } - - return bytes; -} - -#endif diff --git a/src/os/win32/ngx_wsasend_chain.c b/src/os/win32/ngx_wsasend_chain.c index 08f93c80b..1d75e0969 100644 --- a/src/os/win32/ngx_wsasend_chain.c +++ b/src/os/win32/ngx_wsasend_chain.c @@ -9,17 +9,21 @@ #include <ngx_event.h> +#define NGX_WSABUFS 8 + + ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { int rc; u_char *prev; - size_t size; - u_long sent; - LPWSABUF wsabuf; + u_long size, sent, send, sprev; + ngx_uint_t complete; ngx_err_t err; ngx_event_t *wev; - ngx_array_t wsabufs; + ngx_array_t vec; + LPWSABUF wsabuf; + WSABUF wsabufs[NGX_WSABUFS]; ngx_chain_t *cl; wev = c->write; @@ -28,80 +32,119 @@ ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, return in; } + send = 0; + complete = 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); + vec.elts = wsabufs; + vec.size = sizeof(WSABUF); + vec.nalloc = NGX_WSABUFS; + vec.pool = c->pool; - prev = NULL; - wsabuf = NULL; + for ( ;; ) { + prev = NULL; + wsabuf = NULL; + sprev = send; - /* create the WSABUF and coalesce the neighbouring bufs */ + vec.nelts = 0; - for (cl = in; cl; cl = cl->next) { + /* create the WSABUF and coalesce the neighbouring bufs */ - if (prev == cl->buf->pos) { - wsabuf->len += cl->buf->last - cl->buf->pos; - prev = cl->buf->last; + for (cl = in; + cl && vec.nelts < ngx_max_wsabufs && send < limit; + cl = cl->next) + { + if (ngx_buf_special(cl->buf)) { + continue; + } + + size = cl->buf->last - cl->buf->pos; + + if (send + size > limit) { + size = (u_long) (limit - send); + } + + if (prev == cl->buf->pos) { + wsabuf->len += cl->buf->last - cl->buf->pos; + + } else { + if (!(wsabuf = ngx_array_push(&vec))) { + return NGX_CHAIN_ERROR; + } + + wsabuf->buf = (char *) cl->buf->pos; + wsabuf->len = cl->buf->last - cl->buf->pos; + } - } else { - ngx_test_null(wsabuf, ngx_push_array(&wsabufs), NGX_CHAIN_ERROR); - wsabuf->buf = (char *) cl->buf->pos; - wsabuf->len = cl->buf->last - cl->buf->pos; prev = cl->buf->last; + send += size; } - } - rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, NULL, NULL); + sent = 0; - if (rc == -1) { - err = ngx_errno; + rc = WSASend(c->fd, vec.elts, vec.nelts, &sent, 0, NULL, NULL); - if (err == WSAEWOULDBLOCK) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, - "WSASend() not ready"); - wev->ready = 0; - return in; + if (rc == -1) { + err = ngx_errno; - } else { - wev->error = 1; - ngx_connection_error(c, err, "WSASend() failed"); - return NGX_CHAIN_ERROR; + if (err == WSAEWOULDBLOCK) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "WSASend() not ready"); + + } else { + wev->error = 1; + ngx_connection_error(c, err, "WSASend() failed"); + return NGX_CHAIN_ERROR; + } } - } - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "WSASend: %d", sent); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "WSASend: fd:%d, s:%ul", c->fd, sent); - c->sent += sent; + if (send - sprev == sent) { + complete = 1; + } - for (cl = in; cl && sent > 0; cl = cl->next) { + c->sent += sent; - size = cl->buf->last - cl->buf->pos; + for (cl = in; cl && sent > 0; cl = cl->next) { + if (ngx_buf_special(cl->buf)) { + continue; + } - if (sent >= size) { - sent -= size; + if (sent == 0) { + break; + } - if (ngx_buf_in_memory(cl->buf)) { + size = cl->buf->last - cl->buf->pos; + + if (sent >= size) { + sent -= size; cl->buf->pos = cl->buf->last; + + continue; } - continue; + cl->buf->pos += sent; + + break; } - if (ngx_buf_in_memory(cl->buf)) { - cl->buf->pos += sent; + if (!complete) { + wev->ready = 0; + return cl; } - break; - } + if (send >= limit || cl == NULL) { + return cl; + } - if (cl) { - wev->ready = 0; + in = cl; } - - return cl; } @@ -111,13 +154,14 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, int rc; u_char *prev; size_t size; - u_long sent; + u_long send, sent; LPWSABUF wsabuf; ngx_err_t err; ngx_event_t *wev; - ngx_array_t wsabufs; + ngx_array_t vec; ngx_chain_t *cl; LPWSAOVERLAPPED ovlp; + WSABUF wsabufs[NGX_WSABUFS]; wev = c->write; @@ -125,6 +169,9 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, return in; } + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "wev->complete: %d", wev->complete); + if (!wev->complete) { /* post the overlapped WSASend() */ @@ -134,32 +181,52 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, * WSASend() will return undocumented WSAEINVAL error. */ - ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR); + vec.elts = wsabufs; + vec.nelts = 0; + vec.size = sizeof(WSABUF); + vec.nalloc = NGX_WSABUFS; + vec.pool = c->pool; + send = 0; prev = NULL; wsabuf = NULL; /* create the WSABUF and coalesce the neighbouring bufs */ - for (cl = in; cl; cl = cl->next) { + for (cl = in; + cl && vec.nelts < ngx_max_wsabufs && send < limit; + cl = cl->next) + { + if (ngx_buf_special(cl->buf)) { + continue; + } + + size = cl->buf->last - cl->buf->pos; + + if (send + size > limit) { + size = (u_long) (limit - send); + } if (prev == cl->buf->pos) { wsabuf->len += cl->buf->last - cl->buf->pos; - prev = cl->buf->last; - + } else { - ngx_test_null(wsabuf, ngx_push_array(&wsabufs), - NGX_CHAIN_ERROR); + if (!(wsabuf = ngx_array_push(&vec))) { + return NGX_CHAIN_ERROR; + } + wsabuf->buf = (char *) cl->buf->pos; wsabuf->len = cl->buf->last - cl->buf->pos; - prev = cl->buf->last; } + + prev = cl->buf->last; + send += size; } ovlp = (LPWSAOVERLAPPED) &c->write->ovlp; ngx_memzero(ovlp, sizeof(WSAOVERLAPPED)); - rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL); + rc = WSASend(c->fd, vec.elts, vec.nelts, &sent, 0, ovlp, NULL); wev->complete = 0; @@ -167,6 +234,8 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, err = ngx_errno; if (err == WSA_IO_PENDING) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "WSASend() posted"); wev->active = 1; return in; @@ -188,6 +257,9 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, return in; } + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "WSASend: fd:%d, s:%ul", c->fd, sent); + } else { /* the overlapped WSASend() complete */ @@ -214,27 +286,30 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, } } - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "WSASend: %d", sent); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "WSASend ovlp: fd:%d, s:%ul", c->fd, sent); c->sent += sent; for (cl = in; cl && sent > 0; cl = cl->next) { + if (ngx_buf_special(cl->buf)) { + continue; + } + + if (sent == 0) { + break; + } size = cl->buf->last - cl->buf->pos; if (sent >= size) { sent -= size; - - if (ngx_buf_in_memory(cl->buf)) { - cl->buf->pos = cl->buf->last; - } + cl->buf->pos = cl->buf->last; continue; } - if (ngx_buf_in_memory(cl->buf)) { - cl->buf->pos += sent; - } + cl->buf->pos += sent; break; } diff --git a/src/os/win32/tray.ico b/src/os/win32/tray.ico Binary files differnew file mode 100644 index 000000000..077cbac27 --- /dev/null +++ b/src/os/win32/tray.ico |