Merge Samba3 and Samba4 together
[amitay/samba.git] / source4 / lib / appweb / ejs-2.0 / mpr / mprLock.c
1 /**
2  *      @file   mprThread.c
3  *      @brief  Mbedthis Portable Runtime Base Thread Locking Support
4  */
5
6 /*
7  *      @copy   default
8  *
9  *      Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
10  *      
11  *      This software is distributed under commercial and open source licenses.
12  *      You may use the GPL open source license described below or you may acquire 
13  *      a commercial license from Mbedthis Software. You agree to be fully bound 
14  *      by the terms of either license. Consult the LICENSE.TXT distributed with 
15  *      this software for full details.
16  *      
17  *      This software is open source; you can redistribute it and/or modify it 
18  *      under the terms of the GNU General Public License as published by the 
19  *      Free Software Foundation; either version 2 of the License, or (at your 
20  *      option) any later version. See the GNU General Public License for more 
21  *      details at: http://www.mbedthis.com/downloads/gplLicense.html
22  *      
23  *      This program is distributed WITHOUT ANY WARRANTY; without even the 
24  *      implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
25  *      
26  *      This GPL license does NOT permit incorporating this software into 
27  *      proprietary programs. If you are unable to comply with the GPL, you must
28  *      acquire a commercial license to use this software. Commercial licenses 
29  *      for this software and support services are available from Mbedthis 
30  *      Software at http://www.mbedthis.com 
31  *      
32  *      @end
33  */
34
35 #include        "mpr.h"
36
37 #if BLD_FEATURE_MULTITHREAD
38 /************************************ Code ************************************/
39
40 void mprInitThreads(MprApp *app)
41 {
42         mprAssert(app);
43
44         if (app->globalLock == 0) {
45                 app->globalLock = mprCreateLock(app);
46                 app->allocLock = mprCreateLock(app);
47         }
48 }
49
50 /******************************************************************************/
51
52 void mprTermThreads(MprApp *app)
53 {
54         mprAssert(app);
55
56         if (app->globalLock) {
57                 mprDestroyLock(app->globalLock);
58                 app->globalLock = 0;
59         }
60         if (app->allocLock) {
61                 MprLock *lock = app->allocLock;
62                 app->allocLock = 0;
63                 mprDestroyLock(lock);
64         }
65 }
66
67 /******************************************************************************/
68
69 MprLock *mprCreateLock(MprCtx ctx)
70 {
71         MprLock *lock;
72
73         mprAssert(ctx);
74
75         lock = mprAllocType(ctx, MprLock);
76
77 #if BLD_HOST_UNIX
78         pthread_mutexattr_t     attr;
79
80         pthread_mutexattr_init(&attr);
81         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
82         pthread_mutex_init(&lock->cs, &attr);
83         pthread_mutexattr_destroy(&attr);
84 #elif WIN
85         InitializeCriticalSectionAndSpinCount(&lock->cs, 5000);
86 #elif VXWORKS
87         lock->cs = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | 
88                 SEM_INVERSION_SAFE);
89         if (lock->cs == 0) {
90                 mprAssert(0);
91                 mprFree(lock);
92                 return 0;
93         }
94 #endif
95         return lock;
96 }
97
98 /******************************************************************************/
99 /*
100  *      Destroy a lock. Must be locked on entrance.
101  */ 
102
103 void mprDestroyLock(MprLock *lock)
104 {
105         mprAssert(lock);
106         if (lock == 0) {
107                 return;
108         }
109
110 #if BLD_HOST_UNIX
111         pthread_mutex_unlock(&lock->cs);
112         pthread_mutex_destroy(&lock->cs);
113 #elif WIN
114         DeleteCriticalSection(&lock->cs);
115 #elif VXWORKS
116         semDelete(lock->cs);
117 #endif
118         mprFree(lock);
119 }
120
121 /******************************************************************************/
122 /*
123  *      Lock a mutex
124  */ 
125
126 void mprLock(MprLock *lock)
127 {
128         /*
129          *      OPT -- Do this just so we can allocate MprApp before we have created its
130          *      lock. Should remove this test here and in mprUnlock.
131          */
132         if (lock == 0) {
133                 return;
134         }
135
136 #if BLD_HOST_UNIX
137         pthread_mutex_lock(&lock->cs);
138 #elif WIN
139         EnterCriticalSection(&lock->cs);
140 #elif VXWORKS
141         semTake(lock->cs, WAIT_FOREVER);
142 #endif
143 }
144
145 /******************************************************************************/
146 /*
147  *      Try to attain a lock. Do not block!
148  */ 
149
150 int mprTryLock(MprLock *lock)
151 {
152         mprAssert(lock);
153
154 #if BLD_HOST_UNIX
155         {
156                 int             err;
157
158                 if ((err = pthread_mutex_trylock(&lock->cs)) != 0) {
159                         if (err == EBUSY) {
160                                 return MPR_ERR_BUSY;
161                         } else {
162                                 return MPR_ERR_CANT_ACCESS;
163                         }
164                 }
165                 return 0;
166         }
167 #elif WIN
168         if (TryEnterCriticalSection(&lock->cs) == 0) {
169                 return MPR_ERR_BUSY;
170         }
171 #elif VXWORKS
172         {
173                 int             rc;
174
175                 rc = semTake(cs, NO_WAIT);
176                 if (rc == -1) {
177                         mprAssert(0);
178                 }
179                 if (rc == S_objLib_OBJ_UNAVAILABLE) {
180                         return MPR_ERR_BUSY;
181                 } else {
182                         return MPR_ERR_CANT_ACCESS;
183                 }
184                 /* Success */
185                 return 0;
186         }
187 #endif
188         return 0;
189 }
190
191 /******************************************************************************/
192 /*
193  *      Unlock.
194  */ 
195
196 void mprUnlock(MprLock *lock)
197 {
198         if (lock == 0) {
199                 return;
200         }
201
202 #if BLD_HOST_UNIX
203         pthread_mutex_unlock(&lock->cs);
204 #elif WIN
205         LeaveCriticalSection(&lock->cs);
206 #elif VXWORKS
207         semGive(lock->cs);
208 #endif
209 }
210
211 /******************************************************************************/
212 /*
213  *      Big global lock. Avoid using this.
214  */
215
216 void mprGlobalLock(MprCtx ctx)
217 {
218         MprApp  *app;
219
220         app = mprGetApp(ctx);
221         mprAssert(app);
222
223         if (app && app->globalLock) {
224                 mprLock(app->globalLock);
225         }
226 }
227
228 /******************************************************************************/
229
230 void mprGlobalUnlock(MprCtx ctx)
231 {
232         MprApp  *app;
233
234         app = mprGetApp(ctx);
235         mprAssert(app);
236
237         if (app && app->globalLock) {
238                 mprUnlock(app->globalLock);
239         }
240 }
241
242 /******************************************************************************/
243
244 int mprGetCurrentThreadID()
245 {
246 #if BLD_HOST_UNIX
247         return (int) pthread_self();
248 #elif WIN
249         return GetCurrentThreadId();
250 #elif VXWORKS
251         return (int) pthread_self();
252 #endif
253 }
254
255 /******************************************************************************/
256 #endif /* BLD_FEATURE_MULTITHREAD */
257
258 /*
259  * Local variables:
260  * tab-width: 4
261  * c-basic-offset: 4
262  * End:
263  * vim:tw=78
264  * vim600: sw=4 ts=4 fdm=marker
265  * vim<600: sw=4 ts=4
266  */