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