rbb 99/02/17 08:28:04
Modified: pthreads/src/main http_main.c
Log:
Part two of the restart patches. This fixes the underlying problem of the
thread getting stuck in the accept_mutex code, by allowing the user out if
errno == EINTR. This patch also separates clean_child_exit from
graceful_killer
and removes the pthread_once calls. Pthread_once is supposed to be used for
init, and all threads block on it, so it doesn't work well for exit code. And
clean_child_exit and graceful_killer are two very separate and distinct
creatures, even though they must interact properly.
Revision Changes Path
1.40 +33 -22 apache-apr/pthreads/src/main/http_main.c
Index: http_main.c
===================================================================
RCS file: /home/cvs/apache-apr/pthreads/src/main/http_main.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- http_main.c 1999/02/17 15:29:51 1.39
+++ http_main.c 1999/02/17 16:28:03 1.40
@@ -175,8 +175,9 @@
int ap_suexec_enabled = 0;
int ap_listenbacklog;
int ap_dump_settings = 0;
+int exiting_now = 0;
+pthread_mutex_t *exit_mutex;
API_VAR_EXPORT int ap_extended_status = 0;
-pthread_once_t firstcall = PTHREAD_ONCE_INIT;
/*
@@ -188,7 +189,7 @@
/*
* During config time, listeners is treated as a NULL-terminated list.
- * child_main previously would start at the beginning of the list each time
+ * ;child_main previously would start at the beginning of the list each time
* through the loop, so a socket early on in the list could easily starve out
* sockets later on in the list. The solution is to start at the listener
* after the last one processed. But to do that fast/easily in child_main
it's
@@ -405,12 +406,7 @@
ap_destroy_pool(pchild);
}
- for (i = 0; i < ss->worker_threads + ss->acceptor_threads; i++) {
- if (ap_scoreboard_image->servers[child_num][i].status !=
SERVER_DEAD) {
- pthread_cancel(ap_scoreboard_image->servers[child_num][i].tid);
- }
- }
-
+ free(exit_mutex);
exit(code);
}
@@ -421,9 +417,8 @@
int index = find_child_by_pid(getpid());
parent_score *ss = &ap_scoreboard_image->parent[index];
- for (i = 0; i < ap_threads_per_child; i++) {
- pthread_cond_signal(&(csd_queue.not_empty));
- }
+ pthread_cond_broadcast(&(csd_queue.not_empty));
+
/* Setup acceptor threads */
lr = ap_listeners;
@@ -437,7 +432,6 @@
pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL);
}
}
- clean_child_exit(0);
}
/****** ZZZ this should probably be abstracted to it's own file. ****/
@@ -765,11 +759,11 @@
{
int ret;
- while ((ret = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR)
{
+ while ((ret = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0 && errno != EINTR)
{
/* nop */
}
- if (ret < 0) {
+ if (ret < 0 && errno != EINTR) {
ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
"fcntl: F_SETLKW: Error getting accept lock, exiting! "
"Perhaps you need to use the LockFile directive to place "
@@ -782,10 +776,10 @@
{
int ret;
- while ((ret = fcntl(lock_fd, F_SETLKW, &unlock_it)) < 0 && errno ==
EINTR) {
+ while ((ret = fcntl(lock_fd, F_SETLKW, &unlock_it)) < 0 && errno !=
EINTR) {
/* nop */
}
- if (ret < 0) {
+ if (ret < 0 && errno != EINTR) {
ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
"fcntl: F_SETLKW: Error freeing accept lock, exiting! "
"Perhaps you need to use the LockFile directive to place "
@@ -839,10 +833,10 @@
{
int ret;
- while ((ret = flock(lock_fd, LOCK_EX)) < 0 && errno == EINTR)
+ while ((ret = flock(lock_fd, LOCK_EX)) < 0 && errno != EINTR)
continue;
- if (ret < 0) {
+ if (ret < 0 && errno != EINTR) {
ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
"flock: LOCK_EX: Error getting accept lock. Exiting!");
clean_child_exit(APEXIT_CHILDFATAL);
@@ -851,7 +845,7 @@
static void accept_mutex_off(void)
{
- if (flock(lock_fd, LOCK_UN) < 0) {
+ if (flock(lock_fd, LOCK_UN) < 0 && errno != EINTR) {
ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
"flock: LOCK_UN: Error freeing accept lock. Exiting!");
clean_child_exit(APEXIT_CHILDFATAL);
@@ -1527,6 +1521,7 @@
static void graceful_sig_handler(int sig)
{
requests_this_child = 0;
+ fprintf(stderr, "SigWINCH received in child\n");
}
/*****************************************************************
@@ -2299,7 +2294,14 @@
}
}
ap_update_child_status(my_pid, my_tid, SERVER_DEAD, (request_rec *)
NULL);
- pthread_once(&firstcall, graceful_killer);
+ pthread_mutex_lock(exit_mutex);
+ if (exiting_now == 0) {
+ exiting_now++;
+ pthread_mutex_unlock(exit_mutex);
+ graceful_killer;
+ clean_child_exit(0);
+ }
+fprintf(stderr,"thorugh pthread_once\n");
pthread_exit(NULL);
}
@@ -2327,8 +2329,14 @@
}
ap_destroy_pool(ptrans);
ap_update_child_status(my_pid, my_tid, SERVER_DEAD, (request_rec *)
NULL);
- pthread_once(&firstcall, graceful_killer);
-
+ pthread_mutex_lock(exit_mutex);
+ if (exiting_now == 0) {
+ exiting_now++;
+ pthread_mutex_unlock(exit_mutex);
+ graceful_killer;
+ clean_child_exit(0);
+ }
+ fprintf(stderr,"through with pthread_once worker\n");
pthread_exit(NULL);
}
@@ -2469,6 +2477,9 @@
requests_this_child = ap_max_requests_per_child;
pchild = ap_make_sub_pool(pconf);
+
+ exit_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+ pthread_mutex_init(exit_mutex, NULL);
/*stuff to do before we switch id's, so we have permissions.*/
reopen_scoreboard(pchild);