blob: 98cb50db2880e25e906d650b23b6cec176e16fc4 [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00005 *
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 <pj/lock.h>
21#include <pj/os.h>
22#include <pj/assert.h>
23#include <pj/pool.h>
24#include <pj/string.h>
25#include <pj/errno.h>
26
27
28typedef void LOCK_OBJ;
29
30/*
31 * Lock structure.
32 */
33struct pj_lock_t
34{
35 LOCK_OBJ *lock_object;
36
37 pj_status_t (*acquire) (LOCK_OBJ*);
38 pj_status_t (*tryacquire) (LOCK_OBJ*);
39 pj_status_t (*release) (LOCK_OBJ*);
40 pj_status_t (*destroy) (LOCK_OBJ*);
41};
42
43typedef pj_status_t (*FPTR)(LOCK_OBJ*);
44
45/******************************************************************************
46 * Implementation of lock object with mutex.
47 */
48static pj_lock_t mutex_lock_template =
49{
50 NULL,
51 (FPTR) &pj_mutex_lock,
52 (FPTR) &pj_mutex_trylock,
53 (FPTR) &pj_mutex_unlock,
54 (FPTR) &pj_mutex_destroy
55};
56
57static pj_status_t create_mutex_lock( pj_pool_t *pool,
58 const char *name,
59 int type,
60 pj_lock_t **lock )
61{
62 pj_lock_t *p_lock;
Benny Prijonoe960bb52007-01-21 17:53:39 +000063 pj_mutex_t *mutex;
Benny Prijono9033e312005-11-21 02:08:39 +000064 pj_status_t rc;
65
66 PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);
67
Benny Prijonof260e462007-04-30 21:03:32 +000068 p_lock = PJ_POOL_ALLOC_T(pool, pj_lock_t);
Benny Prijono9033e312005-11-21 02:08:39 +000069 if (!p_lock)
70 return PJ_ENOMEM;
71
72 pj_memcpy(p_lock, &mutex_lock_template, sizeof(pj_lock_t));
Benny Prijonoe960bb52007-01-21 17:53:39 +000073 rc = pj_mutex_create(pool, name, type, &mutex);
Benny Prijono9033e312005-11-21 02:08:39 +000074 if (rc != PJ_SUCCESS)
75 return rc;
76
Benny Prijonoe960bb52007-01-21 17:53:39 +000077 p_lock->lock_object = mutex;
Benny Prijono9033e312005-11-21 02:08:39 +000078 *lock = p_lock;
79 return PJ_SUCCESS;
80}
81
82
83PJ_DEF(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,
84 const char *name,
85 pj_lock_t **lock )
86{
87 return create_mutex_lock(pool, name, PJ_MUTEX_SIMPLE, lock);
88}
89
90PJ_DEF(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,
91 const char *name,
92 pj_lock_t **lock )
93{
94 return create_mutex_lock(pool, name, PJ_MUTEX_RECURSE, lock);
95}
96
97
98/******************************************************************************
99 * Implementation of NULL lock object.
100 */
101static pj_status_t null_op(void *arg)
102{
103 PJ_UNUSED_ARG(arg);
104 return PJ_SUCCESS;
105}
106
107static pj_lock_t null_lock_template =
108{
109 NULL,
110 &null_op,
111 &null_op,
112 &null_op,
113 &null_op
114};
115
116PJ_DEF(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,
117 const char *name,
118 pj_lock_t **lock )
119{
120 PJ_UNUSED_ARG(name);
121 PJ_UNUSED_ARG(pool);
122
123 PJ_ASSERT_RETURN(lock, PJ_EINVAL);
124
125 *lock = &null_lock_template;
126 return PJ_SUCCESS;
127}
128
129
130/******************************************************************************
131 * Implementation of semaphore lock object.
132 */
133#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
134
135static pj_lock_t sem_lock_template =
136{
137 NULL,
138 (FPTR) &pj_sem_wait,
139 (FPTR) &pj_sem_trywait,
140 (FPTR) &pj_sem_post,
141 (FPTR) &pj_sem_destroy
142};
143
144PJ_DEF(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool,
145 const char *name,
146 unsigned initial,
147 unsigned max,
148 pj_lock_t **lock )
149{
150 pj_lock_t *p_lock;
Benny Prijonoe960bb52007-01-21 17:53:39 +0000151 pj_sem_t *sem;
Benny Prijono9033e312005-11-21 02:08:39 +0000152 pj_status_t rc;
153
154 PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);
155
Benny Prijonof260e462007-04-30 21:03:32 +0000156 p_lock = PJ_POOL_ALLOC_T(pool, pj_lock_t);
Benny Prijono9033e312005-11-21 02:08:39 +0000157 if (!p_lock)
158 return PJ_ENOMEM;
159
160 pj_memcpy(p_lock, &sem_lock_template, sizeof(pj_lock_t));
Benny Prijonoe960bb52007-01-21 17:53:39 +0000161 rc = pj_sem_create( pool, name, initial, max, &sem);
Benny Prijono9033e312005-11-21 02:08:39 +0000162 if (rc != PJ_SUCCESS)
163 return rc;
164
Benny Prijonoe960bb52007-01-21 17:53:39 +0000165 p_lock->lock_object = sem;
Benny Prijono9033e312005-11-21 02:08:39 +0000166 *lock = p_lock;
167
168 return PJ_SUCCESS;
169}
170
171
172#endif /* PJ_HAS_SEMAPHORE */
173
174
175PJ_DEF(pj_status_t) pj_lock_acquire( pj_lock_t *lock )
176{
177 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
178 return (*lock->acquire)(lock->lock_object);
179}
180
181PJ_DEF(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock )
182{
183 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
184 return (*lock->tryacquire)(lock->lock_object);
185}
186
187PJ_DEF(pj_status_t) pj_lock_release( pj_lock_t *lock )
188{
189 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
190 return (*lock->release)(lock->lock_object);
191}
192
193PJ_DEF(pj_status_t) pj_lock_destroy( pj_lock_t *lock )
194{
195 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
196 return (*lock->destroy)(lock->lock_object);
197}
198