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 ChangesPath
1.17 +40 -31apache-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));