apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <...@rkbloom.net>
Subject Proc mutex re-org
Date Sun, 13 Jun 2004 01:45:16 GMT

OK, here is the proc mutex re-org.  This is ugly, but it passes all of the
tests, using both fork and proc_create.  The only problem with this patch,
is that it doesn't do the configure magic to actually setup FORK_DEFAULT
and PROC_CREATE_DEFAULT.  To test this, I just set APR_USE_FLOCK_SERIALIZE
to 1 along with APR_USE_SYSVSEM_SERIALIZE.  I am nost sure what the best
way is to do this with configure, so I will leave that as an exercise for
the group to discuss.

Ryan


Index: include/apr_global_mutex.h
===================================================================
RCS file: /home/cvs/apr/include/apr_global_mutex.h,v
retrieving revision 1.11
diff -u -u -r1.11 apr_global_mutex.h
--- include/apr_global_mutex.h	13 Feb 2004 09:38:28 -0000	1.11
+++ include/apr_global_mutex.h	13 Jun 2004 02:01:24 -0000
@@ -89,6 +89,7 @@
 APR_DECLARE(apr_status_t) apr_global_mutex_child_init(
                               apr_global_mutex_t **mutex,
                               const char *fname,
+                              apr_lockmech_e mech,
                               apr_pool_t *pool);

 /**
Index: include/apr_proc_mutex.h
===================================================================
RCS file: /home/cvs/apr/include/apr_proc_mutex.h,v
retrieving revision 1.14
diff -u -u -r1.14 apr_proc_mutex.h
--- include/apr_proc_mutex.h	13 Feb 2004 09:38:28 -0000	1.14
+++ include/apr_proc_mutex.h	13 Jun 2004 02:01:24 -0000
@@ -41,12 +41,13 @@
  *          APR_LOCK_foo.  Only APR_LOCK_DEFAULT is portable.
  */
 typedef enum {
-    APR_LOCK_FCNTL,         /**< fcntl() */
-    APR_LOCK_FLOCK,         /**< flock() */
-    APR_LOCK_SYSVSEM,       /**< System V Semaphores */
-    APR_LOCK_PROC_PTHREAD,  /**< POSIX pthread process-based locking */
-    APR_LOCK_POSIXSEM,      /**< POSIX semaphore process-based locking */
-    APR_LOCK_DEFAULT        /**< Use the default process lock */
+    APR_LOCK_FCNTL,              /**< fcntl() */
+    APR_LOCK_FLOCK,              /**< flock() */
+    APR_LOCK_SYSVSEM,            /**< System V Semaphores */
+    APR_LOCK_PROC_PTHREAD,       /**< POSIX pthread process-based locking */
+    APR_LOCK_POSIXSEM,           /**< POSIX semaphore process-based locking */
+    APR_LOCK_FORK_DEFAULT,       /**< Use the default process lock when using apr_proc_fork
*/
+    APR_LOCK_PROC_CREATE_DEFAULT /**< Use the default process lock when using apr_proc_create
*/
 } apr_lockmech_e;

 /** Opaque structure representing a process mutex. */
@@ -93,6 +94,7 @@
  */
 APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
                                                     const char *fname,
