blob: e9905f3dad51781f079cbaaf729534cf29a32d1b [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include "test.h"
21#include <pjlib.h>
22
23#if INCLUDE_MUTEX_TEST
24
25#undef TRACE_
26//#define TRACE_(x) PJ_LOG(3,x)
27#define TRACE_(x)
28
29/* Test witn non-recursive mutex. */
30static int simple_mutex_test(pj_pool_t *pool)
31{
32 pj_status_t rc;
33 pj_mutex_t *mutex;
34
35 PJ_LOG(3,("", "...testing simple mutex"));
36
37 /* Create mutex. */
38 TRACE_(("", "....create mutex"));
39 rc = pj_mutex_create( pool, "", PJ_MUTEX_SIMPLE, &mutex);
40 if (rc != PJ_SUCCESS) {
41 app_perror("...error: pj_mutex_create", rc);
42 return -10;
43 }
44
45 /* Normal lock/unlock cycle. */
46 TRACE_(("", "....lock mutex"));
47 rc = pj_mutex_lock(mutex);
48 if (rc != PJ_SUCCESS) {
49 app_perror("...error: pj_mutex_lock", rc);
50 return -20;
51 }
52 TRACE_(("", "....unlock mutex"));
53 rc = pj_mutex_unlock(mutex);
54 if (rc != PJ_SUCCESS) {
55 app_perror("...error: pj_mutex_unlock", rc);
56 return -30;
57 }
58
59 /* Lock again. */
60 TRACE_(("", "....lock mutex"));
61 rc = pj_mutex_lock(mutex);
62 if (rc != PJ_SUCCESS) return -40;
63
64 /* Try-lock should fail. It should not deadlocked. */
65 TRACE_(("", "....trylock mutex"));
66 rc = pj_mutex_trylock(mutex);
67 if (rc == PJ_SUCCESS)
68 PJ_LOG(3,("", "...info: looks like simple mutex is recursive"));
69
70 /* Unlock and done. */
71 TRACE_(("", "....unlock mutex"));
72 rc = pj_mutex_unlock(mutex);
73 if (rc != PJ_SUCCESS) return -50;
74
75 TRACE_(("", "....destroy mutex"));
76 rc = pj_mutex_destroy(mutex);
77 if (rc != PJ_SUCCESS) return -60;
78
79 TRACE_(("", "....done"));
80 return PJ_SUCCESS;
81}
82
83
84/* Test with recursive mutex. */
85static int recursive_mutex_test(pj_pool_t *pool)
86{
87 pj_status_t rc;
88 pj_mutex_t *mutex;
89
90 PJ_LOG(3,("", "...testing recursive mutex"));
91
92 /* Create mutex. */
93 TRACE_(("", "....create mutex"));
94 rc = pj_mutex_create( pool, "", PJ_MUTEX_RECURSE, &mutex);
95 if (rc != PJ_SUCCESS) {
96 app_perror("...error: pj_mutex_create", rc);
97 return -10;
98 }
99
100 /* Normal lock/unlock cycle. */
101 TRACE_(("", "....lock mutex"));
102 rc = pj_mutex_lock(mutex);
103 if (rc != PJ_SUCCESS) {
104 app_perror("...error: pj_mutex_lock", rc);
105 return -20;
106 }
107 TRACE_(("", "....unlock mutex"));
108 rc = pj_mutex_unlock(mutex);
109 if (rc != PJ_SUCCESS) {
110 app_perror("...error: pj_mutex_unlock", rc);
111 return -30;
112 }
113
114 /* Lock again. */
115 TRACE_(("", "....lock mutex"));
116 rc = pj_mutex_lock(mutex);
117 if (rc != PJ_SUCCESS) return -40;
118
119 /* Try-lock should NOT fail. . */
120 TRACE_(("", "....trylock mutex"));
121 rc = pj_mutex_trylock(mutex);
122 if (rc != PJ_SUCCESS) {
123 app_perror("...error: recursive mutex is not recursive!", rc);
124 return -40;
125 }
126
127 /* Locking again should not fail. */
128 TRACE_(("", "....lock mutex"));
129 rc = pj_mutex_lock(mutex);
130 if (rc != PJ_SUCCESS) {
131 app_perror("...error: recursive mutex is not recursive!", rc);
132 return -45;
133 }
134
135 /* Unlock several times and done. */
136 TRACE_(("", "....unlock mutex 3x"));
137 rc = pj_mutex_unlock(mutex);
138 if (rc != PJ_SUCCESS) return -50;
139 rc = pj_mutex_unlock(mutex);
140 if (rc != PJ_SUCCESS) return -51;
141 rc = pj_mutex_unlock(mutex);
142 if (rc != PJ_SUCCESS) return -52;
143
144 TRACE_(("", "....destroy mutex"));
145 rc = pj_mutex_destroy(mutex);
146 if (rc != PJ_SUCCESS) return -60;
147
148 TRACE_(("", "....done"));
149 return PJ_SUCCESS;
150}
151
152#if PJ_HAS_SEMAPHORE
153static int semaphore_test(pj_pool_t *pool)
154{
155 pj_sem_t *sem;
156 pj_status_t status;
157
158 PJ_LOG(3,("", "...testing semaphore"));
159
160 status = pj_sem_create(pool, NULL, 0, 1, &sem);
161 if (status != PJ_SUCCESS) {
162 app_perror("...error: pj_sem_create()", status);
163 return -151;
164 }
165
166 status = pj_sem_post(sem);
167 if (status != PJ_SUCCESS) {
168 app_perror("...error: pj_sem_post()", status);
169 pj_sem_destroy(sem);
170 return -153;
171 }
172
173 status = pj_sem_trywait(sem);
174 if (status != PJ_SUCCESS) {
175 app_perror("...error: pj_sem_trywait()", status);
176 pj_sem_destroy(sem);
177 return -156;
178 }
179
180 status = pj_sem_post(sem);
181 if (status != PJ_SUCCESS) {
182 app_perror("...error: pj_sem_post()", status);
183 pj_sem_destroy(sem);
184 return -159;
185 }
186
187 status = pj_sem_wait(sem);
188 if (status != PJ_SUCCESS) {
189 app_perror("...error: pj_sem_wait()", status);
190 pj_sem_destroy(sem);
191 return -161;
192 }
193
194 status = pj_sem_destroy(sem);
195 if (status != PJ_SUCCESS) {
196 app_perror("...error: pj_sem_destroy()", status);
197 return -163;
198 }
199
200 return 0;
201}
202#endif /* PJ_HAS_SEMAPHORE */
203
204
205int mutex_test(void)
206{
207 pj_pool_t *pool;
208 int rc;
209
210 pool = pj_pool_create(mem, "", 4000, 4000, NULL);
211
212 rc = simple_mutex_test(pool);
213 if (rc != 0)
214 return rc;
215
216 rc = recursive_mutex_test(pool);
217 if (rc != 0)
218 return rc;
219
220#if PJ_HAS_SEMAPHORE
221 rc = semaphore_test(pool);
222 if (rc != 0)
223 return rc;
224#endif
225
226 pj_pool_release(pool);
227
228 return 0;
229}
230
231#else
232int dummy_mutex_test;
233#endif
234