blob: a81e13259ab69651456f6bfe93942105d5680e84 [file] [log] [blame]
Benny Prijono4766ffe2005-11-01 17:56:59 +00001/* $Id$
Benny Prijonodd859a62005-11-01 16:42:51 +00002 */
3#include <pj/lock.h>
4#include <pj/os.h>
5#include <pj/assert.h>
6#include <pj/pool.h>
7#include <pj/string.h>
8#include <pj/errno.h>
9
10
11typedef void LOCK_OBJ;
12
13/*
14 * Lock structure.
15 */
16struct pj_lock_t
17{
18 LOCK_OBJ *lock_object;
19
20 pj_status_t (*acquire) (LOCK_OBJ*);
21 pj_status_t (*tryacquire) (LOCK_OBJ*);
22 pj_status_t (*release) (LOCK_OBJ*);
23 pj_status_t (*destroy) (LOCK_OBJ*);
24};
25
26typedef pj_status_t (*FPTR)(LOCK_OBJ*);
27
28/******************************************************************************
29 * Implementation of lock object with mutex.
30 */
31static pj_lock_t mutex_lock_template =
32{
33 NULL,
34 (FPTR) &pj_mutex_lock,
35 (FPTR) &pj_mutex_trylock,
36 (FPTR) &pj_mutex_unlock,
37 (FPTR) &pj_mutex_destroy
38};
39
40static pj_status_t create_mutex_lock( pj_pool_t *pool,
41 const char *name,
42 int type,
43 pj_lock_t **lock )
44{
45 pj_lock_t *p_lock;
46 pj_status_t rc;
47
48 PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);
49
50 p_lock = pj_pool_alloc(pool, sizeof(pj_lock_t));
51 if (!p_lock)
52 return PJ_ENOMEM;
53
54 pj_memcpy(p_lock, &mutex_lock_template, sizeof(pj_lock_t));
55 rc = pj_mutex_create(pool, name, type, (pj_mutex_t**)&p_lock->lock_object);
56 if (rc != PJ_SUCCESS)
57 return rc;
58
59 *lock = p_lock;
60 return PJ_SUCCESS;
61}
62
63
64PJ_DEF(pj_status_t) pj_lock_create_simple_mutex( pj_pool_t *pool,
65 const char *name,
66 pj_lock_t **lock )
67{
68 return create_mutex_lock(pool, name, PJ_MUTEX_SIMPLE, lock);
69}
70
71PJ_DEF(pj_status_t) pj_lock_create_recursive_mutex( pj_pool_t *pool,
72 const char *name,
73 pj_lock_t **lock )
74{
75 return create_mutex_lock(pool, name, PJ_MUTEX_RECURSE, lock);
76}
77
78
79/******************************************************************************
80 * Implementation of NULL lock object.
81 */
82static pj_status_t null_op(void *arg)
83{
84 PJ_UNUSED_ARG(arg);
85 return PJ_SUCCESS;
86}
87
88static pj_lock_t null_lock_template =
89{
90 NULL,
91 &null_op,
92 &null_op,
93 &null_op,
94 &null_op
95};
96
97PJ_DEF(pj_status_t) pj_lock_create_null_mutex( pj_pool_t *pool,
98 const char *name,
99 pj_lock_t **lock )
100{
101 PJ_UNUSED_ARG(name);
102 PJ_UNUSED_ARG(pool);
103
104 PJ_ASSERT_RETURN(lock, PJ_EINVAL);
105
106 *lock = &null_lock_template;
107 return PJ_SUCCESS;
108}
109
110
111/******************************************************************************
112 * Implementation of semaphore lock object.
113 */
114#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
115
116static pj_lock_t sem_lock_template =
117{
118 NULL,
119 (FPTR) &pj_sem_wait,
120 (FPTR) &pj_sem_trywait,
121 (FPTR) &pj_sem_post,
122 (FPTR) &pj_sem_destroy
123};
124
125PJ_DEF(pj_status_t) pj_lock_create_semaphore( pj_pool_t *pool,
126 const char *name,
127 unsigned initial,
128 unsigned max,
129 pj_lock_t **lock )
130{
131 pj_lock_t *p_lock;
132 pj_status_t rc;
133
134 PJ_ASSERT_RETURN(pool && lock, PJ_EINVAL);
135
136 p_lock = pj_pool_alloc(pool, sizeof(pj_lock_t));
137 if (!p_lock)
138 return PJ_ENOMEM;
139
140 pj_memcpy(p_lock, &sem_lock_template, sizeof(pj_lock_t));
141 rc = pj_sem_create( pool, name, initial, max,
142 (pj_sem_t**)&p_lock->lock_object);
143 if (rc != PJ_SUCCESS)
144 return rc;
145
146 *lock = p_lock;
147
148 return PJ_SUCCESS;
149}
150
151
152#endif /* PJ_HAS_SEMAPHORE */
153
154
155PJ_DEF(pj_status_t) pj_lock_acquire( pj_lock_t *lock )
156{
157 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
158 return (*lock->acquire)(lock->lock_object);
159}
160
161PJ_DEF(pj_status_t) pj_lock_tryacquire( pj_lock_t *lock )
162{
163 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
164 return (*lock->tryacquire)(lock->lock_object);
165}
166
167PJ_DEF(pj_status_t) pj_lock_release( pj_lock_t *lock )
168{
169 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
170 return (*lock->release)(lock->lock_object);
171}
172
173PJ_DEF(pj_status_t) pj_lock_destroy( pj_lock_t *lock )
174{
175 PJ_ASSERT_RETURN(lock != NULL, PJ_EINVAL);
176 return (*lock->destroy)(lock->lock_object);
177}
178