+                                                    apr_lockmech_e mech,
                                                     apr_pool_t *pool);

 /**
Index: include/arch/unix/apr_arch_proc_mutex.h
===================================================================
RCS file: /home/cvs/apr/include/arch/unix/apr_arch_proc_mutex.h,v
retrieving revision 1.6
diff -u -u -r1.6 apr_arch_proc_mutex.h
--- include/arch/unix/apr_arch_proc_mutex.h	5 Jun 2004 13:33:19 -0000	1.6
+++ include/arch/unix/apr_arch_proc_mutex.h	13 Jun 2004 02:01:24 -0000
@@ -73,7 +73,7 @@
     apr_status_t (*tryacquire)(apr_proc_mutex_t *);
     apr_status_t (*release)(apr_proc_mutex_t *);
     apr_status_t (*cleanup)(void *);
-    apr_status_t (*child_init)(apr_proc_mutex_t **, apr_pool_t *, const char *);
+    apr_status_t (*child_init)(apr_proc_mutex_t *, const char *);
     const char *name;
 };
 typedef struct apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_lock_methods_t;
Index: locks/unix/global_mutex.c
===================================================================
RCS file: /home/cvs/apr/locks/unix/global_mutex.c,v
retrieving revision 1.12
diff -u -u -r1.12 global_mutex.c
--- locks/unix/global_mutex.c	13 Feb 2004 09:38:31 -0000	1.12
+++ locks/unix/global_mutex.c	13 Jun 2004 02:01:24 -0000
@@ -80,11 +80,23 @@
 APR_DECLARE(apr_status_t) apr_global_mutex_child_init(
                               apr_global_mutex_t **mutex,
                               const char *fname,
+                              apr_lockmech_e mech,
                               apr_pool_t *pool)
 {
     apr_status_t rv;
+    apr_global_mutex_t *m = *mutex;

-    rv = apr_proc_mutex_child_init(&((*mutex)->proc_mutex), fname, pool);
+    if (mech != APR_LOCK_SYSVSEM && mech != APR_LOCK_PROC_PTHREAD &&
+        mech != APR_LOCK_POSIXSEM && mech != APR_LOCK_FCNTL) {
+        m = (apr_global_mutex_t *)apr_palloc(pool, sizeof(*m));
+        m->pool = pool;
+    }
+
+    rv = apr_proc_mutex_child_init(&m->proc_mutex, fname, mech, m->pool);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
+    *mutex = m;
     return rv;
 }

Index: locks/unix/proc_mutex.c
===================================================================
RCS file: /home/cvs/apr/locks/unix/proc_mutex.c,v
retrieving revision 1.39
diff -u -u -r1.39 proc_mutex.c
--- locks/unix/proc_mutex.c	5 Jun 2004 13:33:19 -0000	1.39
+++ locks/unix/proc_mutex.c	13 Jun 2004 02:01:24 -0000
@@ -30,8 +30,7 @@

 #if APR_HAS_POSIXSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || \
     APR_HAS_PROC_PTHREAD_SERIALIZE || APR_HAS_SYSVSEM_SERIALIZE
-static apr_status_t proc_mutex_no_child_init(apr_proc_mutex_t **mutex,
-                                             apr_pool_t *cont,
+static apr_status_t proc_mutex_no_child_init(apr_proc_mutex_t *mutex,
                                              const char *fname)
 {
     return APR_SUCCESS;
@@ -608,27 +607,17 @@
     return APR_SUCCESS;
 }

-static apr_status_t proc_mutex_flock_child_init(apr_proc_mutex_t **mutex,
-                                                apr_pool_t *pool,
+static apr_status_t proc_mutex_flock_child_init(apr_proc_mutex_t *mutex,
                                                 const char *fname)
 {
-    apr_proc_mutex_t *new_mutex;
     int rv;

-    new_mutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
-
-    memcpy(new_mutex, *mutex, sizeof *new_mutex);
-    new_mutex->pool = pool;
-    if (!fname) {
-        fname = (*mutex)->fname;
-    }
-    new_mutex->fname = apr_pstrdup(pool, fname);
-    rv = apr_file_open(&new_mutex->interproc, new_mutex->fname,
-                       APR_WRITE, 0, new_mutex->pool);
+    mutex->fname = apr_pstrdup(mutex->pool, fname);
+    rv = apr_file_open(&mutex->interproc, mutex->fname, APR_WRITE, 0,
+                       mutex->pool);
     if (rv != APR_SUCCESS) {
         return rv;
     }
-    *mutex = new_mutex;
     return APR_SUCCESS;
 }

@@ -699,17 +688,36 @@
         return APR_ENOTIMPL;
 #endif
         break;
-    case APR_LOCK_DEFAULT:
+    case APR_LOCK_FORK_DEFAULT:
+#if APR_USE_FLOCK_SERIALIZE
+        new_mutex->inter_meth = &mutex_flock_methods;
+#elif APR_USE_SYSVSEM_SERIALIZE
+        new_mutex->inter_meth = &mutex_sysv_methods;
+#elif APR_USE_FCNTL_SERIALIZE
+        new_mutex->inter_meth = &mutex_fcntl_methods;
+#elif APR_USE_PROC_PTHREAD_SERIALIZE
+        new_mutex->inter_meth = &mutex_proc_pthread_methods;
+#elif APR_USE_POSIXSEM_SERIALIZE
+        new_mutex->inter_meth = &mutex_posixsem_methods;
+#else
+        return APR_ENOTIMPL;
+#endif
+        break;
+    case APR_LOCK_PROC_CREATE_DEFAULT:
 #if APR_USE_FLOCK_SERIALIZE
         new_mutex->inter_meth = &mutex_flock_methods;
+/*
 #elif APR_USE_SYSVSEM_SERIALIZE
         new_mutex->inter_meth = &mutex_sysv_methods;
+*/
 #elif APR_USE_FCNTL_SERIALIZE
         new_mutex->inter_meth = &mutex_fcntl_methods;
