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...