--- test/testglobalmutex.h.orig 2006-04-12 14:06:21.813977886 -0400 +++ test/testglobalmutex.h 2006-04-12 15:05:50.722110207 -0400 @@ -17,9 +17,13 @@ #ifndef TESTGLOBALMUTEX_H #define TESTGLOBALMUTEX_H +#define NORMAL_MODE 0 +#define TRY_MODE 1 + /* set this to 255 so that the child processes can return it successfully. */ #define MAX_ITER 255 #define MAX_COUNTER (MAX_ITER * 4) +#define MAX_WAIT_USEC (1000*1000) #define LOCKNAME "data/apr_globalmutex.lock" --- test/testglobalmutex.c.orig 2006-04-12 14:01:00.346792130 -0400 +++ test/testglobalmutex.c 2006-04-12 15:44:19.372036834 -0400 @@ -21,11 +21,11 @@ #include "apr_errno.h" #include "testutil.h" -static void launch_child(abts_case *tc, apr_lockmech_e mech, +static void launch_child(abts_case *tc, int mode, apr_lockmech_e mech, apr_proc_t *proc, apr_pool_t *p) { apr_procattr_t *procattr; - const char *args[3]; + const char *args[4]; apr_status_t rv; rv = apr_procattr_create(&procattr, p); @@ -39,8 +39,9 @@ APR_ASSERT_SUCCESS(tc, "Couldn't set error check in procattr", rv); args[0] = "globalmutexchild" EXTENSION; - args[1] = (const char*)apr_itoa(p, (int)mech); - args[2] = NULL; + args[1] = (const char*)apr_itoa(p, mode); + args[2] = (const char*)apr_itoa(p, (int)mech); + args[3] = NULL; rv = apr_proc_create(proc, "./globalmutexchild" EXTENSION, args, NULL, procattr, p); APR_ASSERT_SUCCESS(tc, "Couldn't launch program", rv); @@ -81,14 +82,15 @@ int x = 0; abts_log_message("lock mechanism is: "); abts_log_message(mutexname(mech)); + abts_log_message("using normal lock mode"); rv = apr_global_mutex_create(&global_lock, LOCKNAME, mech, p); APR_ASSERT_SUCCESS(tc, "Error creating mutex", rv); - launch_child(tc, mech, &p1, p); - launch_child(tc, mech, &p2, p); - launch_child(tc, mech, &p3, p); - launch_child(tc, mech, &p4, p); + launch_child(tc, NORMAL_MODE, mech, &p1, p); + launch_child(tc, NORMAL_MODE, mech, &p2, p); + launch_child(tc, NORMAL_MODE, mech, &p3, p); + launch_child(tc, NORMAL_MODE, mech, &p4, p); x += wait_child(tc, &p1); x += wait_child(tc, &p2); @@ -97,7 +99,27 @@ if (x != MAX_COUNTER) { char buf[200]; - sprintf(buf, "global mutex '%s' failed: %d not %d", + sprintf(buf, "global mutex '%s' failed: %d not %d (in normal mode)", + mutexname(mech), x, MAX_COUNTER); + abts_fail(tc, buf, __LINE__); + } + + x = 0; + abts_log_message("using try lock mode"); + + launch_child(tc, TRY_MODE, mech, &p1, p); + launch_child(tc, TRY_MODE, mech, &p2, p); + launch_child(tc, TRY_MODE, mech, &p3, p); + launch_child(tc, TRY_MODE, mech, &p4, p); + + x += wait_child(tc, &p1); + x += wait_child(tc, &p2); + x += wait_child(tc, &p3); + x += wait_child(tc, &p4); + + if (x != MAX_COUNTER) { + char buf[200]; + sprintf(buf, "global mutex '%s' failed: %d not %d (in try mode)", mutexname(mech), x, MAX_COUNTER); abts_fail(tc, buf, __LINE__); } --- test/globalmutexchild.c.orig 2006-04-12 14:01:05.148765046 -0400 +++ test/globalmutexchild.c 2006-04-12 15:43:16.410405798 -0400 @@ -31,6 +31,7 @@ { apr_pool_t *p; int i = 0; + int mode; apr_lockmech_e mech; apr_global_mutex_t *global_lock; apr_status_t rv; @@ -40,7 +41,13 @@ apr_pool_create(&p, NULL); if (argc >= 2) { - mech = (apr_lockmech_e)apr_strtoi64(argv[1], NULL, 0); + mode = atoi(argv[1]); + } + else { + mode = NORMAL_MODE; + } + if (argc >= 3) { + mech = (apr_lockmech_e)apr_strtoi64(argv[2], NULL, 0); } else { mech = APR_LOCK_DEFAULT; @@ -52,7 +59,20 @@ apr_global_mutex_child_init(&global_lock, LOCKNAME, p); while (1) { - apr_global_mutex_lock(global_lock); + if (mode == NORMAL_MODE) { + apr_global_mutex_lock(global_lock); + } + else { + int wait_usec = 0; + + while (rv = apr_global_mutex_trylock(global_lock)) { + if (!APR_STATUS_IS_EBUSY(rv)) + exit(-rv); + if (++wait_usec >= MAX_WAIT_USEC) + exit(-APR_EBUSY); + apr_sleep(1); + } + } if (i == MAX_ITER) { apr_global_mutex_unlock(global_lock); exit(i);