+/*
 #elif APR_USE_PROC_PTHREAD_SERIALIZE
         new_mutex->inter_meth = &mutex_proc_pthread_methods;
 #elif APR_USE_POSIXSEM_SERIALIZE
         new_mutex->inter_meth = &mutex_posixsem_methods;
+*/
 #else
         return APR_ENOTIMPL;
 #endif
@@ -725,7 +733,8 @@
     apr_status_t rv;
     apr_proc_mutex_t mutex;

-    if ((rv = proc_mutex_choose_method(&mutex, APR_LOCK_DEFAULT)) != APR_SUCCESS) {
+    if ((rv = proc_mutex_choose_method(&mutex, APR_LOCK_PROC_CREATE_DEFAULT)) !=
+        APR_SUCCESS) {
         return "unknown";
     }
     mutex.meth = mutex.inter_meth;
@@ -750,6 +759,25 @@
     return APR_SUCCESS;
 }

+static apr_status_t proc_mutex_child_init(apr_proc_mutex_t *new_mutex,
+                                          apr_lockmech_e mech,
+                                          const char *fname)
+{
+    apr_status_t rv;
+
+    if ((rv = proc_mutex_choose_method(new_mutex, mech)) != APR_SUCCESS) {
+        return rv;
+    }
+
+    new_mutex->meth = new_mutex->inter_meth;
+
+    if ((rv = new_mutex->meth->child_init(new_mutex, fname)) != APR_SUCCESS) {
+        return rv;
+    }
+
+    return APR_SUCCESS;
+}
+
 APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
                                                 const char *fname,
                                                 apr_lockmech_e mech,
@@ -775,9 +803,29 @@

 APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
                                                     const char *fname,
+                                                    apr_lockmech_e mech,
                                                     apr_pool_t *pool)
 {
-    return (*mutex)->meth->child_init(mutex, pool, fname);
+    apr_status_t rv;
+    apr_proc_mutex_t *new_mutex;
+
+    new_mutex = *mutex;
+
+    if (mech != APR_LOCK_SYSVSEM && mech != APR_LOCK_PROC_PTHREAD &&
+        mech != APR_LOCK_POSIXSEM && mech != APR_LOCK_FCNTL) {
+        new_mutex = (apr_proc_mutex_t *)apr_pcalloc(pool,
+                sizeof(apr_proc_mutex_t));
+
+        new_mutex->pool  = pool;
+#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
+        new_mutex->interproc = NULL;
+#endif
+    }
+    if ((rv = proc_mutex_child_init(new_mutex, mech, fname)) != APR_SUCCESS)
+        return rv;
+
+    *mutex = new_mutex;
+    return (*mutex)->meth->child_init(new_mutex, fname);
 }

 APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex)
