stoddard 99/04/14 14:03:38
Modified: pthreads/src/include http_accept.h httpd.h pthreads/src/main http_accept.c http_core.c http_main.c Log: New accept loop logic: All worker threads accept. a.k.a. multi accept Revision Changes Path 1.2 +5 -3 apache-apr/pthreads/src/include/http_accept.h Index: http_accept.h =================================================================== RCS file: /export/home/cvs/apache-apr/pthreads/src/include/http_accept.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- http_accept.h 1999/04/07 22:52:16 1.1 +++ http_accept.h 1999/04/14 21:03:18 1.2 @@ -75,7 +75,9 @@ int sd; } proc_info; +/* Select the accept technique. Move this to ap_config eventually... */ #define USE_ACCEPT_QUEUE +/*#define USE_MULTI_ACCEPT*/ #if defined (USE_ACCEPT_QUEUE) void init_accept(pool*, int, int); @@ -84,10 +86,10 @@ void stop_accepting_requests(pool*); #elif defined (USE_MULTI_ACCEPT) -void init_accept(pool*); -#define start_accepting_requests(x, y) +void init_accept(pool*,int, int); +void start_accepting_requests(int); int get_request(struct sockaddr *); -void stop_accepting_requests(); +void stop_accepting_requests(pool *); #endif 1.14 +2 -1 apache-apr/pthreads/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /export/home/cvs/apache-apr/pthreads/src/include/httpd.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- httpd.h 1999/03/24 18:39:46 1.13 +++ httpd.h 1999/04/14 21:03:19 1.14 @@ -923,7 +923,8 @@ listen_rec *next; struct sockaddr_in local_addr; /* local IP address and port */ int fd; - int used; /* Only used during restart */ + int used; /* Only used during restart */ + int index; /* index into the listenfds array */ /* more stuff here, like which protocol is bound to the port */ }; 1.4 +174 -3 apache-apr/pthreads/src/main/http_accept.c Index: http_accept.c =================================================================== RCS file: /export/home/cvs/apache-apr/pthreads/src/main/http_accept.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- http_accept.c 1999/04/12 23:47:25 1.3 +++ http_accept.c 1999/04/14 21:03:26 1.4 @@ -68,12 +68,12 @@ /* Indicates that all acceptor threads are dead after SIGWINCH and the worker * threads can now exit */ static int workers_may_exit = 0; +static int requests_this_child; +#if defined (USE_ACCEPT_QUEUE) /* The queue of sockets we've accepted */ static FDQueue csd_queue; -static int requests_this_child; - static void * accept_thread(void * dummy) { proc_info * ti = dummy; @@ -295,10 +295,181 @@ return csd; } -void stop_accepting_requests(pool* pconf) { +void stop_accepting_requests(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) +/* + * USE_MULTI_ACCEPT + * Worker threads do the accept and process the request. + */ +static listen_rec *head_listener; +static int num_listenfds; +static struct pollfd *listenfds; + + +void init_accept(pool* pchild, + int worker_threads_per_child, + int acceptors_per_child) +{ + int i; + listen_rec *lr; + + SAFE_ACCEPT(accept_mutex_child_init(pchild)); + requests_this_child = ap_max_requests_per_child; + head_listener = ap_listeners; + num_listenfds = acceptors_per_child; + + listenfds = ap_palloc(pchild, sizeof(struct pollfd) * num_listenfds); + + for (lr = ap_listeners, i = 0; i < num_listenfds; lr = lr->next, ++i) { + lr->index = i; + listenfds[i].fd = lr->fd; + listenfds[i].events = POLLIN; /* should we add POLLPRI ?*/ + listenfds[i].revents = 0; + } + +} +void start_accepting_requests(int my_child_num) +{ +} +int get_request(struct sockaddr *sa_client) +{ + int csd = -1; + int sd; + int srv; + listen_rec *lr; + int index; + + size_t len = sizeof(struct sockaddr); + + while ((ap_max_requests_per_child != 0 && requests_this_child > 0) || + (ap_max_requests_per_child == 0)) { + + SAFE_ACCEPT(accept_mutex_on(0)); + + for (;;) { + + if (workers_may_exit) + break; + + if (num_listenfds > 1) { + /* more than one socket */ + srv = poll(listenfds, num_listenfds, -1); + if (workers_may_exit) + break; + if (srv < 0) { + SAFE_ACCEPT(accept_mutex_off(0)); + /* Single Unix documents select as returning errnos + * EBADF, EINTR, and EINVAL... and in none of those + * cases does it make sense to continue. In fact + * on Linux 2.0.x we seem to end up with EFAULT + * occasionally, and we'd loop forever due to it. + */ + ap_log_error(APLOG_MARK, APLOG_ERR, (const server_rec*) ap_get_server_conf(), "select: (listen)"); + clean_child_exit(1); + } + + if (srv == 0) { + /* Is srv == 0 a valid return? */ + continue; + } + + /* find a listener */ + /* Loop or NULL terminated list? That is the question. Be consistent across + all the accept techniques */ + lr = head_listener; + do { + /* XXX: should we check for PR_POLL_ERR ?? */ + if (listenfds[lr->index].revents & POLLIN) { + /* advance to the next listener for next loop */ + head_listener = lr->next; + /* hack to handle listenfds being NULL terminated list + * rather than a loop + */ + if (!head_listener) { + head_listener = ap_listeners; + } + goto got_lr; + } + lr = lr->next; + if (lr == NULL) { + lr = ap_listeners; + } + } while (lr != head_listener); + + /* if we don't find anything then just start again */ + fprintf(stderr,"poll returned but we got nothing!\n"); + head_listener = ap_listeners; + continue; + + got_lr: + sd = lr->fd; + } + else { + /* only one socket, just pretend we did the other stuff */ + sd = ap_listeners->fd; + } + + csd = accept(sd, sa_client, &len); + + if (csd >= 0) + break; /* We have a socket ready for reading */ + /* XXX: we need to deal with error conditions here */ + } + + + SAFE_ACCEPT(accept_mutex_off(0)); + + if (csd >= 0) { + return csd; + } else{ + break; + } + } + + /* If the workers have not already been signaled to die, SIGWINCH the parent to + * kick-off the restart + */ + if (!workers_may_exit) { + index = find_child_by_pid(getpid()); + kill(ap_scoreboard_image->parent[index].pid, SIGWINCH); + } + + + return -1; + +} +void stop_accepting_requests(pool* pconf) +{ + + listen_rec *lr; + 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; + + /* Kick threads out of poll/accept */ + lr = ap_listeners; + while (lr != NULL) { + ap_pclosesocket(pconf, lr->fd); + lr= lr->next; + } + + for (i = 0; i < ss->worker_threads + ss->acceptor_threads; i++) { + pthread_join(ap_scoreboard_image->servers[index][i].tid, NULL); + } + +} + +#endif + 1.12 +0 -14 apache-apr/pthreads/src/main/http_core.c Index: http_core.c =================================================================== RCS file: /export/home/cvs/apache-apr/pthreads/src/main/http_core.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- http_core.c 1999/03/17 17:01:18 1.11 +++ http_core.c 1999/04/14 21:03:28 1.12 @@ -2261,17 +2261,6 @@ return NULL; } -static const char *set_excess_requests(cmd_parms *cmd, void *dummy, char *arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_excess_requests_per_child = atoi(arg); - return NULL; -} - #if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS) static void set_rlimit(cmd_parms *cmd, struct rlimit **plimit, const char *arg, @@ -2892,9 +2881,6 @@ NULL }, { "ThreadsPerChild", set_threads, NULL, RSRC_CONF, TAKE1, "Number of threads a child creates" }, -{ "ExcessRequestsPerChild", set_excess_requests, NULL, RSRC_CONF, TAKE1, - "Maximum number of requests a particular child serves after it is ready " - "to die." }, { "ListenBacklog", set_listenbacklog, NULL, RSRC_CONF, TAKE1, "Maximum length of the queue of pending connections, as used by listen(2)" }, { "CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF, TAKE1, 1.69 +6 -7 apache-apr/pthreads/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apache-apr/pthreads/src/main/http_main.c,v retrieving revision 1.68 retrieving revision 1.69 diff -u -r1.68 -r1.69 --- http_main.c 1999/04/09 04:10:37 1.68 +++ http_main.c 1999/04/14 21:03:29 1.69 @@ -160,12 +160,13 @@ #ifdef MULTIPLE_GROUPS gid_t group_id_list[NGROUPS_MAX]; #endif -int ap_threads_per_child; -int ap_acceptors_per_child; +int ap_threads_per_child; /* Worker threads per child */ +int ap_acceptors_per_child; /* Accept threads per child */ + int ap_max_requests_per_child; int ap_idle_thread_threshold; int ap_busy_thread_threshold; -int ap_excess_requests_per_child; + char *ap_pid_fname; char *ap_scoreboard_fname; char *ap_lock_fname; @@ -243,8 +244,8 @@ } #define tls() ((tls_main_t *) gettls(tls_main_key)) /* ZZZZZ */ #endif + -static listen_rec *head_listener; /* *Non*-shared http_main globals... */ @@ -1493,7 +1494,7 @@ break; lr = lr->next; } - head_listener = ap_listeners; + close_unused_listeners(); #ifdef NO_SERIALIZED_ACCEPT @@ -2235,8 +2236,6 @@ int child_slot; ap_wait_t status; int pid; - - head_listener = ap_listeners; while (!restart_pending && !shutdown_pending) { pid = wait_or_timeout(&status);