Return-Path: Delivered-To: apache-cvs-archive@hyperreal.org Received: (qmail 130 invoked by uid 6000); 17 Feb 1999 16:28:07 -0000 Received: (qmail 122 invoked by alias); 17 Feb 1999 16:28:05 -0000 Delivered-To: apache-apr-cvs@hyperreal.org Received: (qmail 120 invoked by uid 236); 17 Feb 1999 16:28:04 -0000 Date: 17 Feb 1999 16:28:04 -0000 Message-ID: <19990217162804.119.qmail@hyperreal.org> From: rbb@hyperreal.org To: apache-apr-cvs@hyperreal.org Subject: cvs commit: apache-apr/pthreads/src/main http_main.c Sender: apache-cvs-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org 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);