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

Reply via email to