I contemplated relatively-complex exit sequences so that children
didn't exit until the test was over, but life is short, and these test
programs should be short too.

Besides adding crude error checking (crude better than none) for some
critical APR calls, this patch ensures that apr_terminate() is not
called in the child processes.

In reality it would be nice to set up a proc mutex such that it is
only destroyed up in the parent.  I suspect that this is reasonable
default behavior, in which case no API change would be necessary.
This could be implemented by storing a pid_t in the internal mutex
representation and comparing that with getpid() in the cleanup before
deciding whether to tell the kernel to destroy the mutex.  The exact
details would vary between mutex types.  For file-based mutexes, there
is no destroy syscall, and the existing logic to close the file still
needs to be performed regardless of parent or child.

Index: testprocmutex.c
===================================================================
RCS file: /home/cvs/apr/test/testprocmutex.c,v
retrieving revision 1.10
diff -u -r1.10 testprocmutex.c
--- testprocmutex.c     9 Apr 2002 06:45:06 -0000       1.10
+++ testprocmutex.c     19 Nov 2002 13:28:10 -0000
@@ -60,6 +60,7 @@
 #include "apr_general.h"
 #include "apr_getopt.h"
 #include "errno.h"
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "test_apr.h"
@@ -70,7 +71,7 @@
 
 apr_proc_mutex_t *proc_lock;
 apr_pool_t *pool;
-int *x;
+int *x, *y;
 
 static int make_child(apr_proc_t **proc, apr_pool_t *p)
 {
@@ -82,14 +83,14 @@
 
     if (apr_proc_fork(*proc, p) == APR_INCHILD) {
         while (1) {
-            apr_proc_mutex_lock(proc_lock); 
+            assert(apr_proc_mutex_lock(proc_lock) == APR_SUCCESS);
             if (i == MAX_ITER) {
-                apr_proc_mutex_unlock(proc_lock); 
+                assert(apr_proc_mutex_unlock(proc_lock) == APR_SUCCESS);
                 exit(1);
             }
             i++;
             (*x)++;
-            apr_proc_mutex_unlock(proc_lock); 
+            assert(apr_proc_mutex_unlock(proc_lock) == APR_SUCCESS);
         }
         exit(1);
     }
@@ -155,7 +156,6 @@
     printf("APR Proc Mutex Test\n==============\n\n");
         
     apr_initialize();
-    atexit(apr_terminate);
 
     if (apr_pool_create(&pool, NULL) != APR_SUCCESS)
         exit(-1);
@@ -178,15 +178,22 @@
         exit(-1);
     }
 
-    apr_shm_create(&shm, sizeof(int), shmname, pool);
+    assert(apr_shm_create(&shm, 2 * sizeof(int), shmname, pool) == 
APR_SUCCESS);
     x = apr_shm_baseaddr_get(shm);
+    y = x + 1;
 
     if ((rv = test_exclusive(lockname)) != APR_SUCCESS) {
         fprintf(stderr,"Exclusive Lock test failed : [%d] %s\n",
                 rv, apr_strerror(rv, (char*)errmsg, 200));
         exit(-2);
     }
-    
+  
+    /* if the child processes run apr_terminate() when they exit, the
+     * mutex will be destroyed and remaining children will be left with
+     * a useless mutex
+     */ 
+    apr_terminate(); 
+
     return 0;
 }
 

-- 
Jeff Trawick | [EMAIL PROTECTED]
Born in Roswell... married an alien...

Reply via email to