Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-04-20 10:08:47 +0400
committerIgor Sysoev <igor@sysoev.ru>2009-04-20 10:08:47 +0400
commitbd91999ea577266b0d899ea206cdaa8d19f486b2 (patch)
tree6936e209210662a34db4f9b9c63d03b95e7d9956
parentb533e9825295a0855d78912dae9d8f1180df0900 (diff)
Win32 master/workers model
-rw-r--r--auto/cc/bcc2
-rw-r--r--auto/cc/msvc7
-rw-r--r--auto/cc/owc2
-rw-r--r--auto/sources7
-rw-r--r--misc/GNUmakefile65
-rw-r--r--src/core/nginx.c100
-rw-r--r--src/core/ngx_connection.c32
-rw-r--r--src/core/ngx_cycle.c12
-rw-r--r--src/core/ngx_log.c6
-rw-r--r--src/event/ngx_event.c2
-rw-r--r--src/os/win32/nginx.rc11
-rw-r--r--src/os/win32/nginx_tray.icobin198 -> 0 bytes
-rw-r--r--src/os/win32/nginx_tray.xpm24
-rw-r--r--src/os/win32/ngx_event_log.c116
-rw-r--r--src/os/win32/ngx_gui.c81
-rw-r--r--src/os/win32/ngx_gui.h23
-rw-r--r--src/os/win32/ngx_gui_resources.h19
-rw-r--r--src/os/win32/ngx_os.h7
-rw-r--r--src/os/win32/ngx_process.c210
-rw-r--r--src/os/win32/ngx_process.h65
-rw-r--r--src/os/win32/ngx_process_cycle.c1133
-rw-r--r--src/os/win32/ngx_process_cycle.h23
-rw-r--r--src/os/win32/ngx_thread.c5
-rw-r--r--src/os/win32/ngx_win32_init.c12
-rw-r--r--src/os/win32/ngx_wsasend.c183
25 files changed, 1695 insertions, 452 deletions
diff --git a/auto/cc/bcc b/auto/cc/bcc
index 638b7dc2f..9570a3c47 100644
--- a/auto/cc/bcc
+++ b/auto/cc/bcc
@@ -46,7 +46,7 @@ NGX_USE_PCH="-Hu -H=$NGX_OBJS/ngx_config.csm"
# Win32 GUI mode application
-LINK="\$(CC) -laa"
+#LINK="\$(CC) -laa"
# the resource file
diff --git a/auto/cc/msvc b/auto/cc/msvc
index 4a053283f..d002bec38 100644
--- a/auto/cc/msvc
+++ b/auto/cc/msvc
@@ -86,11 +86,14 @@ LIBC="-MT"
CFLAGS="$CFLAGS $LIBC"
-# Win32 GUI mode application
CORE_LIBS="$CORE_LIBS kernel32.lib user32.lib"
-CORE_LINK="$CORE_LINK -subsystem:windows -entry:mainCRTStartup"
+
+# Win32 GUI mode application
+#CORE_LINK="$CORE_LINK -subsystem:windows -entry:mainCRTStartup"
# debug
+# msvc8 under Wine issues
+# Program database manager mismatch; please check your installation
if [ $NGX_CC_NAME != msvc8 ]; then
CFLAGS="$CFLAGS -Zi"
CORE_LINK="$CORE_LINK -debug"
diff --git a/auto/cc/owc b/auto/cc/owc
index 868860041..1a5fa210b 100644
--- a/auto/cc/owc
+++ b/auto/cc/owc
@@ -71,7 +71,7 @@ NGX_USE_PCH="-fh=$NGX_OBJS/ngx_config.pch"
# the link flags, built target is NT GUI mode application
-CORE_LINK="$CORE_LINK -l=nt_win"
+#CORE_LINK="$CORE_LINK -l=nt_win"
# the resource file
diff --git a/auto/sources b/auto/sources
index 4c14634de..7ee0d44e4 100644
--- a/auto/sources
+++ b/auto/sources
@@ -215,8 +215,6 @@ WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \
src/os/win32/ngx_socket.h \
src/os/win32/ngx_os.h \
src/os/win32/ngx_user.h \
- src/os/win32/ngx_gui.h \
- src/os/win32/ngx_gui_resources.h \
src/os/win32/ngx_process_cycle.h"
WIN32_CONFIG=src/os/win32/ngx_win32_config.h
@@ -233,14 +231,15 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \
src/os/win32/ngx_wsarecv.c \
src/os/win32/ngx_wsarecv_chain.c \
src/os/win32/ngx_udp_wsarecv.c \
+ src/os/win32/ngx_wsasend.c \
src/os/win32/ngx_wsasend_chain.c \
src/os/win32/ngx_win32_init.c \
src/os/win32/ngx_user.c \
- src/os/win32/ngx_gui.c \
+ src/os/win32/ngx_event_log.c \
src/os/win32/ngx_process_cycle.c \
src/event/ngx_event_acceptex.c"
-NGX_WIN32_ICONS="src/os/win32/nginx.ico src/os/win32/nginx_tray.ico"
+NGX_WIN32_ICONS="src/os/win32/nginx.ico"
NGX_WIN32_RC="src/os/win32/nginx.rc"
diff --git a/misc/GNUmakefile b/misc/GNUmakefile
index b863d67dc..99a62d5e8 100644
--- a/misc/GNUmakefile
+++ b/misc/GNUmakefile
@@ -1,8 +1,13 @@
-VER= $(shell grep 'define NGINX_VERSION' src/core/nginx.h \
- | sed -e 's/^.*\"\(.*\)\"/\1/')
-NGINX= nginx-$(VER)
-TEMP= tmp
+VER = $(shell grep 'define NGINX_VERSION' src/core/nginx.h \
+ | sed -e 's/^.*\"\(.*\)\"/\1/')
+NGINX = nginx-$(VER)
+TEMP = tmp
+
+OBJS = objs.msvc8
+OPENSSL = openssl-0.9.8k
+ZLIB = zlib-1.2.3
+PCRE = pcre-4.4
release:
@@ -64,7 +69,45 @@ snapshot:
tar -c -z -f $(NGINX).tar.gz --directory $(TEMP) $(NGINX)
-icons: src/os/win32/nginx.ico src/os/win32/nginx_tray.ico
+zip:
+ rm -rf $(TEMP)
+ rm -f $(NGINX).zip
+
+ mkdir -p $(TEMP)/$(NGINX)/docs
+ mkdir -p $(TEMP)/$(NGINX)/logs
+ mkdir -p $(TEMP)/$(NGINX)/temp
+
+ svn export -rHEAD conf $(TEMP)/$(NGINX)/conf/
+ perl -pi -e 's/$$/\r/' $(TEMP)/$(NGINX)/conf/*
+
+ svn export -rHEAD contrib $(TEMP)/$(NGINX)/contrib/
+ svn export -rHEAD docs/html $(TEMP)/$(NGINX)/html/
+
+ $(MAKE) -f docs/GNUmakefile changes
+
+ cp -p $(OBJS)/nginx.exe $(TEMP)/$(NGINX)
+
+ cp -p docs/text/LICENSE $(TEMP)/$(NGINX)/docs/
+ cp -p docs/text/README $(TEMP)/$(NGINX)/docs/
+ mv $(TEMP)/$(NGINX)/CHANGES* $(TEMP)/$(NGINX)/docs/
+
+ cp -p $(OBJS)/lib/$(OPENSSL)/LICENSE \
+ $(TEMP)/$(NGINX)/docs/OpenSSL.LICENSE
+
+ cp -p $(OBJS)/lib/$(PCRE)/COPYING \
+ $(TEMP)/$(NGINX)/docs/PCRE.COPYING
+
+ perl -ne 'print if /^ \(C\) 1995-2004/ .. /^ jloup\@gzip.org/' \
+ $(OBJS)/lib/$(ZLIB)/README \
+ > $(TEMP)/$(NGINX)/docs/zlib.LICENSE
+
+ touch -r $(OBJS)/lib/$(ZLIB)/README \
+ $(TEMP)/$(NGINX)/docs/zlib.LICENSE
+
+ cd $(TEMP) && zip -r ../$(NGINX).zip $(NGINX)
+
+
+icons: src/os/win32/nginx.ico
# 32x32 and 16x16 icons
@@ -82,15 +125,3 @@ src/os/win32/nginx.ico: src/os/win32/nginx_icon32.xpm \
ppmtowinicon -output src/os/win32/nginx.ico -andpgms \
$(TEMP)/nginx32.ppm $(TEMP)/nginx32.pbm \
$(TEMP)/nginx16.ppm $(TEMP)/nginx16.pbm
-
-# tray icon
-
-src/os/win32/nginx_tray.ico: src/os/win32/nginx_tray.xpm
-
- test -d $(TEMP) || mkdir $(TEMP)
-
- xpmtoppm --alphaout=$(TEMP)/nginx_tray.pbm \
- src/os/win32/nginx_tray.xpm > $(TEMP)/nginx_tray.ppm
-
- ppmtowinicon -output src/os/win32/nginx_tray.ico -andpgms \
- $(TEMP)/nginx_tray.ppm $(TEMP)/nginx_tray.pbm
diff --git a/src/core/nginx.c b/src/core/nginx.c
index a542eca74..cfc2337f1 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -180,10 +180,14 @@ ngx_module_t ngx_core_module = {
};
-ngx_uint_t ngx_max_module;
+ngx_uint_t ngx_max_module;
+
+static ngx_uint_t ngx_show_version;
+static ngx_uint_t ngx_show_configure;
+#if (NGX_WIN32)
+static char *ngx_signal;
+#endif
-static ngx_uint_t ngx_show_version;
-static ngx_uint_t ngx_show_configure;
static char **ngx_os_environ;
@@ -303,22 +307,15 @@ main(int argc, char *const *argv)
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
- ngx_process = ccf->master ? NGX_PROCESS_MASTER : NGX_PROCESS_SINGLE;
+ if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
+ ngx_process = NGX_PROCESS_MASTER;
+ }
#if (NGX_WIN32)
-#if 0
-
- TODO:
-
- if (ccf->run_as_service) {
- if (ngx_service(cycle->log) != NGX_OK) {
- return 1;
- }
-
- return 0;
+ if (ngx_signal) {
+ return ngx_signal_process(cycle, ngx_signal);
}
-#endif
#else
@@ -334,17 +331,17 @@ main(int argc, char *const *argv)
ngx_daemonized = 1;
}
+#endif
+
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return 1;
}
-#endif
-
- if (ngx_process == NGX_PROCESS_MASTER) {
- ngx_master_process_cycle(cycle);
+ if (ngx_process == NGX_PROCESS_SINGLE) {
+ ngx_single_process_cycle(cycle);
} else {
- ngx_single_process_cycle(cycle);
+ ngx_master_process_cycle(cycle);
}
return 0;
@@ -645,6 +642,29 @@ ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
cycle->conf_param.len = ngx_strlen(cycle->conf_param.data);
break;
+#if (NGX_WIN32)
+ case 's':
+ if (argv[++i] == NULL) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
+ "the option \"-s\" requires parameter");
+ return NGX_ERROR;
+ }
+
+ if (ngx_strcmp(argv[i], "stop") == 0
+ || ngx_strcmp(argv[i], "quit") == 0
+ || ngx_strcmp(argv[i], "reopen") == 0
+ || ngx_strcmp(argv[i], "reload") == 0)
+ {
+ ngx_process = NGX_PROCESS_SIGNALLER;
+ ngx_signal = argv[i];
+ break;
+ }
+
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
+ "invalid option: \"-s %s\"", argv[i]);
+ return NGX_ERROR;
+#endif
+
default:
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
"invalid option: \"%s\"", argv[i]);
@@ -786,6 +806,27 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
#endif
+
+ if (ccf->pid.len == 0) {
+ ccf->pid.len = sizeof(NGX_PID_PATH) - 1;
+ ccf->pid.data = (u_char *) NGX_PID_PATH;
+ }
+
+ if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);
+
+ ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
+ if (ccf->oldpid.data == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
+ NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));
+
+
#if !(NGX_WIN32)
if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
@@ -814,25 +855,6 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
ccf->group = grp->gr_gid;
}
- if (ccf->pid.len == 0) {
- ccf->pid.len = sizeof(NGX_PID_PATH) - 1;
- ccf->pid.data = (u_char *) NGX_PID_PATH;
- }
-
- if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);
-
- ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
- if (ccf->oldpid.data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
- NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));
-
if (ccf->lock_file.len == 0) {
ccf->lock_file.len = sizeof(NGX_LOCK_PATH) - 1;
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index f413ffbe8..ed9efe754 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -557,28 +557,30 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
c = ls[i].connection;
- if (c->read->active) {
- if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
- ngx_del_conn(c, NGX_CLOSE_EVENT);
+ if (c) {
+ if (c->read->active) {
+ if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
+ ngx_del_conn(c, NGX_CLOSE_EVENT);
- } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
+ } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
- /*
- * it seems that Linux-2.6.x OpenVZ sends events
- * for closed shared listening sockets unless
- * the events was explicity deleted
- */
+ /*
+ * it seems that Linux-2.6.x OpenVZ sends events
+ * for closed shared listening sockets unless
+ * the events was explicity deleted
+ */
- ngx_del_event(c->read, NGX_READ_EVENT, 0);
+ ngx_del_event(c->read, NGX_READ_EVENT, 0);
- } else {
- ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+ } else {
+ ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+ }
}
- }
- ngx_free_connection(c);
+ ngx_free_connection(c);
- c->fd = (ngx_socket_t) -1;
+ c->fd = (ngx_socket_t) -1;
+ }
ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
"close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index d4186d358..2d829dd04 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -295,8 +295,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-#if !(NGX_WIN32)
-
if (ngx_test_config) {
if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
@@ -325,8 +323,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
}
}
-#endif
-
if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
goto failed;
@@ -928,8 +924,6 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
}
-#if !(NGX_WIN32)
-
ngx_int_t
ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
{
@@ -938,6 +932,10 @@ ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
ngx_file_t file;
u_char pid[NGX_INT64_LEN + 2];
+ if (ngx_process > NGX_PROCESS_MASTER) {
+ return NGX_OK;
+ }
+
ngx_memzero(&file, sizeof(ngx_file_t));
file.name = *name;
@@ -987,8 +985,6 @@ ngx_delete_pidfile(ngx_cycle_t *cycle)
}
}
-#endif
-
static ngx_int_t
ngx_test_lockfile(u_char *file, ngx_log_t *log)
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index 35a24172e..8769bcdc6 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -227,9 +227,9 @@ ngx_log_init(void)
NGX_FILE_DEFAULT_ACCESS);
if (ngx_stderr.fd == NGX_INVALID_FILE) {
- ngx_message_box("nginx", MB_OK, ngx_errno,
- "Could not open error log file: "
- ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed");
+ ngx_event_log(ngx_errno,
+ "Could not open error log file: "
+ ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed");
return NULL;
}
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 1f8693a3c..8d18ef648 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -442,7 +442,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
ecf = (*cf)[ngx_event_core_module.ctx_index];
- if (!ngx_test_config) {
+ if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) {
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
"using the \"%s\" event method", ecf->name);
}
diff --git a/src/os/win32/nginx.rc b/src/os/win32/nginx.rc
index 8aa6ff595..3230cfc45 100644
--- a/src/os/win32/nginx.rc
+++ b/src/os/win32/nginx.rc
@@ -1,16 +1,5 @@
// Copyright (C) Igor Sysoev
-#include <ngx_gui_resources.h>
nginx icon discardable "src\\os\\win32\\nginx.ico"
-tray icon discardable "src\\os\\win32\\nginx_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/nginx_tray.ico b/src/os/win32/nginx_tray.ico
deleted file mode 100644
index b39e5241c..000000000
--- a/src/os/win32/nginx_tray.ico
+++ /dev/null
Binary files differ
diff --git a/src/os/win32/nginx_tray.xpm b/src/os/win32/nginx_tray.xpm
deleted file mode 100644
index 2fa0445bd..000000000
--- a/src/os/win32/nginx_tray.xpm
+++ /dev/null
@@ -1,24 +0,0 @@
-/* XPM */
-static char * nginx_xpm[] = {
-"16 16 2 2",
-/* colors */
-" c none",
-"GG c #008000",
-/* pixels */
-" ",
-" GGGGGGGGGGGGGGGG ",
-" GGGGGGGGGGGGGGGG ",
-" GGGGGGGGGGGGGGGGGGGG ",
-" GGGGGG GGGGGG ",
-" GGGGGG GGGGGG ",
-" GGGGGG ",
-" GGGGGG GGGGGGGGGGGGGGGG ",
-" GGGGGG GGGGGGGGGGGGGGGGGG ",
-" GGGGGG GGGGGGGGGGGGGG ",
-" GGGGGG GGGGGG ",
-" GGGGGG GGGGGG ",
-" GGGGGGGGGGGGGGGGGGGG ",
-" GGGGGGGGGGGGGGGG ",
-" GGGGGGGGGGGGGGGG ",
-" "
-};
diff --git a/src/os/win32/ngx_event_log.c b/src/os/win32/ngx_event_log.c
new file mode 100644
index 000000000..98887605a
--- /dev/null
+++ b/src/os/win32/ngx_event_log.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_MAX_ERROR_STR 2048
+
+
+void ngx_cdecl
+ngx_event_log(ngx_err_t err, const char *fmt, ...)
+{
+ u_char *p, *last;
+ long types;
+ HKEY key;
+ HANDLE ev;
+ va_list args;
+ u_char text[NGX_MAX_ERROR_STR];
+ const char *msgarg[9];
+ static u_char netmsg[] = "%SystemRoot%\\System32\\netmsg.dll";
+
+ p = text + GetModuleFileName(NULL, (char *) text, NGX_MAX_ERROR_STR - 50);
+
+ *p++ = ':';
+ ngx_linefeed(p);
+
+ va_start(args, fmt);
+ p = ngx_vsnprintf(p, NGX_MAX_ERROR_STR, fmt, args);
+ va_end(args);
+
+ last = text + NGX_MAX_ERROR_STR;
+
+ if (err) {
+
+ if (p > last - 50) {
+
+ /* leave a space for an error code */
+
+ p = last - 50;
+ *p++ = '.';
+ *p++ = '.';
+ *p++ = '.';
+ }
+
+ p = ngx_snprintf(p, last - p, ((unsigned) err < 0x80000000)
+ ? " (%d: " : " (%Xd: ", err);
+ p = ngx_strerror_r(err, p, last - p);
+
+ if (p < last) {
+ *p++ = ')';
+ }
+ }
+
+ if (p > last - NGX_LINEFEED_SIZE - 1) {
+ p = last - NGX_LINEFEED_SIZE - 1;
+ }
+
+ ngx_linefeed(p);
+
+ *p = '\0';
+
+ /*
+ * we do not log errors here since we use
+ * Event Log only to log our own logs open errors
+ */
+
+ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\nginx",
+ 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &key, NULL)
+ != 0)
+ {
+ return;
+ }
+
+ if (RegSetValueEx(key, "EventMessageFile", 0, REG_EXPAND_SZ,
+ netmsg, sizeof(netmsg) - 1)
+ != 0)
+ {
+ return;
+ }
+
+ types = EVENTLOG_ERROR_TYPE;
+
+ if (RegSetValueEx(key, "TypesSupported", 0, REG_DWORD,
+ (u_char *) &types, sizeof(long))
+ != 0)
+ {
+ return;
+ }
+
+ RegCloseKey(key);
+
+ ev = RegisterEventSource(NULL, "nginx");
+
+ msgarg[0] = (char *) text;
+ msgarg[1] = NULL;
+ msgarg[2] = NULL;
+ msgarg[3] = NULL;
+ msgarg[4] = NULL;
+ msgarg[5] = NULL;
+ msgarg[6] = NULL;
+ msgarg[7] = NULL;
+ msgarg[8] = NULL;
+
+ /*
+ * the 3299 event id in netmsg.dll has the generic message format:
+ * "%1 %2 %3 %4 %5 %6 %7 %8 %9"
+ */
+
+ ReportEvent(ev, EVENTLOG_ERROR_TYPE, 0, 3299, NULL, 9, 0, msgarg, NULL);
+
+ DeregisterEventSource(ev);
+}
diff --git a/src/os/win32/ngx_gui.c b/src/os/win32/ngx_gui.c
deleted file mode 100644
index ba6564560..000000000
--- a/src/os/win32/ngx_gui.c
+++ /dev/null
@@ -1,81 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_MAX_TEXT 2048
-
-
-void __cdecl
-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++ = '.';
- }
-
- p = ngx_snprintf(p, last - p, ((unsigned) err < 0x80000000)
- ? " (%d: " : " (%Xd: ", 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
deleted file mode 100644
index 0bff21c09..000000000
--- a/src/os/win32/ngx_gui.h
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#ifndef _NGX_GUI_H_INCLUDED_
-#define _NGX_GUI_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_gui_resources.h>
-
-
-void ngx_cdecl 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_gui_resources.h b/src/os/win32/ngx_gui_resources.h
deleted file mode 100644
index cfbb00f1a..000000000
--- a/src/os/win32/ngx_gui_resources.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#ifndef _NGX_GUI_RESOURCES_H_INCLUDED_
-#define _NGX_GUI_RESOURCES_H_INCLUDED_
-
-
-#include <winuser.h>
-
-
-#define NGX_WM_TRAY WM_USER
-#define NGX_WM_EXIT WM_USER + 1
-#define NGX_WM_ABOUT WM_USER + 2
-
-
-#endif /* _NGX_GUI_RESOURCES_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_os.h b/src/os/win32/ngx_os.h
index 2124ab8d7..cbd1fc22b 100644
--- a/src/os/win32/ngx_os.h
+++ b/src/os/win32/ngx_os.h
@@ -10,7 +10,6 @@
#include <ngx_config.h>
#include <ngx_core.h>
-#include <ngx_gui.h>
#define NGX_IO_SENDFILE 1
@@ -40,11 +39,15 @@ ssize_t ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
ssize_t ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf,
size_t size);
ssize_t ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain);
+ssize_t ngx_wsasend(ngx_connection_t *c, u_char *buf, size_t size);
+ssize_t ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size);
ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit);
ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit);
+void ngx_cdecl ngx_event_log(ngx_err_t err, const char *fmt, ...);
+
extern ngx_os_io_t ngx_os_io;
extern ngx_uint_t ngx_ncpu;
@@ -57,6 +60,4 @@ extern ngx_fd_t ngx_stderr_fileno;
extern char ngx_unique[];
-
#endif /* _NGX_OS_H_INCLUDED_ */
-
diff --git a/src/os/win32/ngx_process.c b/src/os/win32/ngx_process.c
index 062c41c8a..f16b827eb 100644
--- a/src/os/win32/ngx_process.c
+++ b/src/os/win32/ngx_process.c
@@ -8,12 +8,212 @@
#include <ngx_core.h>
-int ngx_argc;
-char **ngx_argv;
-char **ngx_os_argv;
+int ngx_argc;
+char **ngx_argv;
+char **ngx_os_argv;
+ngx_int_t ngx_last_process;
+ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
-ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
+
+ngx_pid_t
+ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn)
{
- return /* STUB */ 0;
+ u_long rc, n;
+ ngx_int_t s;
+ ngx_pid_t pid;
+ ngx_exec_ctx_t ctx;
+ char file[MAX_PATH + 1];
+
+ if (respawn >= 0) {
+ s = respawn;
+
+ } else {
+ for (s = 0; s < ngx_last_process; s++) {
+ if (ngx_processes[s].handle == NULL) {
+ break;
+ }
+ }
+
+ if (s == NGX_MAX_PROCESSES) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "no more than %d processes can be spawned",
+ NGX_MAX_PROCESSES);
+ return NGX_INVALID_PID;
+ }
+ }
+
+ n = GetModuleFileName(NULL, file, MAX_PATH);
+
+ if (n == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "GetModuleFileName() failed");
+ return NGX_INVALID_PID;
+ }
+
+ file[n] = '\0';
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "GetModuleFileName: \"%s\"", file);
+
+ ctx.path = file;
+ ctx.name = name;
+ ctx.argv = NULL;
+ ctx.envp = NULL;
+
+ pid = ngx_execute(cycle, &ctx);
+
+ if (pid == NGX_INVALID_PID) {
+ return pid;
+ }
+
+ ngx_memzero(&ngx_processes[s], sizeof(ngx_process_t));
+
+ ngx_processes[s].handle = ctx.child;
+ ngx_processes[s].pid = pid;
+ ngx_processes[s].name = name;
+
+ ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%ul%Z", name, pid);
+ ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%ul%Z", name, pid);
+ ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%ul%Z",
+ name, pid);
+
+ rc = WaitForSingleObject(ngx_master_process_event, 5000);
+
+ ngx_time_update(0, 0);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "WaitForSingleObject: %ul", rc);
+
+ switch (rc) {
+
+ case WAIT_OBJECT_0:
+
+ ngx_processes[s].term = OpenEvent(EVENT_MODIFY_STATE, 0,
+ (char *) ngx_processes[s].term_event);
+ if (ngx_processes[s].term == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed",
+ ngx_processes[s].term_event);
+ goto failed;
+ }
+
+ ngx_processes[s].quit = OpenEvent(EVENT_MODIFY_STATE, 0,
+ (char *) ngx_processes[s].quit_event);
+ if (ngx_processes[s].quit == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed",
+ ngx_processes[s].quit_event);
+ goto failed;
+ }
+
+ ngx_processes[s].reopen = OpenEvent(EVENT_MODIFY_STATE, 0,
+ (char *) ngx_processes[s].reopen_event);
+ if (ngx_processes[s].reopen == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed",
+ ngx_processes[s].reopen_event);
+ goto failed;
+ }
+
+ if (ResetEvent(ngx_master_process_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed",
+ ngx_master_process_event_name);
+ goto failed;
+ }
+
+ break;
+
+ case WAIT_TIMEOUT:
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "the event \"%s\" was not signaled for 5s",
+ ngx_master_process_event_name);
+ goto failed;
+
+ case WAIT_FAILED:
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "WaitForSingleObject(\"%s\") failed",
+ ngx_master_process_event_name);
+
+ goto failed;
+ }
+
+ if (respawn >= 0) {
+ return pid;
+ }
+
+ switch (respawn) {
+
+ case NGX_PROCESS_RESPAWN:
+ ngx_processes[s].just_respawn = 0;
+ break;
+
+ case NGX_PROCESS_JUST_RESPAWN:
+ ngx_processes[s].just_respawn = 1;
+ break;
+ }
+
+ if (s == ngx_last_process) {
+ ngx_last_process++;
+ }
+
+ return pid;
+
+failed:
+
+ if (ngx_processes[s].reopen) {
+ ngx_close_handle(ngx_processes[s].reopen);
+ }
+
+ if (ngx_processes[s].quit) {
+ ngx_close_handle(ngx_processes[s].quit);
+ }
+
+ if (ngx_processes[s].term) {
+ ngx_close_handle(ngx_processes[s].term);
+ }
+
+ TerminateProcess(ngx_processes[s].handle, 2);
+
+ if (ngx_processes[s].handle) {
+ ngx_close_handle(ngx_processes[s].handle);
+ }
+
+ return NGX_INVALID_PID;
+}
+
+
+ngx_pid_t
+ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ngx_memzero(&si, sizeof(STARTUPINFO));
+ si.cb = sizeof(STARTUPINFO);
+
+ ngx_memzero(&pi, sizeof(PROCESS_INFORMATION));
+
+ if (CreateProcess(ctx->path, /* STUB */ NULL,
+ NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)
+ == 0)
+ {
+ ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
+ "CreateProcess(\"%s\") failed", ngx_argv[0]);
+
+ return 0;
+ }
+
+ ctx->child = pi.hProcess;
+
+ if (CloseHandle(pi.hThread) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CloseHandle(pi.hThread) failed");
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
+ "start %s process %P", ctx->name, pi.dwProcessId);
+
+ return pi.dwProcessId;
}
diff --git a/src/os/win32/ngx_process.h b/src/os/win32/ngx_process.h
index bd282b217..49eef785c 100644
--- a/src/os/win32/ngx_process.h
+++ b/src/os/win32/ngx_process.h
@@ -8,38 +8,71 @@
#define _NGX_PROCESS_H_INCLUDED_
-typedef DWORD ngx_pid_t;
-#define NGX_INVALID_PID 0
+typedef DWORD ngx_pid_t;
+#define NGX_INVALID_PID 0
-#define ngx_getpid GetCurrentProcessId
-#define ngx_log_pid ngx_pid
+#define ngx_getpid GetCurrentProcessId
+#define ngx_log_pid ngx_pid
+
+
+#define NGX_PROCESS_SYNC_NAME \
+ (sizeof("ngx_cache_manager_mutex_") + NGX_INT32_LEN)
+
+
+typedef struct {
+ HANDLE handle;
+ ngx_pid_t pid;
+ char *name;
+
+ HANDLE term;
+ HANDLE quit;
+ HANDLE reopen;
+
+ u_char term_event[NGX_PROCESS_SYNC_NAME];
+ u_char quit_event[NGX_PROCESS_SYNC_NAME];
+ u_char reopen_event[NGX_PROCESS_SYNC_NAME];
+
+ unsigned just_respawn:1;
+ unsigned exiting:1;
+} ngx_process_t;
typedef struct {
- char *path;
- char *name;
- char *const *argv;
- char *const *envp;
+ char *path;
+ char *name;
+ char *const *argv;
+ char *const *envp;
+ HANDLE child;
} ngx_exec_ctx_t;
-#define NGX_PROCESS_SINGLE 0
-#define NGX_PROCESS_MASTER 1
-#define NGX_PROCESS_WORKER 2
+#define NGX_PROCESS_SINGLE 0
+#define NGX_PROCESS_MASTER 1
+#define NGX_PROCESS_WORKER 2
+ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn);
ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx);
#define ngx_debug_point()
-#define ngx_sched_yield() Sleep(0)
+#define ngx_sched_yield() Sleep(0)
+
+
+#define NGX_MAX_PROCESSES (MAXIMUM_WAIT_OBJECTS - 4)
+
+#define NGX_PROCESS_RESPAWN -2
+#define NGX_PROCESS_JUST_RESPAWN -3
+
+extern int ngx_argc;
+extern char **ngx_argv;
+extern char **ngx_os_argv;
-extern int ngx_argc;
-extern char **ngx_argv;
-extern char **ngx_os_argv;
+extern ngx_int_t ngx_last_process;
+extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
-extern ngx_pid_t ngx_pid;
+extern ngx_pid_t ngx_pid;
#endif /* _NGX_PROCESS_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c
index 6e7c28688..22d70c6fe 100644
--- a/src/os/win32/ngx_process_cycle.c
+++ b/src/os/win32/ngx_process_cycle.c
@@ -10,69 +10,237 @@
#include <nginx.h>
-static ngx_thread_value_t __stdcall ngx_worker_thread_cycle(void *data);
-static void ngx_process_tray(ngx_cycle_t *cycle);
-static long __stdcall ngx_window_procedure(HWND window, u_int message,
- u_int wparam, long lparam);
+static void ngx_process_init(ngx_cycle_t *cycle);
+static void ngx_console_init(ngx_cycle_t *cycle);
+static int __stdcall ngx_console_handler(u_long type);
+static ngx_int_t ngx_create_events(ngx_cycle_t *cycle);
+static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type);
+static void ngx_reopen_worker_processes(ngx_cycle_t *cycle);
+static void ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old);
+static void ngx_terminate_worker_processes(ngx_cycle_t *cycle);
+static ngx_uint_t ngx_reap_worker(ngx_cycle_t *cycle, HANDLE h);
+static void ngx_master_process_exit(ngx_cycle_t *cycle);
+static void ngx_worker_process_cycle(ngx_cycle_t *cycle, char *mevn);
+static void ngx_worker_process_exit(ngx_cycle_t *cycle);
+static ngx_thread_value_t __stdcall ngx_worker_thread(void *data);
+static ngx_thread_value_t __stdcall ngx_cache_manager_thread(void *data);
+static void ngx_cache_manager_process_handler(void);
+
+
+ngx_uint_t ngx_process;
+ngx_pid_t ngx_pid;
+ngx_uint_t ngx_threaded;
+
+ngx_uint_t ngx_inherited;
+ngx_pid_t ngx_new_binary;
+
+sig_atomic_t ngx_terminate;
+sig_atomic_t ngx_quit;
+sig_atomic_t ngx_reopen;
+sig_atomic_t ngx_reconfigure;
+ngx_uint_t ngx_exiting;
+
+
+HANDLE ngx_master_process_event;
+char ngx_master_process_event_name[NGX_PROCESS_SYNC_NAME];
+
+static HANDLE ngx_stop_event;
+static char ngx_stop_event_name[NGX_PROCESS_SYNC_NAME];
+static HANDLE ngx_quit_event;
+static char ngx_quit_event_name[NGX_PROCESS_SYNC_NAME];
+static HANDLE ngx_reopen_event;
+static char ngx_reopen_event_name[NGX_PROCESS_SYNC_NAME];
+static HANDLE ngx_reload_event;
+static char ngx_reload_event_name[NGX_PROCESS_SYNC_NAME];
+
+HANDLE ngx_cache_manager_mutex;
+char ngx_cache_manager_mutex_name[NGX_PROCESS_SYNC_NAME];
+HANDLE ngx_cache_manager_event;
-#if 0
-ngx_pid_t ngx_new_binary;
-sig_atomic_t ngx_reap;
-sig_atomic_t ngx_timer;
+void
+ngx_master_process_cycle(ngx_cycle_t *cycle)
+{
+ u_long nev, ev, timeout;
+ ngx_err_t err;
+ ngx_int_t n;
+ ngx_msec_t timer;
+ ngx_uint_t live;
+ HANDLE events[MAXIMUM_WAIT_OBJECTS];
-#endif
+ ngx_process_init(cycle);
-ngx_uint_t ngx_process;
-ngx_pid_t ngx_pid;
-ngx_uint_t ngx_threaded;
-ngx_uint_t ngx_inherited;
+ ngx_sprintf((u_char *) ngx_master_process_event_name,
+ "ngx_master_%s%Z", ngx_unique);
+ if (ngx_process == NGX_PROCESS_WORKER) {
+ ngx_worker_process_cycle(cycle, ngx_master_process_event_name);
+ return;
+ }
-sig_atomic_t ngx_terminate;
-sig_atomic_t ngx_quit;
-ngx_uint_t ngx_exiting;
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "master started");
-#if 0
+ ngx_console_init(cycle);
-sig_atomic_t ngx_noaccept;
-sig_atomic_t ngx_reconfigure;
-sig_atomic_t ngx_reopen;
-sig_atomic_t ngx_change_binary;
+ SetEnvironmentVariable("ngx_unique", ngx_unique);
-#endif
+ ngx_master_process_event = CreateEvent(NULL, 1, 0,
+ ngx_master_process_event_name);
+ if (ngx_master_process_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed",
+ ngx_master_process_event_name);
+ exit(2);
+ }
+ if (ngx_create_events(cycle) != NGX_OK) {
+ exit(2);
+ }
-static HMENU ngx_menu;
+ ngx_sprintf((u_char *) ngx_cache_manager_mutex_name,
+ "ngx_cache_manager_mutex_%s%Z", ngx_unique);
+ ngx_cache_manager_mutex = CreateMutex(NULL, 0,
+ ngx_cache_manager_mutex_name);
+ if (ngx_cache_manager_mutex == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateMutex(\"%s\") failed", ngx_cache_manager_mutex_name);
+ exit(2);
+ }
-void
-ngx_master_process_cycle(ngx_cycle_t *cycle)
-{
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "master mode is not supported");
- exit(2);
-}
+ events[0] = ngx_stop_event;
+ events[1] = ngx_quit_event;
+ events[2] = ngx_reopen_event;
+ events[3] = ngx_reload_event;
+ ngx_close_listening_sockets(cycle);
-void
-ngx_single_process_cycle(ngx_cycle_t *cycle)
-{
- ngx_int_t i;
- ngx_err_t err;
- ngx_tid_t tid;
- ngx_core_conf_t *ccf;
+ ngx_start_worker_processes(cycle, NGX_PROCESS_RESPAWN);
- ngx_init_temp_number();
+ timer = 0;
+ timeout = INFINITE;
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->init_process) {
- if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
- /* fatal */
- exit(2);
+ for ( ;; ) {
+
+ nev = 4;
+ for (n = 0; n < ngx_last_process; n++) {
+ if (ngx_processes[n].handle) {
+ events[nev++] = ngx_processes[n].handle;
+ }
+ }
+
+ if (timer) {
+ timeout = timer > ngx_current_msec ? timer - ngx_current_msec : 0;
+ }
+
+ ev = WaitForMultipleObjects(nev, events, 0, timeout);
+
+ err = ngx_errno;
+ ngx_time_update(0, 0);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "master WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_OBJECT_0) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+
+ if (ResetEvent(ngx_stop_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed", ngx_stop_event_name);
+ }
+
+ if (timer == 0) {
+ timer = ngx_current_msec + 5000;
+ }
+
+ ngx_terminate = 1;
+ ngx_quit_worker_processes(cycle, 0);
+
+ continue;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 1) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "shutting down");
+
+ if (ResetEvent(ngx_quit_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed", ngx_quit_event_name);
+ }
+
+ ngx_quit = 1;
+ ngx_quit_worker_processes(cycle, 0);
+
+ continue;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 2) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
+
+ if (ResetEvent(ngx_reopen_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed",
+ ngx_reopen_event_name);
+ }
+
+ ngx_reopen_files(cycle, -1);
+ ngx_reopen_worker_processes(cycle);
+
+ continue;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 3) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
+
+ if (ResetEvent(ngx_reload_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed",
+ ngx_reload_event_name);
+ }
+
+ ngx_start_worker_processes(cycle, NGX_PROCESS_JUST_RESPAWN);
+ ngx_quit_worker_processes(cycle, 1);
+
+ continue;
+ }
+
+ if (ev > WAIT_OBJECT_0 + 3 && ev < WAIT_OBJECT_0 + nev) {
+
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "reap worker");
+
+ live = ngx_reap_worker(cycle, events[ev]);
+
+ if (!live && (ngx_terminate || ngx_quit)) {
+ ngx_master_process_exit(cycle);
}
+
+ continue;
+ }
+
+ if (ev == WAIT_TIMEOUT) {
+ ngx_terminate_worker_processes(cycle);
+
+ ngx_master_process_exit(cycle);
+ }
+
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "WaitForMultipleObjects() failed");
+
+ continue;
}
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "WaitForMultipleObjects() returned unexpected value %ul", ev);
}
+}
+
+
+static void
+ngx_process_init(ngx_cycle_t *cycle)
+{
+ ngx_err_t err;
+ ngx_core_conf_t *ccf;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
@@ -90,29 +258,288 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
/* fatal */
exit(2);
}
+}
- if (ngx_create_thread(&tid, ngx_worker_thread_cycle, NULL, cycle->log)
- != 0)
- {
- /* fatal */
- exit(2);
+
+static void
+ngx_console_init(ngx_cycle_t *cycle)
+{
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ if (ccf->daemon) {
+ if (FreeConsole() == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "FreeConsole() failed");
+ }
+
+ return;
}
- ngx_process_tray(cycle);
+ if (SetConsoleCtrlHandler(ngx_console_handler, 1) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetConsoleCtrlHandler() failed");
+ }
}
-static ngx_thread_value_t __stdcall
-ngx_worker_thread_cycle(void *data)
+static int __stdcall
+ngx_console_handler(u_long type)
{
- ngx_cycle_t *cycle;
+ char *msg;
- cycle = (ngx_cycle_t *) ngx_cycle;
+ switch (type) {
- while (!ngx_quit) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
+ case CTRL_C_EVENT:
+ msg = "Ctrl-C pressed, exiting";
+ break;
- ngx_process_events_and_timers(cycle);
+ case CTRL_BREAK_EVENT:
+ msg = "Ctrl-Break pressed, exiting";
+ break;
+
+ case CTRL_CLOSE_EVENT:
+ msg = "console closing, exiting";
+ break;
+
+ case CTRL_LOGOFF_EVENT:
+ msg = "user logs off, exiting";
+ break;
+
+ default:
+ return 0;
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, msg);
+
+ if (ngx_stop_event == NULL) {
+ return 1;
+ }
+
+ if (SetEvent(ngx_stop_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ "SetEvent(\"%s\") failed", ngx_stop_event_name);
+ }
+
+ return 1;
+}
+
+
+static ngx_int_t
+ngx_create_events(ngx_cycle_t *cycle)
+{
+ ngx_sprintf((u_char *) ngx_stop_event_name, "ngx_stop_%s%Z", ngx_unique);
+
+ ngx_stop_event = CreateEvent(NULL, 1, 0, ngx_stop_event_name);
+ if (ngx_stop_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_stop_event_name);
+ return NGX_ERROR;
+ }
+
+
+ ngx_sprintf((u_char *) ngx_quit_event_name, "ngx_quit_%s%Z", ngx_unique);
+
+ ngx_quit_event = CreateEvent(NULL, 1, 0, ngx_quit_event_name);
+ if (ngx_quit_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_quit_event_name);
+ return NGX_ERROR;
+ }
+
+
+ ngx_sprintf((u_char *) ngx_reopen_event_name,
+ "ngx_reopen_%s%Z", ngx_unique);
+
+ ngx_reopen_event = CreateEvent(NULL, 1, 0, ngx_reopen_event_name);
+ if (ngx_reopen_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_reopen_event_name);
+ return NGX_ERROR;
+ }
+
+
+ ngx_sprintf((u_char *) ngx_reload_event_name,
+ "ngx_reload_%s%Z", ngx_unique);
+
+ ngx_reload_event = CreateEvent(NULL, 1, 0, ngx_reload_event_name);
+ if (ngx_reload_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_reload_event_name);
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+static void
+ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type)
+{
+ ngx_int_t n;
+ ngx_core_conf_t *ccf;
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ for (n = 0; n < ccf->worker_processes; n++) {
+ if (ngx_spawn_process(cycle, "worker", type) == NGX_INVALID_PID) {
+ return;
+ }
+ }
+}
+
+
+static void
+ngx_reopen_worker_processes(ngx_cycle_t *cycle)
+{
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ if (ngx_processes[n].handle == NULL) {
+ continue;
+ }
+
+ if (SetEvent(ngx_processes[n].reopen) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetEvent(\"%s\") failed",
+ ngx_processes[n].reopen_event);
+ }
+ }
+}
+
+
+static void
+ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old)
+{
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "process: %d %P %p e:%d t:%d r:%d j:%d",
+ n,
+ ngx_processes[n].pid,
+ ngx_processes[n].handle,
+ ngx_processes[n].exiting,
+ ngx_processes[n].just_respawn);
+
+ if (old && ngx_processes[n].just_respawn) {
+ ngx_processes[n].just_respawn = 0;
+ continue;
+ }
+
+ if (ngx_processes[n].handle == NULL) {
+ continue;
+ }
+
+ if (SetEvent(ngx_processes[n].quit) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetEvent(\"%s\") failed",
+ ngx_processes[n].quit_event);
+ }
+
+ ngx_processes[n].exiting = 1;
+ }
+}
+
+
+static void
+ngx_terminate_worker_processes(ngx_cycle_t *cycle)
+{
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ if (ngx_processes[n].handle == NULL) {
+ continue;
+ }
+
+ if (TerminateProcess(ngx_processes[n].handle, 0) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "TerminateProcess(\"%p\") failed",
+ ngx_processes[n].handle);
+ }
+
+ ngx_processes[n].exiting = 1;
+
+ ngx_close_handle(ngx_processes[n].reopen);
+ ngx_close_handle(ngx_processes[n].quit);
+ ngx_close_handle(ngx_processes[n].term);
+ ngx_close_handle(ngx_processes[n].handle);
+ }
+}
+
+
+static ngx_uint_t
+ngx_reap_worker(ngx_cycle_t *cycle, HANDLE h)
+{
+ u_long code;
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ if (ngx_processes[n].handle != h) {
+ continue;
+ }
+
+ if (GetExitCodeProcess(h, &code) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "GetExitCodeProcess(%P) failed",
+ ngx_processes[n].pid);
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
+ "%s process %P exited with code %Xul",
+ ngx_processes[n].name, ngx_processes[n].pid, code);
+
+ ngx_close_handle(ngx_processes[n].reopen);
+ ngx_close_handle(ngx_processes[n].quit);
+ ngx_close_handle(ngx_processes[n].term);
+ ngx_close_handle(h);
+
+ ngx_processes[n].handle = NULL;
+ ngx_processes[n].term = NULL;
+ ngx_processes[n].quit = NULL;
+ ngx_processes[n].reopen = NULL;
+
+ if (!ngx_processes[n].exiting && !ngx_terminate && !ngx_quit) {
+
+ if (ngx_spawn_process(cycle, ngx_processes[n].name, n)
+ == NGX_INVALID_PID)
+ {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "can not respawn %s", ngx_processes[n].name);
+
+ if (n == ngx_last_process - 1) {
+ ngx_last_process--;
+ }
+ }
+ }
+
+ goto found;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unknown process handle %p", h);
+
+found:
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "process: %d %P %p e:%d t:%d r:%d j:%d",
+ n,
+ ngx_processes[n].pid,
+ ngx_processes[n].handle,
+ ngx_processes[n].exiting,
+ ngx_processes[n].just_respawn);
+
+ if (ngx_processes[n].handle) {
+ return 1;
+ }
}
return 0;
@@ -120,164 +547,544 @@ ngx_worker_thread_cycle(void *data)
static void
-ngx_process_tray(ngx_cycle_t *cycle)
+ngx_master_process_exit(ngx_cycle_t *cycle)
{
- int rc;
- MSG message;
- HWND window;
- HMENU menu;
- HICON icon, tray;
- WNDCLASS wc;
- HINSTANCE instance;
-
- 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);
+ ngx_uint_t i;
+
+ ngx_delete_pidfile(cycle);
+
+ ngx_close_handle(ngx_cache_manager_mutex);
+ ngx_close_handle(ngx_stop_event);
+ ngx_close_handle(ngx_quit_event);
+ ngx_close_handle(ngx_reopen_event);
+ ngx_close_handle(ngx_reload_event);
+ ngx_close_handle(ngx_master_process_event);
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
+
+ for (i = 0; ngx_modules[i]; i++) {
+ if (ngx_modules[i]->exit_master) {
+ ngx_modules[i]->exit_master(cycle);
+ }
}
- tray = LoadIcon(instance, "tray");
- if (icon == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "LoadIcon(\"tray\") failed");
- /* fatal */
- exit(2);
+ ngx_destroy_pool(cycle->pool);
+
+ exit(0);
+}
+
+
+static void
+ngx_worker_process_cycle(ngx_cycle_t *cycle, char *mevn)
+{
+ char wtevn[NGX_PROCESS_SYNC_NAME];
+ char wqevn[NGX_PROCESS_SYNC_NAME];
+ char wroevn[NGX_PROCESS_SYNC_NAME];
+ HANDLE mev, events[3];
+ u_long nev, ev;
+ ngx_err_t err;
+ ngx_tid_t wtid, cmtid;
+ ngx_log_t *log;
+
+ log = cycle->log;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "worker started");
+
+ ngx_sprintf((u_char *) wtevn, "ngx_worker_term_%ul%Z", ngx_pid);
+ events[0] = CreateEvent(NULL, 1, 0, wtevn);
+ if (events[0] == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "CreateEvent(\"%s\") failed", wtevn);
+ goto failed;
}
- menu = LoadMenu(instance, "nginx");
- if (menu == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "LoadMenu() failed");
- /* fatal */
- exit(2);
+ ngx_sprintf((u_char *) wqevn, "ngx_worker_quit_%ul%Z", ngx_pid);
+ events[1] = CreateEvent(NULL, 1, 0, wqevn);
+ if (events[1] == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "CreateEvent(\"%s\") failed", wqevn);
+ goto failed;
}
- ngx_menu = GetSubMenu(menu, 0);
- if (ngx_menu == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "GetSubMenu() failed");
- /* fatal */
- exit(2);
+ ngx_sprintf((u_char *) wroevn, "ngx_worker_reopen_%ul%Z", ngx_pid);
+ events[2] = CreateEvent(NULL, 1, 0, wroevn);
+ if (events[2] == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "CreateEvent(\"%s\") failed", wroevn);
+ goto failed;
+ }
+
+ mev = OpenEvent(EVENT_MODIFY_STATE, 0, mevn);
+ if (mev == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "OpenEvent(\"%s\") failed", mevn);
+ goto failed;
}
+ if (SetEvent(mev) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "SetEvent(\"%s\") failed", mevn);
+ goto failed;
+ }
- 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);
+ ngx_sprintf((u_char *) ngx_cache_manager_mutex_name,
+ "ngx_cache_manager_mutex_%s%Z", ngx_unique);
+
+ ngx_cache_manager_mutex = OpenMutex(SYNCHRONIZE, 0,
+ ngx_cache_manager_mutex_name);
+ if (ngx_cache_manager_mutex == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "OpenMutex(\"%s\") failed", ngx_cache_manager_mutex_name);
+ goto failed;
}
- window = CreateWindow("nginx", "nginx", WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, instance, NULL);
+ ngx_cache_manager_event = CreateEvent(NULL, 1, 0, NULL);
+ if (ngx_cache_manager_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"ngx_cache_manager_event\") failed");
+ goto failed;
+ }
- if (window == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "CreateWindow() failed");
- /* fatal */
- exit(2);
+
+ if (ngx_create_thread(&wtid, ngx_worker_thread, NULL, log) != 0) {
+ goto failed;
}
+ if (ngx_create_thread(&cmtid, ngx_cache_manager_thread, NULL, log) != 0) {
+ goto failed;
+ }
- if (ngx_system_tray_icon(window, NIM_ADD, tray, (u_char *) " nginx")
- != NGX_OK)
- {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "Shell_NotifyIcon(NIM_ADD) failed");
- /* fatal */
- exit(2);
+ for ( ;; ) {
+ ev = WaitForMultipleObjects(3, events, 0, INFINITE);
+
+ err = ngx_errno;
+ ngx_time_update(0, 0);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
+ "worker WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_OBJECT_0) {
+ ngx_terminate = 1;
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "exiting");
+
+ if (ResetEvent(events[0]) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ "ResetEvent(\"%s\") failed", wtevn);
+ }
+
+ break;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 1) {
+ ngx_quit = 1;
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "gracefully shutting down");
+ break;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 2) {
+ ngx_reopen = 1;
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "reopening logs");
+
+ if (ResetEvent(events[2]) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ "ResetEvent(\"%s\") failed", wroevn);
+ }
+
+ continue;
+ }
+
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, log, err,
+ "WaitForMultipleObjects() failed");
+
+ goto failed;
+ }
+ }
+
+ /* wait threads */
+
+ if (SetEvent(ngx_cache_manager_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "SetEvent(\"ngx_cache_manager_event\") failed");
}
+ events[1] = wtid;
+ events[2] = cmtid;
+
+ nev = 3;
+
for ( ;; ) {
- rc = GetMessage(&message, NULL, 0, 0);
+ ev = WaitForMultipleObjects(nev, events, 0, INFINITE);
- if (rc == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "GetMessage() failed");
+ err = ngx_errno;
+ ngx_time_update(0, 0);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
+ "worker exit WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_OBJECT_0) {
+ break;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 1) {
+ if (nev == 2) {
+ break;
+ }
+
+ events[1] = events[2];
+ nev = 2;
continue;
}
- if (rc == 0) {
- exit(0);
+ if (ev == WAIT_OBJECT_0 + 2) {
+ nev = 2;
+ continue;
}
- TranslateMessage(&message);
- DispatchMessage(&message);
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, log, err,
+ "WaitForMultipleObjects() failed");
+ break;
+ }
}
+
+ ngx_close_handle(ngx_cache_manager_event);
+ ngx_close_handle(events[0]);
+ ngx_close_handle(events[1]);
+ ngx_close_handle(events[2]);
+ ngx_close_handle(mev);
+
+ ngx_worker_process_exit(cycle);
+
+failed:
+
+ exit(2);
}
-static long __stdcall
-ngx_window_procedure(HWND window, u_int message, u_int wparam, long lparam)
+static ngx_thread_value_t __stdcall
+ngx_worker_thread(void *data)
{
- POINT mouse;
+ ngx_int_t n;
+ ngx_uint_t i;
+ ngx_cycle_t *cycle;
+ ngx_connection_t *c;
- switch (message) {
+ cycle = (ngx_cycle_t *) ngx_cycle;
- 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;
+ ngx_init_temp_number();
+
+ for (n = 0; ngx_modules[n]; n++) {
+ if (ngx_modules[n]->init_process) {
+ if (ngx_modules[n]->init_process(cycle) == NGX_ERROR) {
+ /* fatal */
+ exit(2);
}
+ }
+ }
+
+ while (!ngx_quit) {
+
+ if (ngx_exiting) {
+
+ c = cycle->connections;
- if (SetForegroundWindow(window) == 0) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- "SetForegroundWindow() failed");
- return 0;
+ for (i = 0; i < cycle->connection_n; i++) {
+
+ /* THREAD: lock */
+
+ if (c[i].fd != -1 && c[i].idle) {
+ c[i].close = 1;
+ c[i].read->handler(c[i].read);
+ }
}
- if (TrackPopupMenu(ngx_menu, TPM_RIGHTBUTTON,
- mouse.x, mouse.y, 0, window, NULL)
- == 0)
+ if (ngx_event_timer_rbtree.root
+ == ngx_event_timer_rbtree.sentinel)
{
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- "TrackPopupMenu() failed");
- return 0;
+ break;
}
}
- return 0;
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "worker cycle");
- case WM_COMMAND:
- if (wparam == NGX_WM_ABOUT) {
- ngx_message_box("nginx", MB_OK, 0,
- NGINX_VER CRLF "(C) 2002-2009 Igor Sysoev");
+ ngx_process_events_and_timers(cycle);
+
+ if (ngx_terminate) {
return 0;
}
- if (wparam == NGX_WM_EXIT) {
- if (ngx_system_tray_icon(window, NIM_DELETE, NULL, NULL)
- != NGX_OK)
+ if (ngx_quit) {
+ ngx_quit = 0;
+
+ if (!ngx_exiting) {
+ ngx_close_listening_sockets(cycle);
+ ngx_exiting = 1;
+ }
+ }
+
+ if (ngx_reopen) {
+ ngx_reopen = 0;
+ ngx_reopen_files(cycle, -1);
+ }
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+
+ return 0;
+}
+
+
+static void
+ngx_worker_process_exit(ngx_cycle_t *cycle)
+{
+ ngx_uint_t i;
+ ngx_connection_t *c;
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
+
+ for (i = 0; ngx_modules[i]; i++) {
+ if (ngx_modules[i]->exit_process) {
+ ngx_modules[i]->exit_process(cycle);
+ }
+ }
+
+ if (ngx_exiting) {
+ c = cycle->connections;
+ for (i = 0; i < cycle->connection_n; i++) {
+ if (c[i].fd != -1
+ && c[i].read
+ && !c[i].read->accept
+ && !c[i].read->channel
+ && !c[i].read->resolver)
{
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- "Shell_NotifyIcon(NIM_DELETE) failed");
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "open socket #%d left in connection %ui",
+ c[i].fd, i);
}
}
+ }
- PostQuitMessage(0);
+ ngx_destroy_pool(cycle->pool);
- return 0;
+ exit(0);
+}
- default:
- return DefWindowProc(window, message, wparam, lparam);
+
+static ngx_thread_value_t __stdcall
+ngx_cache_manager_thread(void *data)
+{
+ u_long ev;
+ HANDLE events[2];
+ ngx_err_t err;
+ ngx_cycle_t *cycle;
+
+ cycle = (ngx_cycle_t *) ngx_cycle;
+
+ events[0] = ngx_cache_manager_event;
+ events[1] = ngx_cache_manager_mutex;
+
+ for ( ;; ) {
+ ev = WaitForMultipleObjects(2, events, 0, INFINITE);
+
+ err = ngx_errno;
+ ngx_time_update(0, 0);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "cache manager WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "WaitForMultipleObjects() failed");
+ }
+
+ /*
+ * ev == WAIT_OBJECT_0
+ * ev == WAIT_OBJECT_0 + 1
+ * ev == WAIT_ABANDONED_0 + 1
+ */
+
+ if (ngx_terminate || ngx_quit) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+ return 0;
+ }
+
+ break;
+ }
+
+ for ( ;; ) {
+
+ if (ngx_terminate || ngx_quit) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+ break;
+ }
+
+ ngx_cache_manager_process_handler();
+ }
+
+ if (ReleaseMutex(ngx_cache_manager_mutex) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "ReleaseMutex() failed");
+ }
+
+ return 0;
+}
+
+
+static void
+ngx_cache_manager_process_handler(void)
+{
+ u_long ev;
+ time_t next, n;
+ ngx_uint_t i;
+ ngx_path_t **path;
+
+ next = 60 * 60;
+
+ path = ngx_cycle->pathes.elts;
+ for (i = 0; i < ngx_cycle->pathes.nelts; i++) {
+
+ if (path[i]->manager) {
+ n = path[i]->manager(path[i]->data);
+
+ next = (n <= next) ? n : next;
+
+ ngx_time_update(0, 0);
+ }
+ }
+
+ if (next == 0) {
+ next = 1;
+ }
+
+ ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next * 1000);
+
+ if (ev != WAIT_TIMEOUT) {
+
+ ngx_time_update(0, 0);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
+ "cache manager WaitForSingleObject: %ul", ev);
+ }
+}
+
+
+void
+ngx_single_process_cycle(ngx_cycle_t *cycle)
+{
+ ngx_int_t i;
+ ngx_tid_t tid;
+
+ ngx_init_temp_number();
+
+ for (i = 0; ngx_modules[i]; i++) {
+ if (ngx_modules[i]->init_process) {
+ if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
+ /* fatal */
+ exit(2);
+ }
+ }
+ }
+
+ ngx_process_init(cycle);
+
+ ngx_console_init(cycle);
+
+ if (ngx_create_events(cycle) != NGX_OK) {
+ exit(2);
+ }
+
+ if (ngx_create_thread(&tid, ngx_worker_thread, NULL, cycle->log) != 0) {
+ /* fatal */
+ exit(2);
+ }
+
+ /* STUB */
+ WaitForSingleObject(ngx_stop_event, INFINITE);
+}
+
+
+ngx_int_t
+ngx_signal_process(ngx_cycle_t *cycle, char *sig)
+{
+ size_t n;
+ HANDLE ev;
+ ngx_int_t rc, pid;
+ ngx_file_t file;
+ ngx_core_conf_t *ccf;
+ u_char buf[NGX_INT64_LEN + 2];
+ char evn[NGX_PROCESS_SYNC_NAME];
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ file.name = ccf->pid;
+ file.log = cycle->log;
+
+ file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
+ NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
+
+ if (file.fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", file.name.data);
+ return 1;
+ }
+
+ rc = 1;
+
+ n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
+
+ if (n == NGX_ERROR) {
+ goto failed;
+ }
+
+ while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
+
+ pid = ngx_atoi(buf, ++n);
+
+ if (pid == NGX_ERROR) {
+ ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
+ "invalid PID number \"%*s\" in \"%s\"",
+ n, buf, file.name.data);
+ goto failed;
+ }
+
+ ngx_sprintf((u_char *) evn, "ngx_%s_%ul%Z", sig, pid);
+
+ ev = OpenEvent(EVENT_MODIFY_STATE, 0, evn);
+ if (ev == NULL) {
+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed", evn);
+ goto failed;
+ }
+
+ if (SetEvent(ev) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetEvent(\"%s\") failed", evn);
+ } else {
+ rc = 0;
+ }
+
+ ngx_close_handle(ev);
+
+failed:
+
+ if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", file.name.data);
+ }
+
+ return rc;
+}
+
+
+void
+ngx_close_handle(HANDLE h)
+{
+ if (CloseHandle(h) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
+ "CloseHandle(%p) failed", h);
}
}
diff --git a/src/os/win32/ngx_process_cycle.h b/src/os/win32/ngx_process_cycle.h
index e80af0a2f..d9ed30b1a 100644
--- a/src/os/win32/ngx_process_cycle.h
+++ b/src/os/win32/ngx_process_cycle.h
@@ -12,30 +12,33 @@
#include <ngx_core.h>
-#define NGX_PROCESS_SINGLE 0
-#define NGX_PROCESS_MASTER 1
-#define NGX_PROCESS_WORKER 2
+#define NGX_PROCESS_SINGLE 0
+#define NGX_PROCESS_MASTER 1
+#define NGX_PROCESS_WORKER 2
+#define NGX_PROCESS_SIGNALLER 3
void ngx_master_process_cycle(ngx_cycle_t *cycle);
void ngx_single_process_cycle(ngx_cycle_t *cycle);
+ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig);
+void ngx_close_handle(HANDLE h);
extern ngx_uint_t ngx_process;
extern ngx_pid_t ngx_pid;
-extern ngx_pid_t ngx_new_binary;
-extern ngx_uint_t ngx_inherited;
extern ngx_uint_t ngx_threaded;
extern ngx_uint_t ngx_exiting;
-extern sig_atomic_t ngx_reap;
-extern sig_atomic_t ngx_timer;
extern sig_atomic_t ngx_quit;
extern sig_atomic_t ngx_terminate;
-extern sig_atomic_t ngx_noaccept;
-extern sig_atomic_t ngx_reconfigure;
extern sig_atomic_t ngx_reopen;
-extern sig_atomic_t ngx_change_binary;
+
+extern ngx_uint_t ngx_inherited;
+extern ngx_pid_t ngx_new_binary;
+
+
+extern HANDLE ngx_master_process_event;
+extern char ngx_master_process_event_name[];
#endif /* _NGX_PROCESS_CYCLE_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_thread.c b/src/os/win32/ngx_thread.c
index f8cedd2a5..120ce8673 100644
--- a/src/os/win32/ngx_thread.c
+++ b/src/os/win32/ngx_thread.c
@@ -18,11 +18,14 @@ ngx_err_t
ngx_create_thread(ngx_tid_t *tid,
ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log)
{
+ u_long id;
ngx_err_t err;
- *tid = CreateThread(NULL, stack_size, func, arg, 0, NULL);
+ *tid = CreateThread(NULL, stack_size, func, arg, 0, &id);
if (*tid != NULL) {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0,
+ "create thread " NGX_TID_T_FMT, id);
return 0;
}
diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c
index f451311ce..e64ce39fc 100644
--- a/src/os/win32/ngx_win32_init.c
+++ b/src/os/win32/ngx_win32_init.c
@@ -24,7 +24,7 @@ ngx_os_io_t ngx_os_io = {
ngx_wsarecv,
ngx_wsarecv_chain,
ngx_udp_wsarecv,
- NULL,
+ ngx_wsasend,
ngx_wsasend_chain,
0
};
@@ -56,7 +56,8 @@ static GUID cx_guid = WSAID_CONNECTEX;
static GUID dx_guid = WSAID_DISCONNECTEX;
-ngx_int_t ngx_os_init(ngx_log_t *log)
+ngx_int_t
+ngx_os_init(ngx_log_t *log)
{
DWORD bytes;
SOCKET s;
@@ -207,7 +208,7 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
ngx_close_socket_n " failed");
}
- if (GetEnvironmentVariable("nginx_unique", ngx_unique, NGX_INT32_LEN + 1)
+ if (GetEnvironmentVariable("ngx_unique", ngx_unique, NGX_INT32_LEN + 1)
!= 0)
{
ngx_process = NGX_PROCESS_WORKER;
@@ -217,7 +218,7 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
if (err != ERROR_ENVVAR_NOT_FOUND) {
ngx_log_error(NGX_LOG_EMERG, log, err,
- "GetEnvironmentVariable(\"nginx_unique\") failed");
+ "GetEnvironmentVariable(\"ngx_unique\") failed");
return NGX_ERROR;
}
@@ -228,7 +229,8 @@ ngx_int_t ngx_os_init(ngx_log_t *log)
}
-void ngx_os_status(ngx_log_t *log)
+void
+ngx_os_status(ngx_log_t *log)
{
ngx_osviex_stub_t *osviex_stub;
diff --git a/src/os/win32/ngx_wsasend.c b/src/os/win32/ngx_wsasend.c
new file mode 100644
index 000000000..e038a2eda
--- /dev/null
+++ b/src/os/win32/ngx_wsasend.c
@@ -0,0 +1,183 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t
+ngx_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int n;
+ u_long sent;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ WSABUF wsabuf;
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return NGX_AGAIN;
+ }
+
+ /*
+ * WSABUF must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ wsabuf.buf = (char *) buf;
+ wsabuf.len = size;
+
+ sent = 0;
+
+ n = WSASend(c->fd, &wsabuf, 1, &sent, 0, NULL, NULL);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size);
+
+ if (n == 0) {
+ if (sent < size) {
+ wev->ready = 0;
+ }
+
+ c->sent += sent;
+
+ return sent;
+ }
+
+ err = ngx_socket_errno;
+
+ if (err == WSAEWOULDBLOCK) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "WSASend() not ready");
+ return NGX_AGAIN;
+ }
+
+ wev->error = 1;
+ ngx_connection_error(c, err, "WSASend() failed");
+
+ return NGX_ERROR;
+}
+
+
+ssize_t
+ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int n;
+ u_long sent;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ LPWSAOVERLAPPED ovlp;
+ WSABUF wsabuf;
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return NGX_AGAIN;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "wev->complete: %d", wev->complete);
+
+ if (!wev->complete) {
+
+ /* post the overlapped WSASend() */
+
+ /*
+ * WSABUFs must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ wsabuf.buf = (char *) buf;
+ wsabuf.len = size;
+
+ sent = 0;
+
+ ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+
+ n = WSASend(c->fd, &wsabuf, 1, &sent, 0, ovlp, NULL);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size);
+
+ wev->complete = 0;
+
+ if (n == 0) {
+ 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 NGX_AGAIN;
+ }
+
+ if (sent < size) {
+ wev->ready = 0;
+ }
+
+ c->sent += sent;
+
+ return sent;
+ }
+
+ err = ngx_socket_errno;
+
+ if (err == WSA_IO_PENDING) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSASend() posted");
+ wev->active = 1;
+ return NGX_AGAIN;
+ }
+
+ wev->error = 1;
+ ngx_connection_error(c, err, "WSASend() failed");
+
+ return NGX_ERROR;
+ }
+
+ /* the overlapped WSASend() complete */
+
+ wev->complete = 0;
+ wev->active = 0;
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ if (wev->ovlp.error) {
+ ngx_connection_error(c, wev->ovlp.error, "WSASend() failed");
+ return NGX_ERROR;
+ }
+
+ sent = wev->available;
+
+ } else {
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp,
+ &sent, 0, NULL)
+ == 0)
+ {
+ ngx_connection_error(c, ngx_socket_errno,
+ "WSASend() or WSAGetOverlappedResult() failed");
+
+ return NGX_ERROR;
+ }
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSAGetOverlappedResult: fd:%d, %ul of %uz",
+ c->fd, sent, size);
+
+ if (sent < size) {
+ wev->ready = 0;
+ }
+
+ c->sent += sent;
+
+ return sent;
+}