Index: test/abts_tests.h
===================================================================
RCS file: /home/cvs/apr/test/abts_tests.h,v
retrieving revision 1.2
diff -u -u -r1.2 abts_tests.h
--- test/abts_tests.h	7 Jun 2004 21:33:25 -0000	1.2
+++ test/abts_tests.h	13 Jun 2004 02:01:24 -0000
@@ -34,9 +34,7 @@
     {testfmt},
     {testfnmatch},
     {testgetopt},
-#if 0 /* not ready yet due to API issues */
     {testglobalmutex},
-#endif
     {testhash},
     {testipsub},
     {testlock},
Index: test/globalmutexchild.c
===================================================================
RCS file: /home/cvs/apr/test/globalmutexchild.c,v
retrieving revision 1.3
diff -u -u -r1.3 globalmutexchild.c
--- test/globalmutexchild.c	4 Jun 2004 11:40:27 -0000	1.3
+++ test/globalmutexchild.c	13 Jun 2004 02:01:24 -0000
@@ -42,22 +42,26 @@
         mech = (apr_lockmech_e)apr_strtoi64(argv[1], NULL, 0);
     }
     else {
-        mech = APR_LOCK_DEFAULT;
+        mech = APR_LOCK_PROC_CREATE_DEFAULT;
     }
-    rv = apr_global_mutex_create(&global_lock, LOCKNAME, mech, p);
+    rv = apr_global_mutex_child_init(&global_lock, LOCKNAME, mech, p);
     if (rv != APR_SUCCESS) {
-        exit(-rv);
+        exit(1);
     }
-    apr_global_mutex_child_init(&global_lock, LOCKNAME, p);

     while (1) {
-        apr_global_mutex_lock(global_lock);
+        if (apr_global_mutex_lock(global_lock)) {
+            exit(1);
+        }
         if (i == MAX_ITER) {
             apr_global_mutex_unlock(global_lock);
             exit(i);
         }
         i++;
-        apr_global_mutex_unlock(global_lock);
+        if (apr_global_mutex_unlock(global_lock)) {
+            exit(1);
+        }
     }
-    exit(0);
+    /* If we actually get here, something is _REALLY_ wrong, fail.  */
+    exit(1);
 }
Index: test/testglobalmutex.c
===================================================================
RCS file: /home/cvs/apr/test/testglobalmutex.c,v
retrieving revision 1.14
diff -u -u -r1.14 testglobalmutex.c
--- test/testglobalmutex.c	9 Jun 2004 19:39:53 -0000	1.14
+++ test/testglobalmutex.c	13 Jun 2004 02:01:24 -0000
@@ -66,21 +66,23 @@
     case APR_LOCK_SYSVSEM: return "sysvsem";
     case APR_LOCK_PROC_PTHREAD: return "proc_pthread";
     case APR_LOCK_POSIXSEM: return "posixsem";
-    case APR_LOCK_DEFAULT: return "default";
+    case APR_LOCK_FORK_DEFAULT: return "fork default";
+    case APR_LOCK_PROC_CREATE_DEFAULT: return "proc create default";
     default: return "unknown";
     }
 }

-static void test_exclusive(abts_case *tc, void *data)
+static void test_exclusive_proc_create(abts_case *tc, void *data)
 {
     apr_lockmech_e mech = *(apr_lockmech_e *)data;
     apr_proc_t p1, p2, p3, p4;
     apr_status_t rv;
     apr_global_mutex_t *global_lock;
     int x = 0;
-    abts_log_message("lock mechanism is: ");
+    abts_log_message("calling apr_proc_exec for lock mechanism: ");
     abts_log_message(mutexname(mech));

+    apr_file_remove(LOCKNAME, p);
     rv = apr_global_mutex_create(&global_lock, LOCKNAME, mech, p);
     APR_ASSERT_SUCCESS(tc, "Error creating mutex", rv);

@@ -102,33 +104,132 @@
     }
 }

