You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@locus.apache.org on 2000/04/04 22:26:37 UTC

cvs commit: apache-2.0/src/lib/apr/test testoc.c Makefile.in

rbb         00/04/04 13:26:36

  Modified:    src/lib/apr/include apr_thread_proc.h
               src/lib/apr/misc/unix misc.h otherchild.c
               src/lib/apr/test Makefile.in
  Added:       src/lib/apr/test testoc.c
  Log:
  Other child logic finished for Unix.  Docs are forthcoming.  This should
  for Apache, and those patches are also coming today.
  
  Revision  Changes    Path
  1.18      +19 -0     apache-2.0/src/lib/apr/include/apr_thread_proc.h
  
  Index: apr_thread_proc.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_thread_proc.h,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- apr_thread_proc.h	2000/04/04 17:58:45	1.17
  +++ apr_thread_proc.h	2000/04/04 20:26:33	1.18
  @@ -77,6 +77,19 @@
   #define APR_CANCEL_ENABLE      3
   #define APR_CANCEL_DISABLE     4
   
  +#define APR_OC_REASON_DEATH         0     /* child has died, caller must call
  +                                           * unregister still */
  +#define APR_OC_REASON_UNWRITABLE    1     /* write_fd is unwritable */
  +#define APR_OC_REASON_RESTART       2     /* a restart is occuring, perform
  +                                           * any necessary cleanup (including
  +                                           * sending a special signal to child)
  +                                           */
  +#define APR_OC_REASON_UNREGISTER    3     /* unregister has been called, do
  +                                           * whatever is necessary (including
  +                                           * kill the child) */
  +#define APR_OC_REASON_LOST          4     /* somehow the child exited without
  +                                           * us knowing ... buggy os? */
  +
   typedef struct ap_thread_t           ap_thread_t;
   typedef struct ap_threadattr_t       ap_threadattr_t;
   typedef struct ap_proc_t		  ap_proc_t;
  @@ -145,6 +158,12 @@
                                 ap_procattr_t *attr, ap_context_t *cont);
   ap_status_t ap_wait_proc(ap_proc_t *proc, ap_wait_how_e waithow);
   ap_status_t ap_detach(ap_proc_t **new, ap_context_t *cont);
  +
  +void ap_register_other_child(ap_proc_t *pid, 
  +                             void (*maintenance) (int reason, void *),
  +                             void *data, int write_fd, ap_context_t *p);
  +void ap_unregister_other_children(void *data);
  +ap_status_t reap_other_child(ap_proc_t *pid); 
   
   ap_status_t ap_kill(ap_proc_t *proc, int sig);
   #ifdef __cplusplus
  
  
  
  1.11      +1 -0      apache-2.0/src/lib/apr/misc/unix/misc.h
  
  Index: misc.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/misc/unix/misc.h,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- misc.h	2000/04/04 17:58:48	1.10
  +++ misc.h	2000/04/04 20:26:34	1.11
  @@ -60,6 +60,7 @@
   #include "apr_general.h"
   #include "apr_pools.h"
   #include "apr_getopt.h"
  +#include "apr_thread_proc.h"
   #ifdef HAVE_STDLIB_H
   #include <stdlib.h>
   #endif
  
  
  
  1.2       +41 -18    apache-2.0/src/lib/apr/misc/unix/otherchild.c
  
  Index: otherchild.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/misc/unix/otherchild.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- otherchild.c	2000/04/04 17:58:48	1.1
  +++ otherchild.c	2000/04/04 20:26:35	1.2
  @@ -53,18 +53,17 @@
    */
   
   #include "misc.h"
  +#include "../../threadproc/unix/threadproc.h"
   
  -#ifdef APR_HAS_OTHER_CHILD
  +static ap_other_child_rec_t *other_children = NULL;
   
  -static other_child_rec *other_children = NULL;
  -
   API_EXPORT(void) ap_register_other_child(ap_proc_t *pid,
                        void (*maintenance) (int reason, void *),
  -                     void *data, int write_fd)
  +                     void *data, int write_fd, ap_context_t *p)
   {
  -    other_child_rec *ocr;
  +    ap_other_child_rec_t *ocr;
   
  -    ocr = ap_palloc(pconf, sizeof(*ocr));
  +    ocr = ap_palloc(p, sizeof(*ocr));
       ocr->pid = pid->pid;
       ocr->maintenance = maintenance;
       ocr->data = data;
  @@ -79,12 +78,12 @@
    */
   API_EXPORT(void) ap_unregister_other_child(void *data)
   {
  -    other_child_rec **pocr, *nocr;
  +    ap_other_child_rec_t **pocr, *nocr;
   
       for (pocr = &other_children; *pocr; pocr = &(*pocr)->next) {
           if ((*pocr)->data == data) {
               nocr = (*pocr)->next;
  -            (*(*pocr)->maintenance) (OC_REASON_UNREGISTER, (*pocr)->data);
  +            (*(*pocr)->maintenance) (APR_OC_REASON_UNREGISTER, (*pocr)->data);
               *pocr = nocr;
               /* XXX: um, well we've just wasted some space in pconf ? */
               return;
  @@ -98,7 +97,8 @@
   {
       fd_set writable_fds;
       int fd_max;
  -    other_child_rec *ocr, *nocr;                                                    struct timeval tv;
  +    ap_other_child_rec_t *ocr, *nocr; 
  +    struct timeval tv; 
       int rc;
   
       if (other_children == NULL)
  @@ -120,14 +120,12 @@
   
           tv.tv_sec = 0;
           tv.tv_usec = 0;
  -        rc = ap_select(fd_max + 1, NULL, &writable_fds, NULL, &tv);
  +        rc = select(fd_max + 1, NULL, &writable_fds, NULL, &tv);
       } while (rc == -1 && errno == EINTR);
   
       if (rc == -1) {
           /* XXX: uhh this could be really bad, we could have a bad file
            * descriptor due to a bug in one of the maintenance routines */
  -        ap_log_unixerr("probe_writable_fds", "select",
  -                    "could not probe writable fds", server_conf);
           return;
       }
       if (rc == 0)
  @@ -139,24 +137,49 @@
               continue;
           if (FD_ISSET(ocr->write_fd, &writable_fds))
               continue;
  -        (*ocr->maintenance) (OC_REASON_UNWRITABLE, ocr->data, -1);
  +        (*ocr->maintenance) (APR_OC_REASON_UNWRITABLE, ocr->data);
       }
   }
   
   /* possibly reap an other_child, return 0 if yes, -1 if not */
  -API_EXPORT(int) reap_other_child(int pid)
  +API_EXPORT(ap_status_t) reap_other_child(ap_proc_t *pid)
   {
  -    other_child_rec *ocr, *nocr;
  +    ap_other_child_rec_t *ocr, *nocr;
   
       for (ocr = other_children; ocr; ocr = nocr) {
           nocr = ocr->next;
  -        if (ocr->pid != pid)
  +        if (ocr->pid != pid->pid)
               continue;
           ocr->pid = -1;
  -        (*ocr->maintenance) (OC_REASON_DEATH, ocr->data);
  +        (*ocr->maintenance) (APR_OC_REASON_DEATH, ocr->data);
           return 0;
       }
       return -1;
  +}
  +
  +API_EXPORT(void) check_other_child(void)
  +{
  +    ap_other_child_rec_t *ocr, *nocr;
  +    pid_t waitret;    
  +
  +    for (ocr = other_children; ocr; ocr = nocr) {
  +        nocr = ocr->next;
  +        if (ocr->pid == -1)
  +            continue;
  +
  +        waitret = waitpid(ocr->pid, NULL, WNOHANG);
  +        if (waitret == ocr->pid) {
  +            ocr->pid = -1;
  +            (*ocr->maintenance) (APR_OC_REASON_DEATH, ocr->data);
  +        }
  +        else if (waitret == 0) {
  +            (*ocr->maintenance) (APR_OC_REASON_RESTART, ocr->data);
  +        }
  +        else if (waitret == -1) {
  +            /* uh what the heck? they didn't call unregister? */
  +            ocr->pid = -1;
  +            (*ocr->maintenance) (APR_OC_REASON_LOST, ocr->data);
  +        }
  +    }
   }
  -#endif
   
  
  
  
  1.14      +5 -0      apache-2.0/src/lib/apr/test/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/test/Makefile.in,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- Makefile.in	2000/04/04 03:51:55	1.13
  +++ Makefile.in	2000/04/04 20:26:36	1.14
  @@ -26,6 +26,7 @@
   	testshmem@EXEEXT@ \
   	testpipe@EXEEXT@ \
   	testdso@EXEEXT@ \
  +	testoc@EXEEXT@ \
   	mod_test.so
   
   OBJS= testfile.o \
  @@ -39,6 +40,7 @@
   	htdigest.o \
   	testmmap.o \
   	testdso.o \
  +	testoc.o \
   	mod_test.o
   
   .c.o:
  @@ -51,6 +53,9 @@
   
   testdso@EXEEXT@: testdso.o
   	$(CC) $(CFLAGS) --export-dynamic -fPIC testdso.o -o testdso@EXEEXT@ $(LDFLAGS) 
  +
  +testoc@EXEEXT@: testoc.o
  +	$(CC) $(CFLAGS) testoc.o -o testoc@EXEEXT@ $(LDFLAGS) 
   
   mod_test.so: mod_test.o
   	$(CC) -shared mod_test.o -o mod_test.so 
  
  
  
  1.1                  apache-2.0/src/lib/apr/test/testoc.c
  
  Index: testoc.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  #include "apr_thread_proc.h"
  #include "apr_errno.h"
  #include "apr_general.h"
  #include "apr_lib.h"
  #include "errno.h"
  #include <stdio.h>
  #ifdef BEOS
  #include <unistd.h>
  #endif
  
  void ocmaint(int reason, void *data)
  {
      switch (reason) {
      case APR_OC_REASON_DEATH:
          fprintf(stdout, "OC killed... correctly\n");
          break;
      case APR_OC_REASON_LOST:
      case APR_OC_REASON_UNWRITABLE:
      case APR_OC_REASON_RESTART:
          fprintf(stdout, "OC maintentance called for reason other than death\n");
          break;
      }
  }
  
  int main(int argc, char *argv[])
  {
      ap_context_t *context;
      ap_context_t *cont2;
      ap_status_t status = 0;
      ap_ssize_t nbytes = 0;
      ap_proc_t *newproc = NULL;
      ap_procattr_t *procattr = NULL;
      char *args[3];
  
      if (argc > 1) {
          while (1);
      }
  
      if (ap_initialize() != APR_SUCCESS) {
          fprintf(stderr, "Couldn't initialize.");
          exit(-1);
      }
      atexit(ap_terminate);
      if (ap_create_context(&context, NULL) != APR_SUCCESS) {
          fprintf(stderr, "Couldn't allocate context.");
          exit(-1);
      }
      
      args[0] = ap_pstrdup(context, "testoc");
      args[1] = ap_pstrdup(context, "-X");
      args[2] = NULL;
  
      fprintf(stdout, "Creating procattr.......");
      if (ap_createprocattr_init(&procattr, context) != APR_SUCCESS) {
          fprintf(stderr, "Could not create attr\n");
          exit(-1);;
      }
  
      fprintf(stdout, "starting other child.......");
      if (ap_create_process(&newproc, "../testoc", args, NULL, procattr, context) 
                            != APR_SUCCESS) {
          fprintf(stderr, "error starting other child\n");
          exit(-1);
      }
      fprintf(stdout, "OK\n");
  
      ap_register_other_child(newproc, ocmaint, NULL, -1, context);
  
      ap_kill(newproc, SIGKILL);
  
      check_other_child();
      
      return 1;
  }