rbb 99/02/17 07:29:52
Modified: pthreads/src/main http_main.c Log: Removing Manoj's two patches from last night, because they go after a symptom, not the cause of the problem. This is the first of a series of commits to fix the underlying problem of graceful restarts. This is my first time removing a patch, so if I do it wrong, I'll fix it in later patches. :) Revision Changes Path 1.39 +13 -28 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.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- http_main.c 1999/02/17 08:13:15 1.38 +++ http_main.c 1999/02/17 15:29:51 1.39 @@ -397,29 +397,14 @@ listen_rec *lr; parent_score *ss = &ap_scoreboard_image->parent[child_num]; - /* XXX - This should be taken care of by the parent process. When it reaps - * the child, it will also update the scoreboard. We can't do this here, - * because clean_child_exit can be called from a signal handler, and - * ap_update_child_status calls pthread_self */ -#if 0 for (i = 0; i < ap_threads_per_child + ap_acceptors_per_child; i++) ap_update_child_status(child_num, i, SERVER_DEAD, (request_rec *) NULL); -#endif if (pchild) { ap_child_exit_modules(pchild, server_conf); ap_destroy_pool(pchild); } - /* XXX - This is not allowed in a signal handler either, and it shouldn't - * be needed. But it's still in here, because without it, we get hanging - * threads on linux. The symptom isn't *too* bad on Linux: a core dump in - * the exit() library call. - * - * The root cause seems to be that alloc's pthread mutex is being used - * across processes, which is not kosher on some platforms (i.e. Linux), - * and a thread whacking a pool will hit an acquire_mutex and hang */ - 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); @@ -446,6 +431,13 @@ ap_pclosesocket(pconf, lr->fd); lr= lr->next; } + + for (i = 0; i < ss->worker_threads + ss->acceptor_threads; i++) { + if (ap_scoreboard_image->servers[index][i].status != SERVER_DEAD) { + 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. ****/ @@ -2308,7 +2300,7 @@ } ap_update_child_status(my_pid, my_tid, SERVER_DEAD, (request_rec *) NULL); pthread_once(&firstcall, graceful_killer); - return NULL; + pthread_exit(NULL); } void * worker_thread(void * dummy) @@ -2336,7 +2328,8 @@ ap_destroy_pool(ptrans); ap_update_child_status(my_pid, my_tid, SERVER_DEAD, (request_rec *) NULL); pthread_once(&firstcall, graceful_killer); - return NULL; + + pthread_exit(NULL); } /***************************************************************** @@ -2580,15 +2573,6 @@ lr->used = 1; accept_thread(my_info); - - /* Wait for other threads to die, then clean up. Note: joining oneself is - * a bad thing, so we make sure that i < my_info->tid, not <= */ - for (i = 0; i < my_info->tid; i++) { - if (ap_scoreboard_image->servers[my_child_num][i].status != SERVER_DEAD) { - pthread_join(ap_scoreboard_image->servers[my_child_num][i].tid, NULL); - } - } - clean_child_exit(0); } static int make_child(server_rec *s, int slot, time_t now) /* ZZZ */ @@ -2826,8 +2810,9 @@ if (pid >= 0) { child_slot = find_child_by_pid(0); if (child_slot >= 0) { - for (i = 0; i < ap_threads_per_child + ap_acceptors_per_child; i++) - ap_update_child_status(child_slot, i, SERVER_DEAD, (request_rec *) NULL); + /* (void) ap_update_child_status(child_slot, SERVER_DEAD, + (request_rec *) NULL); + LOOK INTO THIS */ if (remaining_children_to_start && child_slot < ap_daemons_limit) {