Win32 master/workers model

This commit is contained in:
Igor Sysoev 2009-04-20 06:08:47 +00:00
parent b533e98252
commit bd91999ea5
25 changed files with 1704 additions and 461 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -557,29 +557,31 @@ 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);
c->fd = (ngx_socket_t) -1;
}
ngx_free_connection(c);
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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

View File

@ -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 ",
" "
};

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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 {
char *path;
char *name;
char *const *argv;
char *const *envp;
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;
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)
extern int ngx_argc;
extern char **ngx_argv;
extern char **ngx_os_argv;
#define NGX_MAX_PROCESSES (MAXIMUM_WAIT_OBJECTS - 4)
extern ngx_pid_t ngx_pid;
#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 ngx_int_t ngx_last_process;
extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
extern ngx_pid_t ngx_pid;
#endif /* _NGX_PROCESS_H_INCLUDED_ */

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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;

183
src/os/win32/ngx_wsasend.c Normal file
View File

@ -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;
}