manoj 99/05/23 23:18:47
Modified: pthreads/src/include http_accept.h pthreads/src/main http_accept.c Log: Bring queued model up-to-date with poll-accept model, for some reason. This makes the accept threads use poll() on a pipe to discover that it's time for a child process to die. Also, since stop_accepting_requests() isn't used anymore (and doesn't really work anyway), get rid of all references to it in both models. Revision Changes Path 1.9 +0 -1 apache-apr/pthreads/src/include/http_accept.h Index: http_accept.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/http_accept.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -u -r1.8 -r1.9 --- http_accept.h 1999/05/09 08:46:27 1.8 +++ http_accept.h 1999/05/24 06:18:46 1.9 @@ -82,7 +82,6 @@ void accept_child_init(pool*, int); void start_accepting_connections(int); int get_connection(struct sockaddr *); -void stop_accepting_connections(pool*); #ifdef USE_MULTI_ACCEPT #define NEED_INTRAPROCESS_SERIALIZED_ACCEPT 1.16 +39 -84 apache-apr/pthreads/src/main/http_accept.c Index: http_accept.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_accept.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -u -r1.15 -r1.16 --- http_accept.c 1999/05/24 02:10:26 1.15 +++ http_accept.c 1999/05/24 06:18:47 1.16 @@ -92,8 +92,11 @@ int my_tid = ti->tid; int sd = ti->sd; int csd = 0; + int srv, ret; struct sockaddr sa_client; size_t len = sizeof(struct sockaddr); + struct pollfd listenfds[2]; + char pipe_read_char; free(ti); @@ -105,8 +108,17 @@ sock_disable_nagle(sd); */ + listenfds[0].fd = ap_pipe_of_death[0]; + listenfds[0].events = POLLIN; + listenfds[0].revents = 0; + listenfds[1].fd = sd; + listenfds[1].events = POLLIN; + listenfds[1].revents = 0; + while ((ap_max_requests_per_child != 0 && requests_this_child > 0) || (ap_max_requests_per_child == 0)) { + if (workers_may_exit) + break; (void) ap_update_child_status(my_pid, my_tid, SERVER_ACCEPTING, (request_rec *) NULL); /* lock around the accept if necessary */ @@ -123,10 +135,33 @@ csd = -1; } else { - csd = accept(sd, &sa_client, &len); - requests_this_child--; - SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child)); - SAFE_ACCEPT(intra_mutex_off(my_tid - ap_threads_per_child)); + for (;;) { + srv = poll(listenfds, 2, -1); + if (listenfds[0].revents & POLLIN) { + /* A process has gotten a signal on the shutdown pipe. + * Check if we're the lucky process to die. */ + ret = read(listenfds[0].fd, &pipe_read_char, 1); + if (ret == -1 && errno == EAGAIN) { + /* It lost the lottery. It must continue to suffer + * through a life of servitude */ + continue; + } + else { + /* It won the lottery (or something else is very + * wrong). Embrace death with open arms. */ + workers_may_exit = 1; + pthread_cond_broadcast(&(csd_queue.not_empty)); + csd = -1; + break; + } + } else { + csd = accept(sd, &sa_client, &len); + requests_this_child--; + break; + } + } + SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child)); + SAFE_ACCEPT(intra_mutex_off(my_tid - ap_threads_per_child)); } (void) ap_update_child_status(my_pid, my_tid, SERVER_QUEUEING, (request_rec *) NULL); @@ -139,66 +174,10 @@ } } - /* Raise SIGWINCH so that all the actions that go with a gradual, - * graceful shutdown of the process get done. - * - * The reason this thread is actually going through the trouble to - * look up its own process ID is because under Red Hat 5.2, getpid() - * actually returns the "process ID" of the thread, since threads - * are just processes that share everything. I hope this is fixed in - * glibc 2.1 & Linux 2.2. - mvsk */ - kill(ap_scoreboard_image->parent[my_pid].pid, SIGWINCH); ap_update_child_status(my_pid, my_tid, SERVER_DEAD, (request_rec *) NULL); return NULL; } - -/* Kill off any worker threads by kicking them out of whatever they are doing - * and allowing them to see that requests_this_child == 0. - * It is possible this function could be defined to be NULL in some accept - * models. - */ - -static void kill_workers(void) -{ - int i; - int index = find_child_by_pid(getpid()); - parent_score *ss = &ap_scoreboard_image->parent[index]; - - pthread_cond_broadcast(&(csd_queue.not_empty)); - for (i = 0; i < ss->worker_threads; i++) { - pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL); - } -} -/* Kill off any acceptor threads by kicking them out of what they are doing - * and allowing them to see that requests_this_child == 0. - * It is possible this function could be defined to be NULL in some accept - * models. - */ -static void kill_acceptors(pool* pconf) -{ - listen_rec *lr; - int i; - int index = find_child_by_pid(getpid()); - parent_score *ss = &ap_scoreboard_image->parent[index]; - - - /* Kick acceptor threads out of accept */ - - lr = ap_listeners; - while (lr != NULL) { - ap_pclosesocket(pconf, lr->fd); - lr= lr->next; - } - - /* Kick any acceptor out of blocking on a full queue */ - pthread_cond_broadcast(&(csd_queue.not_full)); - - for (i = ss->worker_threads; i < ss->worker_threads + ss->acceptor_threads; i++) { - pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL); - } -} - void accept_parent_init(pool *pconf, int listener_count) { SAFE_ACCEPT(accept_mutex_init(pconf, listener_count)); @@ -308,14 +287,6 @@ return csd; } -void stop_accepting_connections(pool* pconf) -{ - requests_this_child = 0; - /* The two functions to get all of our other threads to die off. */ - kill_acceptors(pconf); - workers_may_exit = 1; - kill_workers(); -} #elif defined(USE_MULTI_ACCEPT) @@ -481,22 +452,6 @@ } workers_may_exit = 1; return -1; -} - -void stop_accepting_connections(pool* pconf) -{ - int i; - int index = find_child_by_pid(getpid()); - - parent_score *ss = &ap_scoreboard_image->parent[index]; - - requests_this_child = 0; - workers_may_exit = 1; - - for (i = 0; i < ss->worker_threads; i++) { - pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL); - } - } #endif