PageRenderTime 27ms CodeModel.GetById 12ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/jslock.h

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
C++ Header | 311 lines | 200 code | 56 blank | 55 comment | 17 complexity | 45c16fe39fd2b6888e0c5c9f690d8eb4 MD5 | raw file
  1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2 *
  3 * ***** BEGIN LICENSE BLOCK *****
  4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5 *
  6 * The contents of this file are subject to the Mozilla Public License Version
  7 * 1.1 (the "License"); you may not use this file except in compliance with
  8 * the License. You may obtain a copy of the License at
  9 * http://www.mozilla.org/MPL/
 10 *
 11 * Software distributed under the License is distributed on an "AS IS" basis,
 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 13 * for the specific language governing rights and limitations under the
 14 * License.
 15 *
 16 * The Original Code is Mozilla Communicator client code, released
 17 * March 31, 1998.
 18 *
 19 * The Initial Developer of the Original Code is
 20 * Netscape Communications Corporation.
 21 * Portions created by the Initial Developer are Copyright (C) 1998
 22 * the Initial Developer. All Rights Reserved.
 23 *
 24 * Contributor(s):
 25 *
 26 * Alternatively, the contents of this file may be used under the terms of
 27 * either of the GNU General Public License Version 2 or later (the "GPL"),
 28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 29 * in which case the provisions of the GPL or the LGPL are applicable instead
 30 * of those above. If you wish to allow use of your version of this file only
 31 * under the terms of either the GPL or the LGPL, and not to allow others to
 32 * use your version of this file under the terms of the MPL, indicate your
 33 * decision by deleting the provisions above and replace them with the notice
 34 * and other provisions required by the GPL or the LGPL. If you do not delete
 35 * the provisions above, a recipient may use your version of this file under
 36 * the terms of any one of the MPL, the GPL or the LGPL.
 37 *
 38 * ***** END LICENSE BLOCK ***** */
 39#ifndef jslock_h__
 40#define jslock_h__
 41
 42#include "jstypes.h"
 43#include "jsprvtd.h"    /* for JSScope, etc. */
 44#include "jspubtd.h"    /* for JSRuntime, etc. */
 45
 46#ifdef JS_THREADSAFE
 47# include "pratom.h"
 48# include "prlock.h"
 49# include "prcvar.h"
 50# include "prthread.h"
 51#endif
 52
 53JS_BEGIN_EXTERN_C
 54
 55#ifdef JS_THREADSAFE
 56
 57#if (defined(_WIN32) && defined(_M_IX86)) ||                                  \
 58    (defined(__GNUC__) && defined(__i386__)) ||                               \
 59    (defined(__GNUC__) && defined(__x86_64__)) ||                             \
 60    (defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) ||           \
 61    defined(AIX) ||                                                           \
 62    defined(USE_ARM_KUSER)
 63# define JS_HAS_NATIVE_COMPARE_AND_SWAP 1
 64#else
 65# define JS_HAS_NATIVE_COMPARE_AND_SWAP 0
 66#endif
 67
 68#if defined(JS_USE_ONLY_NSPR_LOCKS) || !JS_HAS_NATIVE_COMPARE_AND_SWAP
 69# define NSPR_LOCK 1
 70#else
 71# undef NSPR_LOCK
 72#endif
 73
 74#define Thin_GetWait(W) ((jsword)(W) & 0x1)
 75#define Thin_SetWait(W) ((jsword)(W) | 0x1)
 76#define Thin_RemoveWait(W) ((jsword)(W) & ~0x1)
 77
 78typedef struct JSFatLock JSFatLock;
 79
 80typedef struct JSThinLock {
 81    jsword      owner;
 82    JSFatLock   *fat;
 83} JSThinLock;
 84
 85#define CX_THINLOCK_ID(cx)       ((jsword)(cx)->thread)
 86#define CURRENT_THREAD_IS_ME(me) (((JSThread *)me)->id == js_CurrentThreadId())
 87
 88typedef PRLock JSLock;
 89
 90typedef struct JSTitle JSTitle;
 91
 92struct JSTitle {
 93    JSContext       *ownercx;           /* creating context, NULL if shared */
 94    JSThinLock      lock;               /* binary semaphore protecting title */
 95    union {                             /* union lockful and lock-free state: */
 96        jsrefcount  count;              /* lock entry count for reentrancy */
 97        JSTitle     *link;              /* next link in rt->titleSharingTodo */
 98    } u;
 99#ifdef JS_DEBUG_TITLE_LOCKS
100    const char      *file[4];           /* file where lock was (re-)taken */
101    unsigned int    line[4];            /* line where lock was (re-)taken */
102#endif
103};
104
105/*
106 * Title structures must be immediately preceded by JSObjectMap structures for
107 * maps that use titles for threadsafety.  This is enforced by assertion in
108 * jsscope.h; see bug 408416 for future remedies to this somewhat fragile
109 * architecture.
110 */
111
112#define TITLE_TO_MAP(title)                                                   \
113    ((JSObjectMap *)((char *)(title) - sizeof(JSObjectMap)))
114
115/*
116 * Atomic increment and decrement for a reference counter, given jsrefcount *p.
117 * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work.
118 */
119#define JS_ATOMIC_INCREMENT(p)      PR_AtomicIncrement((PRInt32 *)(p))
120#define JS_ATOMIC_DECREMENT(p)      PR_AtomicDecrement((PRInt32 *)(p))
121#define JS_ATOMIC_ADD(p,v)          PR_AtomicAdd((PRInt32 *)(p), (PRInt32)(v))
122
123#define js_CurrentThreadId()        (jsword)PR_GetCurrentThread()
124#define JS_NEW_LOCK()               PR_NewLock()
125#define JS_DESTROY_LOCK(l)          PR_DestroyLock(l)
126#define JS_ACQUIRE_LOCK(l)          PR_Lock(l)
127#define JS_RELEASE_LOCK(l)          PR_Unlock(l)
128
129#define JS_NEW_CONDVAR(l)           PR_NewCondVar(l)
130#define JS_DESTROY_CONDVAR(cv)      PR_DestroyCondVar(cv)
131#define JS_WAIT_CONDVAR(cv,to)      PR_WaitCondVar(cv,to)
132#define JS_NO_TIMEOUT               PR_INTERVAL_NO_TIMEOUT
133#define JS_NOTIFY_CONDVAR(cv)       PR_NotifyCondVar(cv)
134#define JS_NOTIFY_ALL_CONDVAR(cv)   PR_NotifyAllCondVar(cv)
135
136#ifdef JS_DEBUG_TITLE_LOCKS
137
138#define SET_OBJ_INFO(obj_, file_, line_)                                       \
139    SET_SCOPE_INFO(OBJ_SCOPE(obj_), file_, line_)
140
141#define SET_SCOPE_INFO(scope_, file_, line_)                                   \
142    js_SetScopeInfo(scope_, file_, line_)
143
144#endif
145
146#define JS_LOCK(cx, tl)             js_Lock(cx, tl)
147#define JS_UNLOCK(cx, tl)           js_Unlock(cx, tl)
148
149#define JS_LOCK_RUNTIME(rt)         js_LockRuntime(rt)
150#define JS_UNLOCK_RUNTIME(rt)       js_UnlockRuntime(rt)
151
152/*
153 * NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objects
154 * (objects for which OBJ_IS_NATIVE returns true).  All uses of these macros in
155 * the engine are predicated on OBJ_IS_NATIVE or equivalent checks.  These uses
156 * are for optimizations above the JSObjectOps layer, under which object locks
157 * normally hide.
158 */
159#define JS_LOCK_OBJ(cx,obj)       ((OBJ_SCOPE(obj)->title.ownercx == (cx))     \
160                                   ? (void)0                                   \
161                                   : (js_LockObj(cx, obj),                     \
162                                      SET_OBJ_INFO(obj,__FILE__,__LINE__)))
163#define JS_UNLOCK_OBJ(cx,obj)     ((OBJ_SCOPE(obj)->title.ownercx == (cx))     \
164                                   ? (void)0 : js_UnlockObj(cx, obj))
165
166#define JS_LOCK_TITLE(cx,title)                                                \
167    ((title)->ownercx == (cx) ? (void)0                                        \
168     : (js_LockTitle(cx, (title)),                                             \
169        SET_TITLE_INFO(title,__FILE__,__LINE__)))
170
171#define JS_UNLOCK_TITLE(cx,title) ((title)->ownercx == (cx) ? (void)0          \
172                                   : js_UnlockTitle(cx, title))
173
174#define JS_LOCK_SCOPE(cx,scope)   JS_LOCK_TITLE(cx,&(scope)->title)
175#define JS_UNLOCK_SCOPE(cx,scope) JS_UNLOCK_TITLE(cx,&(scope)->title)
176
177#define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope)                            \
178    js_TransferTitle(cx, &scope->title, &newscope->title)
179
180
181extern void js_Lock(JSContext *cx, JSThinLock *tl);
182extern void js_Unlock(JSContext *cx, JSThinLock *tl);
183extern void js_LockRuntime(JSRuntime *rt);
184extern void js_UnlockRuntime(JSRuntime *rt);
185extern void js_LockObj(JSContext *cx, JSObject *obj);
186extern void js_UnlockObj(JSContext *cx, JSObject *obj);
187extern void js_InitTitle(JSContext *cx, JSTitle *title);
188extern void js_FinishTitle(JSContext *cx, JSTitle *title);
189extern void js_LockTitle(JSContext *cx, JSTitle *title);
190extern void js_UnlockTitle(JSContext *cx, JSTitle *title);
191extern int js_SetupLocks(int,int);
192extern void js_CleanupLocks();
193extern void js_TransferTitle(JSContext *, JSTitle *, JSTitle *);
194extern JS_FRIEND_API(jsval)
195js_GetSlotThreadSafe(JSContext *, JSObject *, uint32);
196extern void js_SetSlotThreadSafe(JSContext *, JSObject *, uint32, jsval);
197extern void js_InitLock(JSThinLock *);
198extern void js_FinishLock(JSThinLock *);
199extern void js_FinishSharingTitle(JSContext *cx, JSTitle *title);
200
201#ifdef DEBUG
202
203#define JS_IS_RUNTIME_LOCKED(rt)        js_IsRuntimeLocked(rt)
204#define JS_IS_OBJ_LOCKED(cx,obj)        js_IsObjLocked(cx,obj)
205#define JS_IS_TITLE_LOCKED(cx,title)    js_IsTitleLocked(cx,title)
206
207extern JSBool js_IsRuntimeLocked(JSRuntime *rt);
208extern JSBool js_IsObjLocked(JSContext *cx, JSObject *obj);
209extern JSBool js_IsTitleLocked(JSContext *cx, JSTitle *title);
210#ifdef JS_DEBUG_TITLE_LOCKS
211extern void js_SetScopeInfo(JSScope *scope, const char *file, int line);
212#endif
213
214#else
215
216#define JS_IS_RUNTIME_LOCKED(rt)        0
217#define JS_IS_OBJ_LOCKED(cx,obj)        1
218#define JS_IS_TITLE_LOCKED(cx,title)    1
219
220#endif /* DEBUG */
221
222#define JS_LOCK_OBJ_VOID(cx, obj, e)                                          \
223    JS_BEGIN_MACRO                                                            \
224        JS_LOCK_OBJ(cx, obj);                                                 \
225        e;                                                                    \
226        JS_UNLOCK_OBJ(cx, obj);                                               \
227    JS_END_MACRO
228
229#define JS_LOCK_VOID(cx, e)                                                   \
230    JS_BEGIN_MACRO                                                            \
231        JSRuntime *_rt = (cx)->runtime;                                       \
232        JS_LOCK_RUNTIME_VOID(_rt, e);                                         \
233    JS_END_MACRO
234
235#else  /* !JS_THREADSAFE */
236
237#define JS_ATOMIC_INCREMENT(p)      (++*(p))
238#define JS_ATOMIC_DECREMENT(p)      (--*(p))
239#define JS_ATOMIC_ADD(p,v)          (*(p) += (v))
240
241#define JS_CurrentThreadId() 0
242#define JS_NEW_LOCK()               NULL
243#define JS_DESTROY_LOCK(l)          ((void)0)
244#define JS_ACQUIRE_LOCK(l)          ((void)0)
245#define JS_RELEASE_LOCK(l)          ((void)0)
246#define JS_LOCK(cx, tl)             ((void)0)
247#define JS_UNLOCK(cx, tl)           ((void)0)
248
249#define JS_NEW_CONDVAR(l)           NULL
250#define JS_DESTROY_CONDVAR(cv)      ((void)0)
251#define JS_WAIT_CONDVAR(cv,to)      ((void)0)
252#define JS_NOTIFY_CONDVAR(cv)       ((void)0)
253#define JS_NOTIFY_ALL_CONDVAR(cv)   ((void)0)
254
255#define JS_LOCK_RUNTIME(rt)         ((void)0)
256#define JS_UNLOCK_RUNTIME(rt)       ((void)0)
257#define JS_LOCK_OBJ(cx,obj)         ((void)0)
258#define JS_UNLOCK_OBJ(cx,obj)       ((void)0)
259#define JS_LOCK_OBJ_VOID(cx,obj,e)  (e)
260#define JS_LOCK_SCOPE(cx,scope)     ((void)0)
261#define JS_UNLOCK_SCOPE(cx,scope)   ((void)0)
262#define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0)
263
264#define JS_IS_RUNTIME_LOCKED(rt)        1
265#define JS_IS_OBJ_LOCKED(cx,obj)        1
266#define JS_IS_TITLE_LOCKED(cx,title)    1
267#define JS_LOCK_VOID(cx, e)             JS_LOCK_RUNTIME_VOID((cx)->runtime, e)
268
269#endif /* !JS_THREADSAFE */
270
271#define JS_LOCK_RUNTIME_VOID(rt,e)                                            \
272    JS_BEGIN_MACRO                                                            \
273        JS_LOCK_RUNTIME(rt);                                                  \
274        e;                                                                    \
275        JS_UNLOCK_RUNTIME(rt);                                                \
276    JS_END_MACRO
277
278#define JS_LOCK_GC(rt)              JS_ACQUIRE_LOCK((rt)->gcLock)
279#define JS_UNLOCK_GC(rt)            JS_RELEASE_LOCK((rt)->gcLock)
280#define JS_LOCK_GC_VOID(rt,e)       (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt))
281#define JS_AWAIT_GC_DONE(rt)        JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT)
282#define JS_NOTIFY_GC_DONE(rt)       JS_NOTIFY_ALL_CONDVAR((rt)->gcDone)
283#define JS_AWAIT_REQUEST_DONE(rt)   JS_WAIT_CONDVAR((rt)->requestDone,        \
284                                                    JS_NO_TIMEOUT)
285#define JS_NOTIFY_REQUEST_DONE(rt)  JS_NOTIFY_CONDVAR((rt)->requestDone)
286
287#ifndef SET_OBJ_INFO
288#define SET_OBJ_INFO(obj,f,l)       ((void)0)
289#endif
290#ifndef SET_TITLE_INFO
291#define SET_TITLE_INFO(title,f,l)   ((void)0)
292#endif
293
294#ifdef JS_THREADSAFE
295
296extern JSBool
297js_CompareAndSwap(jsword *w, jsword ov, jsword nv);
298
299#else
300
301static inline JSBool
302js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
303{
304    return (*w == ov) ? *w = nv, JS_TRUE : JS_FALSE;
305}
306
307#endif
308
309JS_END_EXTERN_C
310
311#endif /* jslock_h___ */