manoj 99/05/27 17:19:34
Modified: pthreads/src/main http_accept.c
Log:
Squash a potential thread-safeness bug. Every thread could touch the lr and
head_listener pointers at the same time when accepts weren't serialized.
So, put back the special condition for one listen socket where we don't
bother with lr and head_listener at all.
Revision Changes Path
1.17 +40 -31 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.16
retrieving revision 1.17
diff -u -u -r1.16 -r1.17
--- http_accept.c 1999/05/24 06:18:47 1.16
+++ http_accept.c 1999/05/28 00:19:33 1.17
@@ -400,38 +400,48 @@
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;
+ /* This conditional is used because the single listen case is the
+ * only one where the accept might not be serialized. In that
+ * case, multiple threads mucking around with the head_listener
+ * pointer will be harmful */
+ if (num_listenfds == 1) {
+ /* only one socket, just pretend we did the other stuff */
+ sd = ap_listeners->fd;
+ }
+ else {
+ /* 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 == NULL) {
+ head_listener = ap_listeners;
+ }
+ goto got_lr;
}
- 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;
+ 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;
+ }
csd = accept(sd, sa_client, &len);
requests_this_child--;
@@ -439,7 +449,6 @@
break; /* We have a socket ready for reading */
/* XXX: we need to deal with error conditions here */
}
-
SAFE_ACCEPT(accept_mutex_off(0));
SAFE_ACCEPT(intra_mutex_off(0));