blob: 148037621ea15e07c6888dbcd12c82f2cef13067 [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono32177c02008-06-20 22:44:47 +00003 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pj/lock.h>
20#include <pj/os.h>
21#include <pj/assert.h>
22#include <pj/pool.h>
23#include <pj/string.h>
24#include <pj/errno.h>
25
26
27typedef void LOCK_OBJ;
28
29/*
30 * Lock structure.
31 */
32struct pj_lock_t
33{
34 LOCK_OBJ *lock_object;
35
36 pj_status_t (*acquire) (LOCK_OBJ*);
37 pj_status_t (*tryacquire) (LOCK_OBJ*);
38 pj_status_t (*release) (LOCK_OBJ*);
39 pj_status_t (*destroy) (LOCK_OBJ*);
40};
41
42typedef pj_status_t (*FPTR)(LOCK_OBJ*);
43
44/******************************************************************************
45 * Implementation of lock object with mutex.
46 */
47static pj_lock_t mutex_lock_template =
48{
49 NULL,
50 (FPTR) &pj_mutex_lock,
51 (FPTR) &pj_mutex_trylock,
52 (FPTR) &pj_mutex_unlock,
53 (FPTR) &pj_mutex_destroy
54};
55
56static pj_status_t create_mutex_lock( pj_pool_t *pool,
57 const char *name,
58 int type,
59 pj_lock_t **lock )
60{
61 pj_lock_t *p_lock;
Benny Prijonoe960bb52007-01-21 17:53:39 +000062 pj_mutex_t *mutex;
Benny Prijono9033e312005-11-21 02:08:39 +000063 pj_status_t rc;
64
65 PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);
66
Benny Prijonof260e462007-04-30 21:03:32 +000067 p_lock = PJ_POOL_ALLOC_T(pool, pj_lock_t);
Benny Prijono9033e312005-11-21 02:08:39 +000068 if (!p_lock)
69 return PJ_ENOMEM;
70
71 pj_memcpy(p_lock, &mutex_lock_template, sizeof(pj_lock_t));
Benny Prijonoe960bb52007-01-21 17:53:39 +000072 rc = pj_mutex_create(pool, name, type, &mutex);
Benny Prijono9033e312005-11-21 02:08:39 +000073 if (rc != PJ_SUCCESS)
74 return rc;
75
Benny Prijonoe960bb52007-01-21 17:53:39 +000076 p_lock->lock_object = mutex;
Benny Prijono9033e312005-11-21 02:08:39 +000077 *lock = p_lock;
78 return PJ_SUCCESS;
79}
80
81
82PJ_DEF(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,
83 const char *name,
84 pj_lock_t **lock )
85{
86 return create_mutex_lock(pool, name, PJ_MUTEX_SIMPLE, lock);
87}
88
89PJ_DEF(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,
90 const char *name,
91 pj_lock_t **lock )
92{
93 return create_mutex_lock(pool, name, PJ_MUTEX_RECURSE, lock);
94}
95
96
97/******************************************************************************
98 * Implementation of NULL lock object.
99 */
100static pj_status_t null_op(void *arg)
101{
102 PJ_UNUSED_ARG(arg);
103 return PJ_SUCCESS;
104}
105
106static pj_lock_t null_lock_template =
107{
108 NULL,
109 &null_op,
110 &null_op,
111 &null_op,
112 &null_op
113};
114
115PJ_DEF(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,
116 const char *name,
117 pj_lock_t **lock )
118{
119 PJ_UNUSED_ARG(name);
120 PJ_UNUSED_ARG(pool);
121
122 PJ_ASSERT_RETURN(lock, PJ_EINVAL);
123
124 *lock = &null_lock_template;
125 return PJ_SUCCESS;
126}
127
128
129/******************************************************************************
130 * Implementation of semaphore lock object.
131 */
132#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
133
134static pj_lock_t sem_lock_template =
135{
136 NULL,
137 (FPTR) &pj_sem_wait,
138 (FPTR) &pj_sem_trywait,
139 (FPTR) &pj_sem_post,
140 (FPTR) &pj_sem_destroy
141};
142
143PJ_DEF(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool,
144 const char *name,
145 unsigned initial,
146 unsigned max,
147 pj_lock_t **lock )
148{
149 pj_lock_t *p_lock;
Benny Prijonoe960bb52007-01-21 17:53:39 +0000150 pj_sem_t *sem;
Benny Prijono9033e312005-11-21 02:08:39 +0000151 pj_status_t rc;
152
153 PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);
154
Benny Prijonof260e462007-04-30 21:03:32 +0000155 p_lock = PJ_POOL_ALLOC_T(pool, pj_lock_t);
Benny Prijono9033e312005-11-21 02:08:39 +0000156 if (!p_lock)
157 return PJ_ENOMEM;
158
159 pj_memcpy(p_lock, &sem_lock_template, sizeof(pj_lock_t));
Benny Prijonoe960bb52007-01-21 17:53:39 +0000160 rc = pj_sem_create( pool, name, initial, max, &sem);
Benny Prijono9033e312005-11-21 02:08:39 +0000161 if (rc != PJ_SUCCESS)
162 return rc;
163
Benny Prijonoe960bb52007-01-21 17:53:39 +0000164 p_lock->lock_object = sem;
Benny Prijono9033e312005-11-21 02:08:39 +0000165 *lock = p_lock;
166
167 return PJ_SUCCESS;
168}
169
170
171#endif /* PJ_HAS_SEMAPHORE */
172
173
174PJ_DEF(pj_status_t) pj_lock_acquire( pj_lock_t *lock )
175{
176 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
177 return (*lock->acquire)(lock->lock_object);
178}
179
180PJ_DEF(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock )
181{
182 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
183 return (*lock->tryacquire)(lock->lock_object);
184}
185
186PJ_DEF(pj_status_t) pj_lock_release( pj_lock_t *lock )
187{
188 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
189 return (*lock->release)(lock->lock_object);
190}
191
192PJ_DEF(pj_status_t) pj_lock_destroy( pj_lock_t *lock )
193{
194 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
195 return (*lock->destroy)(lock->lock_object);
196}
197