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);