Nginx fails to accept new connection if active worker crashes
faskiri.devel
nginx-forum at nginx.us
Wed Nov 16 08:51:09 UTC 2011
Thanks for your attention!
It works fine with accept_mutex off, I will run my stress test harness
over the weekend to see the impact on the performance. If there is a
significant difference in performance, will surely update the thread
with the same.
For my understanding, I had implemented a workaround to get around this
problem. Is your solution along the same line?
My patch:
diff --git a/service/nginxServer/nginx-1.0.5/src/event/ngx_event.c
b/service/nginxServer/nginx-1.0.5/src/event/ngx_event.c
index c57d37e..a6ed725 100644
--- a/service/nginxServer/nginx-1.0.5/src/event/ngx_event.c
+++ b/service/nginxServer/nginx-1.0.5/src/event/ngx_event.c
@@ -49,6 +49,10 @@ ngx_atomic_t *ngx_connection_counter =
&connection_counter;
ngx_atomic_t *ngx_accept_mutex_ptr;
ngx_shmtx_t ngx_accept_mutex;
+// This is shared var protected by ngx_use_accept_mutex. Access only
when
+// ngx_accept_mutex is held. The var stores the PID of the process
currently
+// holding the mutex
+ngx_pid_t *ngx_accept_mutex_held_by;
ngx_uint_t ngx_use_accept_mutex;
ngx_uint_t ngx_accept_events;
ngx_uint_t ngx_accept_mutex_held;
@@ -254,6 +258,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
}
if (ngx_accept_mutex_held) {
+ *ngx_accept_mutex_held_by = 0;
ngx_shmtx_unlock(&ngx_accept_mutex);
}
@@ -526,6 +531,9 @@ ngx_event_module_init(ngx_cycle_t *cycle)
{
return NGX_ERROR;
}
+ // cl = 128 bytes are available for us to use. ngx_shmtx_create
uses
+ // ngx_atomic_t bytes to assign to mutex->lock, using the memory
after that
+ ngx_accept_mutex_held_by = (ngx_pid_t*) (shared +
sizeof(ngx_atomic_t));
ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
diff --git a/service/nginxServer/nginx-1.0.5/src/event/ngx_event.h
b/service/nginxServer/nginx-1.0.5/src/event/ngx_event.h
index 778da52..f1b06d4 100644
--- a/service/nginxServer/nginx-1.0.5/src/event/ngx_event.h
+++ b/service/nginxServer/nginx-1.0.5/src/event/ngx_event.h
@@ -501,6 +501,7 @@ extern ngx_atomic_t
*ngx_connection_counter;
extern ngx_atomic_t *ngx_accept_mutex_ptr;
extern ngx_shmtx_t ngx_accept_mutex;
+extern ngx_pid_t *ngx_accept_mutex_held_by;
extern ngx_uint_t ngx_use_accept_mutex;
extern ngx_uint_t ngx_accept_events;
extern ngx_uint_t ngx_accept_mutex_held;
diff --git
a/service/nginxServer/nginx-1.0.5/src/event/ngx_event_accept.c
b/service/nginxServer/nginx-1.0.5/src/event/ngx_event_accept.c
index 2355d1b..feb4568 100644
--- a/service/nginxServer/nginx-1.0.5/src/event/ngx_event_accept.c
+++ b/service/nginxServer/nginx-1.0.5/src/event/ngx_event_accept.c
@@ -298,6 +298,10 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"accept mutex locked");
+ *ngx_accept_mutex_held_by = ngx_pid;
+
+ // If the mutex was already held by me and we are using
RTSIG_EVENT, no
+ // need to enable accept_events
if (ngx_accept_mutex_held
&& ngx_accept_events == 0
&& !(ngx_event_flags & NGX_USE_RTSIG_EVENT))
@@ -306,6 +310,8 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
}
if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
+ // No one is holding the mutex now
+ *ngx_accept_mutex_held_by = 0;
ngx_shmtx_unlock(&ngx_accept_mutex);
return NGX_ERROR;
}
@@ -317,8 +323,9 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "accept mutex lock failed: %ui",
ngx_accept_mutex_held);
+ "accept mutex lock failed: held by: %ui",
*ngx_accept_mutex_held_by);
+ // If I held it earlier, but not anymore (ngx_trylock_accept_mutex
failed)
if (ngx_accept_mutex_held) {
if (ngx_disable_accept_events(cycle) == NGX_ERROR) {
return NGX_ERROR;
diff --git a/service/nginxServer/nginx-1.0.5/src/os/unix/ngx_process.c
b/service/nginxServer/nginx-1.0.5/src/os/unix/ngx_process.c
index 6055587..b66d4b3 100644
--- a/service/nginxServer/nginx-1.0.5/src/os/unix/ngx_process.c
+++ b/service/nginxServer/nginx-1.0.5/src/os/unix/ngx_process.c
@@ -492,17 +492,18 @@ ngx_process_get_status(void)
}
- if (ngx_accept_mutex_ptr) {
-
- /*
- * unlock the accept mutex if the abnormally exited
process
- * held it
- */
-
- ngx_atomic_cmp_set(ngx_accept_mutex_ptr, pid, 0);
+ // If the accept mutex is held by the abnormally exited
process
+ // Note: If the process holding this has died, the mutex cannot
be
+ // acquired by someone else, in which case,
ngx_accept_mutex_held is
+ // free to be accessed
+ if (ngx_accept_mutex_held_by != NULL && pid ==
*ngx_accept_mutex_held_by) {
+ ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+ "PID %P held the accept mutex. Releasing", pid);
+ // Reset the value before unlocking
+ *ngx_accept_mutex_held_by = 0;
+ ngx_shmtx_unlock(&ngx_accept_mutex);
}
-
one = 1;
process = "unknown process";
--
1.7.1
Posted at Nginx Forum: http://forum.nginx.org/read.php?2,218359,218425#msg-218425
More information about the nginx
mailing list