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
path: root/src/core
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2006-02-08 18:33:12 +0300
committerIgor Sysoev <igor@sysoev.ru>2006-02-08 18:33:12 +0300
commitffe714403d604b385c89daa7fe5a83860a672a54 (patch)
tree24ce46a2354a79212f91fdbc3d6045ea340c3f12 /src/core
parent2446d5d6adf67d81883024ffb20ec21d146c0450 (diff)
nginx-0.3.27-RELEASE importrelease-0.3.27
*) Change: the "variables_hash_max_size" and "variables_hash_bucket_size" directives. *) Feature: the $body_bytes_sent variable can be used not only in the "log_format" directive. *) Feature: the $ssl_protocol and $ssl_cipher variables. *) Feature: the cache line size detection for widespread CPUs at start time. *) Feature: now the "accept_mutex" directive is supported using fcntl(2) on platforms different from i386, amd64, sparc64, and ppc. *) Feature: the "lock_file" directive and the --with-lock-path=PATH autoconfiguration directive. *) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive then the requests with the body was not transferred.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/nginx.c32
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_connection.c3
-rw-r--r--src/core/ngx_core.h3
-rw-r--r--src/core/ngx_cpuinfo.c93
-rw-r--r--src/core/ngx_cycle.c452
-rw-r--r--src/core/ngx_cycle.h5
-rw-r--r--src/core/ngx_shmtx.c70
-rw-r--r--src/core/ngx_shmtx.h111
-rw-r--r--src/core/ngx_spinlock.c33
10 files changed, 555 insertions, 249 deletions
diff --git a/src/core/nginx.c b/src/core/nginx.c
index a9a0dd905..64f801205 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -58,6 +58,13 @@ static ngx_command_t ngx_core_commands[] = {
offsetof(ngx_core_conf_t, pid),
NULL },
+ { ngx_string("lock_file"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ 0,
+ offsetof(ngx_core_conf_t, lock_file),
+ NULL },
+
{ ngx_string("worker_processes"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
@@ -214,11 +221,11 @@ main(int argc, char *const *argv)
return 1;
}
- if (ngx_save_argv(&init_cycle, argc, argv) == NGX_ERROR) {
+ if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
return 1;
}
- if (ngx_getopt(&init_cycle, argc, ngx_argv) == NGX_ERROR) {
+ if (ngx_getopt(&init_cycle, argc, ngx_argv) != NGX_OK) {
return 1;
}
@@ -226,11 +233,11 @@ main(int argc, char *const *argv)
log->log_level = NGX_LOG_INFO;
}
- if (ngx_os_init(log) == NGX_ERROR) {
+ if (ngx_os_init(log) != NGX_OK) {
return 1;
}
- if (ngx_add_inherited_sockets(&init_cycle) == NGX_ERROR) {
+ if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
return 1;
}
@@ -274,7 +281,7 @@ main(int argc, char *const *argv)
TODO:
if (ccf->run_as_service) {
- if (ngx_service(cycle->log) == NGX_ERROR) {
+ if (ngx_service(cycle->log) != NGX_OK) {
return 1;
}
@@ -284,19 +291,19 @@ main(int argc, char *const *argv)
#else
- if (ngx_init_signals(cycle->log) == NGX_ERROR) {
+ if (ngx_init_signals(cycle->log) != NGX_OK) {
return 1;
}
if (!ngx_inherited && ccf->daemon) {
- if (ngx_daemon(cycle->log) == NGX_ERROR) {
+ if (ngx_daemon(cycle->log) != NGX_OK) {
return 1;
}
ngx_daemonized = 1;
}
- if (ngx_create_pidfile(cycle, NULL) == NGX_ERROR) {
+ if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return 1;
}
@@ -666,6 +673,15 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
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;
+ ccf->lock_file.data = (u_char *) NGX_LOCK_PATH;
+ }
+
+ if (ngx_conf_full_name(cycle, &ccf->lock_file) == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
#endif
return NGX_CONF_OK;
diff --git a/src/core/nginx.h b/src/core/nginx.h
index c8ddddbd9..74ba8095d 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VER "nginx/0.3.26"
+#define NGINX_VER "nginx/0.3.27"
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 75604284f..abc006f0c 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -495,7 +495,7 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
}
ngx_accept_mutex_held = 0;
- ngx_accept_mutex = NULL;
+ ngx_use_accept_mutex = 0;
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
@@ -726,7 +726,6 @@ ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
|| err == NGX_ECONNREFUSED
|| err == NGX_EHOSTUNREACH)
{
-
switch (c->log_error) {
case NGX_ERROR_IGNORE_ECONNRESET:
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index 46e88df88..1779513e1 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -62,6 +62,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
#endif
#include <ngx_radix_tree.h>
#include <ngx_times.h>
+#include <ngx_shmtx.h>
#include <ngx_inet.h>
#if (NGX_HAVE_UNIX_DOMAIN)
#include <ngx_unix_domain.h>
@@ -83,5 +84,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
#define ngx_abs(value) (((value) >= 0) ? (value) : - (value))
+void ngx_cpuinfo(void);
+
#endif /* _NGX_CORE_H_INCLUDED_ */
diff --git a/src/core/ngx_cpuinfo.c b/src/core/ngx_cpuinfo.c
new file mode 100644
index 000000000..a939635f8
--- /dev/null
+++ b/src/core/ngx_cpuinfo.c
@@ -0,0 +1,93 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (( __i386__ || __amd64__ ) && ( __GNUC__ || __INTEL_COMPILER ))
+
+
+static ngx_inline void ngx_cpuid(uint32_t i, uint32_t *buf);
+
+
+static ngx_inline void
+ngx_cpuid(uint32_t i, uint32_t *buf)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ __asm__ (
+
+ "cpuid"
+
+ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
+
+ buf[0] = eax;
+ buf[1] = ebx;
+ buf[2] = edx;
+ buf[3] = ecx;
+}
+
+
+/* auto detect the L2 cache line size of modern and widespread CPUs */
+
+void
+ngx_cpuinfo(void)
+{
+ u_char *vendor;
+ uint32_t vbuf[5], cpu[4];
+
+ vbuf[0] = 0;
+ vbuf[1] = 0;
+ vbuf[2] = 0;
+ vbuf[3] = 0;
+ vbuf[4] = 0;
+
+ ngx_cpuid(0, vbuf);
+
+ vendor = (u_char *) &vbuf[1];
+
+ if (vbuf[0] == 0) {
+ return;
+ }
+
+ ngx_cpuid(1, cpu);
+
+ if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
+
+ switch (cpu[0] & 0xf00) {
+
+ /* Pentium */
+ case 5:
+ /* Pentium Pro, II, III */
+ case 6:
+ ngx_cacheline_size = 32;
+ break;
+
+ /*
+ * Pentium 4, although its cache line size is 64 bytes,
+ * it prefetches up to two cache lines during memory read
+ */
+ case 15:
+ ngx_cacheline_size = 128;
+ break;
+ }
+
+ } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
+ ngx_cacheline_size = 64;
+ }
+}
+
+#else
+
+
+void
+ngx_cpuinfo(void)
+{
+}
+
+
+#endif
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index b5941be6f..baf25ea95 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -9,6 +9,7 @@
#include <ngx_event.h>
+static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2);
static void ngx_clean_old_cycles(ngx_event_t *ev);
@@ -42,7 +43,7 @@ ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
void *rv;
- ngx_uint_t i, n, failed;
+ ngx_uint_t i, n;
ngx_log_t *log;
ngx_conf_t conf;
ngx_pool_t *pool;
@@ -52,7 +53,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
ngx_listening_t *ls, *nls;
ngx_core_conf_t *ccf;
ngx_core_module_t *module;
-
+#if !(WIN32)
+ ngx_core_conf_t *old_ccf;
+#endif
log = old_cycle->log;
@@ -236,82 +239,100 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
}
- failed = 0;
-
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
#if !(NGX_WIN32)
- if (ngx_create_pidfile(cycle, old_cycle) == NGX_ERROR) {
- failed = 1;
- }
-#endif
+ if (ngx_test_config) {
+
+ if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
+ goto failed;
+ }
- if (!failed) {
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
- ngx_core_module);
+ } else if (!ngx_is_init_cycle(old_cycle)) {
- if (ngx_create_pathes(cycle, ccf->user) == NGX_ERROR) {
- failed = 1;
+ /*
+ * we do not create the pid file in the first ngx_init_cycle() call
+ * because we need to write the demonized process pid
+ */
+
+ old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
+ ngx_core_module);
+ if (ccf->pid.len != old_ccf->pid.len
+ || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
+ {
+ /* new pid file name */
+
+ if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
+ goto failed;
+ }
+
+ ngx_delete_pidfile(old_cycle);
}
}
+#endif
- if (!failed) {
- /* open the new files */
+ if (ngx_test_lockfile(ccf->lock_file.data, log) != NGX_OK) {
+ goto failed;
+ }
- part = &cycle->open_files.part;
- file = part->elts;
- for (i = 0; /* void */ ; i++) {
+ if (ngx_create_pathes(cycle, ccf->user) != NGX_OK) {
+ goto failed;
+ }
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
- if (file[i].name.data == NULL) {
- continue;
- }
+ /* open the new files */
- file[i].fd = ngx_open_file(file[i].name.data,
- NGX_FILE_RDWR,
- NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND);
+ part = &cycle->open_files.part;
+ file = part->elts;
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
- "log: %p %d \"%s\"",
- &file[i], file[i].fd, file[i].name.data);
+ for (i = 0; /* void */ ; i++) {
- if (file[i].fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_open_file_n " \"%s\" failed",
- file[i].name.data);
- failed = 1;
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
break;
}
+ part = part->next;
+ file = part->elts;
+ i = 0;
+ }
+
+ if (file[i].name.data == NULL) {
+ continue;
+ }
+
+ file[i].fd = ngx_open_file(file[i].name.data, NGX_FILE_RDWR,
+ NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND);
+
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
+ "log: %p %d \"%s\"",
+ &file[i], file[i].fd, file[i].name.data);
+
+ if (file[i].fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed",
+ file[i].name.data);
+ goto failed;
+ }
#if (NGX_WIN32)
- if (ngx_file_append_mode(file[i].fd) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_file_append_mode_n " \"%s\" failed",
- file[i].name.data);
- failed = 1;
- break;
- }
+ if (ngx_file_append_mode(file[i].fd) != NGX_OK) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ ngx_file_append_mode_n " \"%s\" failed",
+ file[i].name.data);
+ goto failed;
+ }
#else
- if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "fcntl(FD_CLOEXEC) \"%s\" failed",
- file[i].name.data);
- failed = 1;
- break;
- }
-#endif
+ if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "fcntl(FD_CLOEXEC) \"%s\" failed",
+ file[i].name.data);
+ goto failed;
}
+#endif
}
cycle->log = cycle->new_log;
@@ -321,159 +342,100 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
cycle->log->log_level = NGX_LOG_ERR;
}
- if (!failed) {
- /* handle the listening sockets */
+ /* handle the listening sockets */
- if (old_cycle->listening.nelts) {
- ls = old_cycle->listening.elts;
- for (i = 0; i < old_cycle->listening.nelts; i++) {
- ls[i].remain = 0;
- }
+ if (old_cycle->listening.nelts) {
+ ls = old_cycle->listening.elts;
+ for (i = 0; i < old_cycle->listening.nelts; i++) {
+ ls[i].remain = 0;
+ }
- nls = cycle->listening.elts;
- for (n = 0; n < cycle->listening.nelts; n++) {
+ nls = cycle->listening.elts;
+ for (n = 0; n < cycle->listening.nelts; n++) {
- for (i = 0; i < old_cycle->listening.nelts; i++) {
- if (ls[i].ignore) {
- continue;
- }
+ for (i = 0; i < old_cycle->listening.nelts; i++) {
+ if (ls[i].ignore) {
+ continue;
+ }
- if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr)
- == NGX_OK)
- {
- nls[n].fd = ls[i].fd;
- nls[n].previous = &ls[i];
- ls[i].remain = 1;
+ if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK)
+ {
+ nls[n].fd = ls[i].fd;
+ nls[n].previous = &ls[i];
+ ls[i].remain = 1;
- if (ls[n].backlog != nls[i].backlog) {
- nls[n].listen = 1;
- }
+ if (ls[n].backlog != nls[i].backlog) {
+ nls[n].listen = 1;
+ }
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- /*
- * FreeBSD, except the most recent versions,
- * could not remove accept filter
- */
- nls[n].deferred_accept = ls[i].deferred_accept;
-
- if (ls[i].accept_filter && nls[n].accept_filter) {
- if (ngx_strcmp(ls[i].accept_filter,
- nls[n].accept_filter) != 0)
- {
- nls[n].delete_deferred = 1;
- nls[n].add_deferred = 1;
- }
-
- } else if (ls[i].accept_filter) {
- nls[n].delete_deferred = 1;
+ /*
+ * FreeBSD, except the most recent versions,
+ * could not remove accept filter
+ */
+ nls[n].deferred_accept = ls[i].deferred_accept;
- } else if (nls[n].accept_filter) {
- nls[n].add_deferred = 1;
- }
-#endif
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
-
- if (ls[n].deferred_accept && !nls[n].deferred_accept) {
- nls[n].delete_deferred = 1;
-
- } else if (ls[i].deferred_accept
- != nls[n].deferred_accept)
+ if (ls[i].accept_filter && nls[n].accept_filter) {
+ if (ngx_strcmp(ls[i].accept_filter,
+ nls[n].accept_filter)
+ != 0)
{
+ nls[n].delete_deferred = 1;
nls[n].add_deferred = 1;
}
-#endif
- break;
- }
- }
- if (nls[n].fd == -1) {
- nls[n].open = 1;
- }
- }
+ } else if (ls[i].accept_filter) {
+ nls[n].delete_deferred = 1;
- } else {
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
- ls[i].open = 1;
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- if (ls[i].accept_filter) {
- ls[i].add_deferred = 1;
- }
-#endif
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- if (ls[i].deferred_accept) {
- ls[i].add_deferred = 1;
- }
+ } else if (nls[n].accept_filter) {
+ nls[n].add_deferred = 1;
+ }
#endif
- }
- }
- if (!failed) {
- if (ngx_open_listening_sockets(cycle) == NGX_ERROR) {
- failed = 1;
- }
-
- if (!ngx_test_config && !failed) {
- ngx_configure_listening_socket(cycle);
- }
- }
- }
-
-
- if (failed) {
-
- /* rollback the new cycle configuration */
-
- part = &cycle->open_files.part;
- file = part->elts;
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- for (i = 0; /* void */ ; i++) {
+ if (ls[n].deferred_accept && !nls[n].deferred_accept) {
+ nls[n].delete_deferred = 1;
- if (i >= part->nelts) {
- if (part->next == NULL) {
+ } else if (ls[i].deferred_accept != nls[n].deferred_accept)
+ {
+ nls[n].add_deferred = 1;
+ }
+#endif
break;
}
- part = part->next;
- file = part->elts;
- i = 0;
- }
-
- if (file[i].fd == NGX_INVALID_FILE
- || file[i].fd == ngx_stderr_fileno)
- {
- continue;
}
- if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
+ if (nls[n].fd == -1) {
+ nls[n].open = 1;
}
}
- if (ngx_test_config) {
- ngx_destroy_cycle_pools(&conf);
- return NULL;
- }
-
+ } else {
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
- if (ls[i].fd == -1 || !ls[i].open) {
- continue;
+ ls[i].open = 1;
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+ if (ls[i].accept_filter) {
+ ls[i].add_deferred = 1;
}
-
- if (ngx_close_socket(ls[i].fd) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_close_socket_n " %V failed",
- &ls[i].addr_text);
+#endif
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+ if (ls[i].deferred_accept) {
+ ls[i].add_deferred = 1;
}
+#endif
}
+ }
- ngx_destroy_cycle_pools(&conf);
- return NULL;
+ if (ngx_open_listening_sockets(cycle) != NGX_OK) {
+ goto failed;
+ }
+
+ if (!ngx_test_config) {
+ ngx_configure_listening_socket(cycle);
}
@@ -488,7 +450,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
cycle->log->file,
cycle->log->file->fd, cycle->log->file->name.data);
- if (dup2(cycle->log->file->fd, STDERR_FILENO) == NGX_ERROR) {
+ if (dup2(cycle->log->file->fd, STDERR_FILENO) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"dup2(STDERR) failed");
/* fatal */
@@ -502,7 +464,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_module) {
- if (ngx_modules[i]->init_module(cycle) == NGX_ERROR) {
+ if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
/* fatal */
exit(1);
}
@@ -564,6 +526,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
}
ngx_destroy_pool(old_cycle->pool);
+
+ cycle->old_cycle = NULL;
+
return cycle;
}
@@ -607,6 +572,58 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
}
return cycle;
+
+
+failed:
+
+ /* rollback the new cycle configuration */
+
+ part = &cycle->open_files.part;
+ file = part->elts;
+
+ for (i = 0; /* void */ ; i++) {
+
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+ part = part->next;
+ file = part->elts;
+ i = 0;
+ }
+
+ if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr_fileno) {
+ continue;
+ }
+
+ if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed",
+ file[i].name.data);
+ }
+ }
+
+ if (ngx_test_config) {
+ ngx_destroy_cycle_pools(&conf);
+ return NULL;
+ }
+
+ ls = cycle->listening.elts;
+ for (i = 0; i < cycle->listening.nelts; i++) {
+ if (ls[i].fd == -1 || !ls[i].open) {
+ continue;
+ }
+
+ if (ngx_close_socket(ls[i].fd) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
+ ngx_close_socket_n " %V failed",
+ &ls[i].addr_text);
+ }
+ }
+
+ ngx_destroy_cycle_pools(&conf);
+
+ return NULL;
}
@@ -651,52 +668,25 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2)
#if !(NGX_WIN32)
ngx_int_t
-ngx_create_pidfile(ngx_cycle_t *cycle, ngx_cycle_t *old_cycle)
+ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
{
- ngx_uint_t trunc;
size_t len;
- u_char pid[NGX_INT64_LEN];
+ ngx_uint_t trunc;
ngx_file_t file;
- ngx_core_conf_t *ccf, *old_ccf;
-
- if (!ngx_test_config && ngx_is_init_cycle(old_cycle)) {
-
- /*
- * do not create the pid file in the first ngx_init_cycle() call
- * because we need to write the demonized process pid
- */
-
- return NGX_OK;
- }
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (!ngx_test_config && old_cycle) {
- old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
- ngx_core_module);
-
- if (ccf->pid.len == old_ccf->pid.len
- && ngx_strcmp(ccf->pid.data, old_ccf->pid.data) == 0)
- {
-
- /* pid file name is the same */
-
- return NGX_OK;
- }
- }
+ u_char pid[NGX_INT64_LEN];
ngx_memzero(&file, sizeof(ngx_file_t));
- file.name = ccf->pid;
- file.log = cycle->log;
+ file.name = *name;
+ file.log = log;
- trunc = ngx_test_config ? 0: NGX_FILE_TRUNCATE;
+ trunc = ngx_test_config ? 0 : NGX_FILE_TRUNCATE;
file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR,
NGX_FILE_CREATE_OR_OPEN|trunc);
if (file.fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
ngx_open_file_n " \"%s\" failed", file.name.data);
return NGX_ERROR;
}
@@ -710,12 +700,10 @@ ngx_create_pidfile(ngx_cycle_t *cycle, ngx_cycle_t *old_cycle)
}
if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_close_file_n " \"%s\" failed", file.name.data);
}
- ngx_delete_pidfile(old_cycle);
-
return NGX_OK;
}
@@ -726,10 +714,6 @@ ngx_delete_pidfile(ngx_cycle_t *cycle)
u_char *name;
ngx_core_conf_t *ccf;
- if (cycle == NULL || cycle->conf_ctx == NULL) {
- return;
- }
-
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data;
@@ -743,6 +727,36 @@ ngx_delete_pidfile(ngx_cycle_t *cycle)
#endif
+static ngx_int_t
+ngx_test_lockfile(u_char *file, ngx_log_t *log)
+{
+#if !(NGX_HAVE_ATOMIC_OPS)
+ ngx_fd_t fd;
+
+ fd = ngx_open_file(file, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN);
+
+ if (fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", file);
+ return NGX_ERROR;
+ }
+
+ if (ngx_close_file(fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", file);
+ }
+
+ if (ngx_delete_file(file) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed", file);
+ }
+
+#endif
+
+ return NGX_OK;
+}
+
+
void
ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
{
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index b29cf3495..ad92ff2df 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -77,6 +77,7 @@ typedef struct {
ngx_gid_t group;
ngx_str_t working_directory;
+ ngx_str_t lock_file;
ngx_str_t pid;
ngx_str_t oldpid;
@@ -94,11 +95,11 @@ typedef struct {
} ngx_core_tls_t;
-#define ngx_is_init_cycle(old) (old && old->conf_ctx == NULL)
+#define ngx_is_init_cycle(cycle) (cycle->conf_ctx == NULL)
ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle);
-ngx_int_t ngx_create_pidfile(ngx_cycle_t *cycle, ngx_cycle_t *old_cycle);
+ngx_int_t ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log);
void ngx_delete_pidfile(ngx_cycle_t *cycle);
void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
diff --git a/src/core/ngx_shmtx.c b/src/core/ngx_shmtx.c
new file mode 100644
index 000000000..ac8a30010
--- /dev/null
+++ b/src/core/ngx_shmtx.c
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (NGX_HAVE_ATOMIC_OPS)
+
+
+ngx_int_t
+ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name, ngx_log_t *log)
+{
+ mtx->lock = addr;
+
+ return NGX_OK;
+}
+
+#else
+
+
+ngx_int_t
+ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name, ngx_log_t *log)
+{
+ if (mtx->name) {
+
+ if (ngx_strcmp(name, mtx->name) == 0) {
+ mtx->name = name;
+ mtx->log = log;
+
+ return NGX_OK;
+ }
+
+ ngx_shmtx_destory(mtx);
+ }
+
+ mtx->fd = ngx_open_file(name, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN);
+
+ if (mtx->fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", name);
+ return NGX_ERROR;
+ }
+
+ if (ngx_delete_file(name) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed", name);
+ }
+
+ mtx->name = name;
+ mtx->log = log;
+
+ return NGX_OK;
+}
+
+
+void
+ngx_shmtx_destory(ngx_shmtx_t *mtx)
+{
+ if (ngx_close_file(mtx->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, mtx->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", mtx->name);
+ }
+}
+
+
+#endif
diff --git a/src/core/ngx_shmtx.h b/src/core/ngx_shmtx.h
new file mode 100644
index 000000000..fdd62e192
--- /dev/null
+++ b/src/core/ngx_shmtx.h
@@ -0,0 +1,111 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef _NGX_SHMTX_H_INCLUDED_
+#define _NGX_SHMTX_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef struct {
+#if (NGX_HAVE_ATOMIC_OPS)
+ ngx_atomic_t *lock;
+#else
+ ngx_fd_t fd;
+ u_char *name;
+ ngx_log_t *log;
+#endif
+} ngx_shmtx_t;
+
+
+ngx_int_t ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name,
+ ngx_log_t *log);
+
+
+#if (NGX_HAVE_ATOMIC_OPS)
+
+static ngx_inline ngx_uint_t
+ngx_shmtx_trylock(ngx_shmtx_t *mtx)
+{
+ if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+#define ngx_shmtx_lock(mtx) ngx_spinlock((mtx)->lock, ngx_pid, 1024)
+
+#define ngx_shmtx_unlock(mtx) (void) ngx_atomic_cmp_set((mtx)->lock, ngx_pid, 0)
+
+#define ngx_shmtx_destory(mtx)
+
+
+#else
+
+static ngx_inline ngx_uint_t
+ngx_shmtx_trylock(ngx_shmtx_t *mtx)
+{
+ ngx_err_t err;
+
+ err = ngx_trylock_fd(mtx->fd);
+
+ if (err == 0) {
+ return 1;
+ }
+
+ if (err == NGX_EAGAIN) {
+ return 0;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, mtx->log, err, ngx_trylock_fd_n " failed");
+
+ ngx_abort();
+}
+
+
+static ngx_inline void
+ngx_shmtx_lock(ngx_shmtx_t *mtx)
+{
+ ngx_err_t err;
+
+ err = ngx_lock_fd(mtx->fd);
+
+ if (err == 0) {
+ return;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, mtx->log, err, ngx_lock_fd_n " failed");
+
+ ngx_abort();
+}
+
+
+static ngx_inline void
+ngx_shmtx_unlock(ngx_shmtx_t *mtx)
+{
+ ngx_err_t err;
+
+ err = ngx_unlock_fd(mtx->fd);
+
+ if (err == 0) {
+ return;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, mtx->log, err, ngx_unlock_fd_n " failed");
+
+ ngx_abort();
+}
+
+
+void ngx_shmtx_destory(ngx_shmtx_t *mtx);
+
+#endif
+
+
+#endif /* _NGX_SHMTX_H_INCLUDED_ */
diff --git a/src/core/ngx_spinlock.c b/src/core/ngx_spinlock.c
index a3082a0a5..f6c80f769 100644
--- a/src/core/ngx_spinlock.c
+++ b/src/core/ngx_spinlock.c
@@ -8,36 +8,35 @@
#include <ngx_core.h>
-/*
- * TODO: the P4 optimized assembler version with the "pause" operation
- */
-
void
-ngx_spinlock(ngx_atomic_t *lock, ngx_uint_t spin)
+ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
{
#if (NGX_HAVE_ATOMIC_OPS)
- ngx_uint_t tries;
-
- tries = 0;
+ ngx_uint_t i, n;
for ( ;; ) {
- if (*lock) {
- if (ngx_ncpu > 1 && tries++ < spin) {
- continue;
- }
+ if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
+ return;
+ }
- ngx_sched_yield();
+ if (ngx_ncpu > 1) {
- tries = 0;
+ for (n = 1; n < spin; n <<= 1) {
- } else {
- if (ngx_atomic_cmp_set(lock, 0, 1)) {
- return;
+ for (i = 0; i < n; i++) {
+ ngx_cpu_pause();
+ }
+
+ if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
+ return;
+ }
}
}
+
+ ngx_sched_yield();
}
#else