+static void fork_child(abts_case *tc, apr_lockmech_e mech,
+                       apr_proc_t *proc, apr_pool_t *p,
+                       apr_global_mutex_t *global_lock)
+{
+    apr_status_t rv;
+    int i = 0;
+
+    /* slight delay to allow things to settle */
+    apr_sleep(1);
+
+    rv = apr_proc_fork(proc, p);
+    if (rv == APR_INCHILD) {
+        apr_initialize();
+
+        rv = apr_global_mutex_child_init(&global_lock, LOCKNAME, mech, p);
+        if (rv != APR_SUCCESS) {
+            exit(1);
+        }
+
+        while (1) {
+            if (apr_global_mutex_lock(global_lock)) {
+                exit(1);
+            }
+            if (i == MAX_ITER) {
+                apr_global_mutex_unlock(global_lock);
+                exit(i);
+            }
+            i++;
+            if (apr_global_mutex_unlock(global_lock)) {
+                exit(1);
+            }
+        }
+        /* If we actually get here, something is _REALLY_ wrong, fail.  */
+        exit(1);
+    }
+}
+
+static void test_exclusive_fork(abts_case *tc, void *data)
+{
+    apr_lockmech_e mech = *(apr_lockmech_e *)data;
+    apr_proc_t p1, p2, p3, p4;
+    apr_status_t rv;
+    apr_global_mutex_t *global_lock;
+    int x = 0;
+    abts_log_message("calling fork for lock mechanism: ");
+    abts_log_message(mutexname(mech));
+
+    apr_file_remove(LOCKNAME, p);
+    rv = apr_global_mutex_create(&global_lock, LOCKNAME, mech, p);
+    APR_ASSERT_SUCCESS(tc, "Error creating mutex", rv);
+
+    fork_child(tc, mech, &p1, p, global_lock);
+    fork_child(tc, mech, &p2, p, global_lock);
+    fork_child(tc, mech, &p3, p, global_lock);
+    fork_child(tc, mech, &p4, p, global_lock);
+
+    x += wait_child(tc, &p1);
+    x += wait_child(tc, &p2);
+    x += wait_child(tc, &p3);
+    x += wait_child(tc, &p4);
+
+    abts_log_message("\n");
+    if (x != MAX_COUNTER) {
+        char buf[200];
+        sprintf(buf, "global mutex '%s' failed: %d not %d",
+                mutexname(mech), x, MAX_COUNTER);
+        abts_fail(tc, buf, __LINE__);
+    }
+}
+
 abts_suite *testglobalmutex(abts_suite *suite)
 {
     suite = ADD_SUITE(suite)

     apr_lockmech_e mech;

-    mech = APR_LOCK_DEFAULT;
-    abts_run_test(suite, test_exclusive, &mech);
+    /* first run the test using apr_proc_create */
+    mech = APR_LOCK_PROC_CREATE_DEFAULT;
+    abts_run_test(suite, test_exclusive_proc_create, &mech);
+#if APR_HAS_POSIXSEM_SERIALIZE
+    mech = APR_LOCK_POSIXSEM;
+    abts_run_test(suite, test_exclusive_proc_create, &mech);
+#endif
+/* XXX These mechanisms don't work with proc_create
+#if APR_HAS_SYSVSEM_SERIALIZE
+    mech = APR_LOCK_SYSVSEM;
+    abts_run_test(suite, test_exclusive_proc_create, &mech);
+#endif
+#if APR_HAS_PROC_PTHREAD_SERIALIZE
+    mech = APR_LOCK_PROC_PTHREAD;
+    abts_run_test(suite, test_exclusive_proc_create, &mech);
+#endif
+#if APR_HAS_FCNTL_SERIALIZE
+    mech = APR_LOCK_FCNTL;
+    abts_run_test(suite, test_exclusive_proc_create, &mech);
+#endif
+*/
+#if APR_HAS_FLOCK_SERIALIZE
+    mech = APR_LOCK_FLOCK;
+    abts_run_test(suite, test_exclusive_proc_create, &mech);
+#endif
+
+#if APR_HAS_FORK
+    /* second run the test using apr_fork iff the platform supports it. */
+    mech = APR_LOCK_FORK_DEFAULT;
+    abts_run_test(suite, test_exclusive_fork, &mech);
 #if APR_HAS_POSIXSEM_SERIALIZE
     mech = APR_LOCK_POSIXSEM;
-    abts_run_test(suite, test_exclusive, &mech);
+    abts_run_test(suite, test_exclusive_fork, &mech);
 #endif
 #if APR_HAS_SYSVSEM_SERIALIZE
     mech = APR_LOCK_SYSVSEM;
-    abts_run_test(suite, test_exclusive, &mech);
+    abts_run_test(suite, test_exclusive_fork, &mech);
 #endif
 #if APR_HAS_PROC_PTHREAD_SERIALIZE
     mech = APR_LOCK_PROC_PTHREAD;
-    abts_run_test(suite, test_exclusive, &mech);
+    abts_run_test(suite, test_exclusive_fork, &mech);
 #endif
 #if APR_HAS_FCNTL_SERIALIZE
     mech = APR_LOCK_FCNTL;
-    abts_run_test(suite, test_exclusive, &mech);
+    abts_run_test(suite, test_exclusive_fork, &mech);
 #endif
 #if APR_HAS_FLOCK_SERIALIZE
     mech = APR_LOCK_FLOCK;
-    abts_run_test(suite, test_exclusive, &mech);
+    abts_run_test(suite, test_exclusive_fork, &mech);
+#endif
 #endif

     return suite;
Index: test/testmutexscope.c
===================================================================
RCS file: /home/cvs/apr/test/testmutexscope.c,v
retrieving revision 1.6
diff -u -u -r1.6 testmutexscope.c
--- test/testmutexscope.c	13 Feb 2004 09:38:34 -0000	1.6
+++ test/testmutexscope.c	13 Jun 2004 02:01:25 -0000
@@ -185,7 +185,7 @@
         apr_lockmech_e mech;
         const char *mech_name;
     } lockmechs[] = {
-        {APR_LOCK_DEFAULT, "default"}
+        {APR_LOCK_PROC_CREATE_DEFAULT, "default"}
 #if APR_HAS_FLOCK_SERIALIZE
         ,{APR_LOCK_FLOCK, "flock"}
 #endif
Index: test/testprocmutex.c
===================================================================
RCS file: /home/cvs/apr/test/testprocmutex.c,v
retrieving revision 1.20
diff -u -u -r1.20 testprocmutex.c
--- test/testprocmutex.c	7 Jun 2004 21:21:35 -0000	1.20
+++ test/testprocmutex.c	13 Jun 2004 02:01:25 -0000
@@ -63,7 +63,7 @@
          */
         apr_initialize();

-        if (apr_proc_mutex_child_init(&proc_lock, NULL, p))
+        if (apr_proc_mutex_child_init(&proc_lock, "data/test", APR_LOCK_FORK_DEFAULT,
p))
             exit(1);

         do {
@@ -98,7 +98,7 @@
     apr_status_t rv;
     int n;

-    rv = apr_proc_mutex_create(&proc_lock, lockname, APR_LOCK_DEFAULT, p);
+    rv = apr_proc_mutex_create(&proc_lock, lockname, APR_LOCK_FORK_DEFAULT, p);
     APR_ASSERT_SUCCESS(tc, "create the mutex", rv);

     for (n = 0; n < CHILDREN; n++)
@@ -128,7 +128,7 @@
     APR_ASSERT_SUCCESS(tc, "create shm segment", rv);

     x = apr_shm_baseaddr_get(shm);
-    test_exclusive(tc, NULL);
+    test_exclusive(tc, "data/test");
 #else
     ABTS_NOT_IMPL(tc, "APR lacks fork() support");
 #endif


Mime
View raw message