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

Reply via email to