summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/mpm/netware/mpm_netware.c180
1 files changed, 85 insertions, 95 deletions
diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c
index c4de43bffb..621d470963 100644
--- a/server/mpm/netware/mpm_netware.c
+++ b/server/mpm/netware/mpm_netware.c
@@ -149,7 +149,6 @@
int ap_threads_per_child=0; /* Worker threads per child */
int ap_thread_stack_size=65536;
-static apr_thread_mutex_t *accept_lock;
static int ap_threads_to_start=0;
static int ap_threads_min_free=0;
static int ap_threads_max_free=0;
@@ -176,8 +175,6 @@ static char *ap_my_addrspace = NULL;
static int die_now = 0;
-static apr_thread_mutex_t *accept_mutex = NULL;
-
/* Keep track of the number of worker threads currently active */
static unsigned long worker_thread_count;
static int request_count;
@@ -192,7 +189,9 @@ static CommandParser_t ConsoleHandler = {0, NULL, 0};
static int show_settings = 0;
-#if 0
+//#define DBINFO_ON
+//#define DBPRINT_ON
+#ifdef DBPRINT_ON
#define DBPRINT0(s) printf(s)
#define DBPRINT1(s,v1) printf(s,v1)
#define DBPRINT2(s,v1,v2) printf(s,v1,v2)
@@ -332,7 +331,6 @@ int nlmUnloadSignaled()
* they are really private to child_main.
*/
-static fd_set main_fds;
int ap_graceful_stop_signalled(void)
{
@@ -340,34 +338,36 @@ int ap_graceful_stop_signalled(void)
return 0;
}
-static int dont_block = 0;
-static int missed_accept = 0;
-static apr_socket_t *sd = NULL;
-
-static int skipped_selects = 0;
+#define MAX_WB_RETRIES 3
+#ifdef DBINFO_ON
static int would_block = 0;
+static int retry_success = 0;
+static int retry_fail = 0;
+static int avg_retries = 0;
+#endif
+
/*static */
void worker_main(void *arg)
{
- ap_listen_rec *lr;
- ap_listen_rec *last_lr = NULL;
+ ap_listen_rec *lr, *first_lr, *last_lr = NULL;
apr_pool_t *ptrans;
apr_pool_t *pbucket;
apr_allocator_t *allocator;
apr_bucket_alloc_t *bucket_alloc;
conn_rec *current_conn;
apr_status_t stat = APR_EINIT;
- int worker_num_arg = (int)arg;
ap_sb_handle_t *sbh;
- int my_worker_num = worker_num_arg;
+ int my_worker_num = (int)arg;
apr_socket_t *csd = NULL;
int requests_this_child = 0;
+ apr_socket_t *sd = NULL;
+ fd_set main_fds;
int sockdes;
- ap_listen_rec *first_lr;
int srv;
struct timeval tv;
+ int wouldblock_retry;
tv.tv_sec = 1;
tv.tv_usec = 0;
@@ -381,9 +381,6 @@ void worker_main(void *arg)
atomic_inc (&worker_thread_count);
- ap_update_child_status_from_indexes(0, my_worker_num, WORKER_READY,
- (request_rec *) NULL);
-
while (!die_now) {
/*
* (Re)initialize this child to a pre-connection state.
@@ -403,101 +400,94 @@ void worker_main(void *arg)
* Wait for an acceptable connection to arrive.
*/
- /* Only allow a single thread at a time into the "accept" loop */
- apr_thread_mutex_lock(accept_mutex);
-
for (;;) {
if (shutdown_pending || restart_pending || (ap_scoreboard_image->servers[0][my_worker_num].status == WORKER_IDLE_KILL)) {
DBPRINT1 ("\nThread slot %d is shutting down\n", my_worker_num);
- apr_thread_mutex_unlock(accept_mutex);
clean_child_exit(0, my_worker_num, ptrans, bucket_alloc);
}
- /* If we just satisfied a request on listen port x, assume that more
- is coming. Don't bother using select() to determine if there is
- more, just try to accept() the next request. */
- if (dont_block && (missed_accept<10)) {
- skipped_selects++;
+ /* Check the listen queue on all sockets for requests */
+ memcpy(&main_fds, &listenfds, sizeof(fd_set));
+ srv = select(listenmaxfd + 1, &main_fds, NULL, NULL, &tv);
+
+ if (srv <= 0)
+ continue;
+
+ /* remember the last_lr we searched last time around so that
+ we don't end up starving any particular listening socket */
+ if (last_lr == NULL) {
+ lr = ap_listeners;
}
else {
- /* If we determine that there are no more requests on the listen
- queue then set the socket back to blocking and move back into
- more of an idle listen state. */
- if (dont_block) {
- apr_setsocketopt(sd, APR_SO_NONBLOCK, 0);
- dont_block = 0;
- }
-
- /* Check the listen queue on all sockets for requests */
- memcpy(&main_fds, &listenfds, sizeof(fd_set));
- srv = select(listenmaxfd + 1, &main_fds, NULL, NULL, &tv);
+ lr = last_lr->next;
+ if (!lr)
+ lr = ap_listeners;
+ }
+ first_lr = lr;
+ do {
+ apr_os_sock_get(&sockdes, lr->sd);
+ if (FD_ISSET(sockdes, &main_fds))
+ goto got_listener;
+ lr = lr->next;
+ if (!lr)
+ lr = ap_listeners;
+ } while (lr != first_lr);
+ /* if we get here, something unexpected happened. Go back
+ into the select state and try again.
+ */
+ continue;
+ got_listener:
+ last_lr = lr;
+ sd = lr->sd;
- if (srv <= 0)
- continue;
+ wouldblock_retry = MAX_WB_RETRIES;
- /* remember the last_lr we searched last time around so that
- we don't end up starving any particular listening socket */
- if (last_lr == NULL) {
- lr = ap_listeners;
+ while (wouldblock_retry) {
+ if ((stat = apr_accept(&csd, sd, ptrans)) == APR_SUCCESS) {
+ break;
}
else {
- lr = last_lr->next;
- if (!lr)
- lr = ap_listeners;
+ /* if the error is a wouldblock then maybe we were too
+ quick try to pull the next request from the listen
+ queue. Try a few more times then return to our idle
+ listen state. */
+ if (APR_TO_NETOS_ERROR(stat) != WSAEWOULDBLOCK) {
+ break;
+ }
+
+ if (wouldblock_retry--) {
+ apr_thread_yield();
+ }
}
- first_lr = lr;
- do {
- apr_os_sock_get(&sockdes, lr->sd);
- if (FD_ISSET(sockdes, &main_fds))
- goto got_listener;
- lr = lr->next;
- if (!lr)
- lr = ap_listeners;
- } while (lr != first_lr);
- /* FIXME: if we get here, something bad has happened, and we're
- probably gonna spin forever.
- */
- continue;
-got_listener:
- last_lr = lr;
- sd = lr->sd;
-
- /* Just got a request on one of the listen sockets so assume that
- there are more coming. Set the socket to non-blocking and
- move into a fast pull mode. */
- apr_setsocketopt(sd, APR_SO_NONBLOCK, 1);
- dont_block = 1;
- missed_accept = 0;
}
-
- stat = apr_accept(&csd, sd, ptrans);
/* If we got a new socket, set it to non-blocking mode and process
it. Otherwise handle the error. */
if (stat == APR_SUCCESS) {
apr_setsocketopt(csd, APR_SO_NONBLOCK, 0);
+#ifdef DBINFO_ON
+ if (wouldblock_retry < MAX_WB_RETRIES) {
+ retry_success++;
+ avg_retries += (MAX_WB_RETRIES-wouldblock_retry);
+ }
+#endif
break; /* We have a socket ready for reading */
}
else {
switch (APR_TO_NETOS_ERROR(stat)) {
-
- /* if the error is a wouldblock then maybe we were too
- quick try to pull the next request from the listen
- queue. Try a few more times then return to our idle
- listen state. */
+
case WSAEWOULDBLOCK:
- missed_accept++;
+#ifdef DBINFO_ON
would_block++;
- apr_thread_yield();
- continue;
+ retry_fail++;
break;
-
+#endif
case WSAECONNRESET:
case WSAETIMEDOUT:
case WSAEHOSTUNREACH:
case WSAENETUNREACH:
break;
-
+
case WSAENETDOWN:
/*
* When the network layer has been shut down, there
@@ -515,21 +505,16 @@ got_listener:
*/
ap_log_error(APLOG_MARK, APLOG_EMERG, stat, ap_server_conf,
"apr_accept: giving up.");
- apr_thread_mutex_unlock(accept_mutex);
clean_child_exit(APEXIT_CHILDFATAL, my_worker_num, ptrans, bucket_alloc);
-
+
default:
ap_log_error(APLOG_MARK, APLOG_ERR, stat, ap_server_conf,
"apr_accept: (client socket)");
- apr_thread_mutex_unlock(accept_mutex);
clean_child_exit(1, my_worker_num, ptrans, bucket_alloc);
}
}
}
- /* Unlock the mutext so that the next thread can start listening for requests. */
- apr_thread_mutex_unlock(accept_mutex);
-
ap_create_sb_handle(&sbh, ptrans, 0, my_worker_num);
/*
* We now have a connection, so set it up with the appropriate
@@ -742,12 +727,13 @@ static void display_settings ()
int status_array[SERVER_NUM_STATUS];
int i, status, total=0;
int reqs = request_count;
- int skips = skipped_selects;
+#ifdef DBINFO_ON
int wblock = would_block;
+
+ would_block = 0;
+#endif
request_count = 0;
- skipped_selects = 0;
- would_block = 0;
ClearScreen (getscreenhandle());
printf("%s \n", ap_get_server_version());
@@ -806,8 +792,13 @@ static void display_settings ()
}
printf ("Total Running:\t%d\tout of: \t%d\n", total, ap_threads_limit);
printf ("Requests per interval:\t%d\n", reqs);
- printf ("Skipped selects:\t%d\n", skips);
+
+#ifdef DBINFO_ON
printf ("Would blocks:\t%d\n", wblock);
+ printf ("Successful retries:\t%d\n", retry_success);
+ printf ("Failed retries:\t%d\n", retry_fail);
+ printf ("Avg retries:\t%d\n", retry_success == 0 ? 0 : avg_retries / retry_success);
+#endif
}
static void show_server_data()
@@ -857,9 +848,9 @@ static int setup_listeners(server_rec *s)
if (sockdes > listenmaxfd) {
listenmaxfd = sockdes;
}
-#ifdef NONBLOCK1
+ /* Use non-blocking listen sockets so that we
+ never get hung up. */
apr_setsocketopt(lr->sd, APR_SO_NONBLOCK, 1);
-#endif
}
return 0;
}
@@ -894,7 +885,6 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
restart_pending = shutdown_pending = 0;
worker_thread_count = 0;
- apr_thread_mutex_create(&accept_mutex, APR_THREAD_MUTEX_DEFAULT, pconf);
if (!is_graceful) {
if (ap_run_pre_mpm(s->process->pool, SB_NOT_SHARED) != OK) {