xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/test/testglobalmutex.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "testglobalmutex.h"
18 #include "apr_thread_proc.h"
19 #include "apr_global_mutex.h"
20 #include "apr_strings.h"
21 #include "apr_errno.h"
22 #include "testutil.h"
23 
launch_child(abts_case * tc,apr_lockmech_e mech,apr_proc_t * proc,apr_pool_t * p)24 static void launch_child(abts_case *tc, apr_lockmech_e mech,
25                          apr_proc_t *proc, apr_pool_t *p)
26 {
27     apr_procattr_t *procattr;
28     const char *args[3];
29     apr_status_t rv;
30 
31     rv = apr_procattr_create(&procattr, p);
32     APR_ASSERT_SUCCESS(tc, "Couldn't create procattr", rv);
33 
34     rv = apr_procattr_io_set(procattr, APR_NO_PIPE, APR_NO_PIPE,
35             APR_NO_PIPE);
36     APR_ASSERT_SUCCESS(tc, "Couldn't set io in procattr", rv);
37 
38     rv = apr_procattr_error_check_set(procattr, 1);
39     APR_ASSERT_SUCCESS(tc, "Couldn't set error check in procattr", rv);
40 
41     args[0] = "globalmutexchild" EXTENSION;
42     args[1] = (const char*)apr_itoa(p, (int)mech);
43     args[2] = NULL;
44     rv = apr_proc_create(proc, TESTBINPATH "globalmutexchild" EXTENSION, args, NULL,
45             procattr, p);
46     APR_ASSERT_SUCCESS(tc, "Couldn't launch program", rv);
47 }
48 
wait_child(abts_case * tc,apr_proc_t * proc)49 static int wait_child(abts_case *tc, apr_proc_t *proc)
50 {
51     int exitcode;
52     apr_exit_why_e why;
53 
54     ABTS_ASSERT(tc, "Error waiting for child process",
55             apr_proc_wait(proc, &exitcode, &why, APR_WAIT) == APR_CHILD_DONE);
56 
57     ABTS_ASSERT(tc, "child didn't terminate normally", why == APR_PROC_EXIT);
58     return exitcode;
59 }
60 
61 /* return symbolic name for a locking meechanism */
mutexname(apr_lockmech_e mech)62 static const char *mutexname(apr_lockmech_e mech)
63 {
64     switch (mech) {
65     case APR_LOCK_FCNTL: return "fcntl";
66     case APR_LOCK_FLOCK: return "flock";
67     case APR_LOCK_SYSVSEM: return "sysvsem";
68     case APR_LOCK_PROC_PTHREAD: return "proc_pthread";
69     case APR_LOCK_POSIXSEM: return "posixsem";
70     case APR_LOCK_DEFAULT: return "default";
71     default: return "unknown";
72     }
73 }
74 
test_exclusive(abts_case * tc,void * data)75 static void test_exclusive(abts_case *tc, void *data)
76 {
77     apr_lockmech_e mech = *(apr_lockmech_e *)data;
78     apr_proc_t p1, p2, p3, p4;
79     apr_status_t rv;
80     apr_global_mutex_t *global_lock;
81     int x = 0;
82     abts_log_message("lock mechanism is: ");
83     abts_log_message(mutexname(mech));
84 
85     rv = apr_global_mutex_create(&global_lock, LOCKNAME, mech, p);
86     APR_ASSERT_SUCCESS(tc, "Error creating mutex", rv);
87 
88     launch_child(tc, mech, &p1, p);
89     launch_child(tc, mech, &p2, p);
90     launch_child(tc, mech, &p3, p);
91     launch_child(tc, mech, &p4, p);
92 
93     x += wait_child(tc, &p1);
94     x += wait_child(tc, &p2);
95     x += wait_child(tc, &p3);
96     x += wait_child(tc, &p4);
97 
98     if (x != MAX_COUNTER) {
99         char buf[200];
100         sprintf(buf, "global mutex '%s' failed: %d not %d",
101                 mutexname(mech), x, MAX_COUNTER);
102         abts_fail(tc, buf, __LINE__);
103     }
104 }
105 
testglobalmutex(abts_suite * suite)106 abts_suite *testglobalmutex(abts_suite *suite)
107 {
108     apr_lockmech_e mech = APR_LOCK_DEFAULT;
109 
110     suite = ADD_SUITE(suite)
111     abts_run_test(suite, test_exclusive, &mech);
112 #if APR_HAS_POSIXSEM_SERIALIZE
113     mech = APR_LOCK_POSIXSEM;
114     abts_run_test(suite, test_exclusive, &mech);
115 #endif
116 #if APR_HAS_SYSVSEM_SERIALIZE
117     mech = APR_LOCK_SYSVSEM;
118     abts_run_test(suite, test_exclusive, &mech);
119 #endif
120 #if APR_HAS_PROC_PTHREAD_SERIALIZE
121     mech = APR_LOCK_PROC_PTHREAD;
122     abts_run_test(suite, test_exclusive, &mech);
123 #endif
124 #if APR_HAS_FCNTL_SERIALIZE
125     mech = APR_LOCK_FCNTL;
126     abts_run_test(suite, test_exclusive, &mech);
127 #endif
128 #if APR_HAS_FLOCK_SERIALIZE
129     mech = APR_LOCK_FLOCK;
130     abts_run_test(suite, test_exclusive, &mech);
131 #endif
132 
133     return suite;
134 }
135 
136