|
|
1.1 ! root 1: /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- ! 2: * ! 3: * The contents of this file are subject to the Netscape Public ! 4: * License Version 1.1 (the "License"); you may not use this file ! 5: * except in compliance with the License. You may obtain a copy of ! 6: * the License at http://www.mozilla.org/NPL/ ! 7: * ! 8: * Software distributed under the License is distributed on an "AS ! 9: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ! 10: * implied. See the License for the specific language governing ! 11: * rights and limitations under the License. ! 12: * ! 13: * The Original Code is Mozilla Communicator client code, released ! 14: * March 31, 1998. ! 15: * ! 16: * The Initial Developer of the Original Code is Netscape ! 17: * Communications Corporation. Portions created by Netscape are ! 18: * Copyright (C) 1998 Netscape Communications Corporation. All ! 19: * Rights Reserved. ! 20: * ! 21: * Contributor(s): ! 22: * ! 23: * Alternatively, the contents of this file may be used under the ! 24: * terms of the GNU Public License (the "GPL"), in which case the ! 25: * provisions of the GPL are applicable instead of those above. ! 26: * If you wish to allow use of your version of this file only ! 27: * under the terms of the GPL and not to allow others to use your ! 28: * version of this file under the NPL, indicate your decision by ! 29: * deleting the provisions above and replace them with the notice ! 30: * and other provisions required by the GPL. If you do not delete ! 31: * the provisions above, a recipient may use your version of this ! 32: * file under either the NPL or the GPL. ! 33: */ ! 34: #ifndef jslock_h__ ! 35: #define jslock_h__ ! 36: ! 37: #ifdef JS_THREADSAFE ! 38: ! 39: #include "jstypes.h" ! 40: #include "pratom.h" ! 41: #include "prlock.h" ! 42: #include "prcvar.h" ! 43: ! 44: #include "jsprvtd.h" /* for JSScope, etc. */ ! 45: #include "jspubtd.h" /* for JSRuntime, etc. */ ! 46: ! 47: #define Thin_GetWait(W) ((jsword)(W) & 0x1) ! 48: #define Thin_SetWait(W) ((jsword)(W) | 0x1) ! 49: #define Thin_RemoveWait(W) ((jsword)(W) & ~0x1) ! 50: ! 51: typedef struct JSFatLock JSFatLock; ! 52: ! 53: struct JSFatLock { ! 54: int susp; ! 55: PRLock *slock; ! 56: PRCondVar *svar; ! 57: JSFatLock *next; ! 58: JSFatLock **prevp; ! 59: }; ! 60: ! 61: typedef struct JSThinLock { ! 62: jsword owner; ! 63: JSFatLock *fat; ! 64: } JSThinLock; ! 65: ! 66: typedef PRLock JSLock; ! 67: ! 68: typedef struct JSFatLockTable { ! 69: JSFatLock *free; ! 70: JSFatLock *taken; ! 71: } JSFatLockTable; ! 72: ! 73: /* ! 74: * Atomic increment and decrement for a reference counter, given jsrefcount *p. ! 75: * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work. ! 76: */ ! 77: #define JS_ATOMIC_INCREMENT(p) PR_AtomicIncrement((PRInt32 *)(p)) ! 78: #define JS_ATOMIC_DECREMENT(p) PR_AtomicDecrement((PRInt32 *)(p)) ! 79: ! 80: #define CurrentThreadId() (jsword)PR_GetCurrentThread() ! 81: #define JS_CurrentThreadId() js_CurrentThreadId() ! 82: #define JS_NEW_LOCK() PR_NewLock() ! 83: #define JS_DESTROY_LOCK(l) PR_DestroyLock(l) ! 84: #define JS_ACQUIRE_LOCK(l) PR_Lock(l) ! 85: #define JS_RELEASE_LOCK(l) PR_Unlock(l) ! 86: #define JS_LOCK0(P,M) js_Lock(P,M) ! 87: #define JS_UNLOCK0(P,M) js_Unlock(P,M) ! 88: ! 89: #define JS_NEW_CONDVAR(l) PR_NewCondVar(l) ! 90: #define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv) ! 91: #define JS_WAIT_CONDVAR(cv,to) PR_WaitCondVar(cv,to) ! 92: #define JS_NO_TIMEOUT PR_INTERVAL_NO_TIMEOUT ! 93: #define JS_NOTIFY_CONDVAR(cv) PR_NotifyCondVar(cv) ! 94: #define JS_NOTIFY_ALL_CONDVAR(cv) PR_NotifyAllCondVar(cv) ! 95: ! 96: /* ! 97: * Include jsscope.h so JS_LOCK_OBJ macro callers don't have to include it. ! 98: * Since there is a JSThinLock member in JSScope, we can't nest this include ! 99: * much earlier (see JSThinLock's typedef, above). Yes, that means there is ! 100: * an #include cycle between jslock.h and jsscope.h: moderate-sized XXX here, ! 101: * to be fixed by moving JS_LOCK_SCOPE to jsscope.h, JS_LOCK_OBJ to jsobj.h, ! 102: * and so on. ! 103: * ! 104: * We also need jsscope.h #ifdef DEBUG for SET_OBJ_INFO and SET_SCOPE_INFO, ! 105: * but we do not want any nested includes that depend on DEBUG. Those lead ! 106: * to build bustage when someone makes a change that depends in a subtle way ! 107: * on jsscope.h being included directly or indirectly, but does not test by ! 108: * building optimized as well as DEBUG. ! 109: */ ! 110: #include "jsscope.h" ! 111: ! 112: #ifdef DEBUG ! 113: ! 114: #define SET_OBJ_INFO(obj_,file_,line_) \ ! 115: SET_SCOPE_INFO(OBJ_SCOPE(obj_),file_,line_) ! 116: ! 117: #define SET_SCOPE_INFO(scope_,file_,line_) \ ! 118: ((scope_)->ownercx ? (void)0 : \ ! 119: (JS_ASSERT((scope_)->u.count > 0 && (scope_)->u.count <= 4), \ ! 120: (void)((scope_)->file[(scope_)->u.count-1] = (file_), \ ! 121: (scope_)->line[(scope_)->u.count-1] = (line_)))) ! 122: #endif /* DEBUG */ ! 123: ! 124: #define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt) ! 125: #define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt) ! 126: ! 127: /* ! 128: * NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objects ! 129: * (objects for which OBJ_IS_NATIVE returns true). All uses of these macros in ! 130: * the engine are predicated on OBJ_IS_NATIVE or equivalent checks. These uses ! 131: * are for optimizations above the JSObjectOps layer, under which object locks ! 132: * normally hide. ! 133: */ ! 134: #define JS_LOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) \ ! 135: ? (void)0 \ ! 136: : (js_LockObj(cx, obj), \ ! 137: SET_OBJ_INFO(obj,__FILE__,__LINE__))) ! 138: #define JS_UNLOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) \ ! 139: ? (void)0 : js_UnlockObj(cx, obj)) ! 140: ! 141: #define JS_LOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 : \ ! 142: (js_LockScope(cx, scope), \ ! 143: SET_SCOPE_INFO(scope,__FILE__,__LINE__))) ! 144: #define JS_UNLOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 : \ ! 145: js_UnlockScope(cx, scope)) ! 146: #define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope) \ ! 147: js_TransferScopeLock(cx, scope, newscope) ! 148: ! 149: extern jsword js_CurrentThreadId(); ! 150: extern void js_LockRuntime(JSRuntime *rt); ! 151: extern void js_UnlockRuntime(JSRuntime *rt); ! 152: extern void js_LockObj(JSContext *cx, JSObject *obj); ! 153: extern void js_UnlockObj(JSContext *cx, JSObject *obj); ! 154: extern void js_LockScope(JSContext *cx, JSScope *scope); ! 155: extern void js_UnlockScope(JSContext *cx, JSScope *scope); ! 156: extern int js_SetupLocks(int,int); ! 157: extern void js_CleanupLocks(); ! 158: extern void js_InitContextForLocking(JSContext *); ! 159: extern void js_TransferScopeLock(JSContext *, JSScope *, JSScope *); ! 160: extern JS_FRIEND_API(jsval) ! 161: js_GetSlotThreadSafe(JSContext *, JSObject *, uint32); ! 162: extern void js_SetSlotThreadSafe(JSContext *, JSObject *, uint32, jsval); ! 163: extern void js_InitLock(JSThinLock *); ! 164: extern void js_FinishLock(JSThinLock *); ! 165: extern void js_FinishSharingScope(JSRuntime *rt, JSScope *scope); ! 166: ! 167: #ifdef DEBUG ! 168: ! 169: #define JS_IS_RUNTIME_LOCKED(rt) js_IsRuntimeLocked(rt) ! 170: #define JS_IS_OBJ_LOCKED(obj) js_IsObjLocked(obj) ! 171: #define JS_IS_SCOPE_LOCKED(scope) js_IsScopeLocked(scope) ! 172: ! 173: extern JSBool js_IsRuntimeLocked(JSRuntime *rt); ! 174: extern JSBool js_IsObjLocked(JSObject *obj); ! 175: extern JSBool js_IsScopeLocked(JSScope *scope); ! 176: ! 177: #else ! 178: ! 179: #define JS_IS_RUNTIME_LOCKED(rt) 0 ! 180: #define JS_IS_OBJ_LOCKED(obj) 1 ! 181: #define JS_IS_SCOPE_LOCKED(scope) 1 ! 182: ! 183: #endif /* DEBUG */ ! 184: ! 185: #define JS_LOCK_OBJ_VOID(cx, obj, e) \ ! 186: JS_BEGIN_MACRO \ ! 187: JS_LOCK_OBJ(cx, obj); \ ! 188: e; \ ! 189: JS_UNLOCK_OBJ(cx, obj); \ ! 190: JS_END_MACRO ! 191: ! 192: #define JS_LOCK_VOID(cx, e) \ ! 193: JS_BEGIN_MACRO \ ! 194: JSRuntime *_rt = (cx)->runtime; \ ! 195: JS_LOCK_RUNTIME_VOID(_rt, e); \ ! 196: JS_END_MACRO ! 197: ! 198: #if defined(JS_USE_ONLY_NSPR_LOCKS) || \ ! 199: !( (defined(_WIN32) && defined(_M_IX86)) || \ ! 200: (defined(__GNUC__) && defined(__i386__)) || \ ! 201: (defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) || \ ! 202: defined(AIX) ) ! 203: ! 204: #define NSPR_LOCK 1 ! 205: ! 206: #undef JS_LOCK0 ! 207: #undef JS_UNLOCK0 ! 208: #define JS_LOCK0(P,M) (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M)) ! 209: #define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat))) ! 210: ! 211: #else /* arch-tests */ ! 212: ! 213: #undef NSPR_LOCK ! 214: ! 215: extern JS_INLINE void js_Lock(JSThinLock *tl, jsword me); ! 216: extern JS_INLINE void js_Unlock(JSThinLock *tl, jsword me); ! 217: ! 218: #endif /* arch-tests */ ! 219: ! 220: #else /* !JS_THREADSAFE */ ! 221: ! 222: #define JS_ATOMIC_INCREMENT(p) (++*(p)) ! 223: #define JS_ATOMIC_DECREMENT(p) (--*(p)) ! 224: ! 225: #define JS_CurrentThreadId() 0 ! 226: #define JS_NEW_LOCK() NULL ! 227: #define JS_DESTROY_LOCK(l) ((void)0) ! 228: #define JS_ACQUIRE_LOCK(l) ((void)0) ! 229: #define JS_RELEASE_LOCK(l) ((void)0) ! 230: #define JS_LOCK0(P,M) ((void)0) ! 231: #define JS_UNLOCK0(P,M) ((void)0) ! 232: ! 233: #define JS_NEW_CONDVAR(l) NULL ! 234: #define JS_DESTROY_CONDVAR(cv) ((void)0) ! 235: #define JS_WAIT_CONDVAR(cv,to) ((void)0) ! 236: #define JS_NOTIFY_CONDVAR(cv) ((void)0) ! 237: #define JS_NOTIFY_ALL_CONDVAR(cv) ((void)0) ! 238: ! 239: #define JS_LOCK_RUNTIME(rt) ((void)0) ! 240: #define JS_UNLOCK_RUNTIME(rt) ((void)0) ! 241: #define JS_LOCK_OBJ(cx,obj) ((void)0) ! 242: #define JS_UNLOCK_OBJ(cx,obj) ((void)0) ! 243: #define JS_LOCK_OBJ_VOID(cx,obj,e) (e) ! 244: #define JS_LOCK_SCOPE(cx,scope) ((void)0) ! 245: #define JS_UNLOCK_SCOPE(cx,scope) ((void)0) ! 246: #define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0) ! 247: ! 248: #define JS_IS_RUNTIME_LOCKED(rt) 1 ! 249: #define JS_IS_OBJ_LOCKED(obj) 1 ! 250: #define JS_IS_SCOPE_LOCKED(scope) 1 ! 251: #define JS_LOCK_VOID(cx, e) JS_LOCK_RUNTIME_VOID((cx)->runtime, e) ! 252: ! 253: #endif /* !JS_THREADSAFE */ ! 254: ! 255: #define JS_LOCK_RUNTIME_VOID(rt,e) \ ! 256: JS_BEGIN_MACRO \ ! 257: JS_LOCK_RUNTIME(rt); \ ! 258: e; \ ! 259: JS_UNLOCK_RUNTIME(rt); \ ! 260: JS_END_MACRO ! 261: ! 262: #define JS_LOCK_GC(rt) JS_ACQUIRE_LOCK((rt)->gcLock) ! 263: #define JS_UNLOCK_GC(rt) JS_RELEASE_LOCK((rt)->gcLock) ! 264: #define JS_LOCK_GC_VOID(rt,e) (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt)) ! 265: #define JS_AWAIT_GC_DONE(rt) JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT) ! 266: #define JS_NOTIFY_GC_DONE(rt) JS_NOTIFY_ALL_CONDVAR((rt)->gcDone) ! 267: #define JS_AWAIT_REQUEST_DONE(rt) JS_WAIT_CONDVAR((rt)->requestDone, \ ! 268: JS_NO_TIMEOUT) ! 269: #define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone) ! 270: ! 271: #define JS_LOCK(P,CX) JS_LOCK0(P,(CX)->thread) ! 272: #define JS_UNLOCK(P,CX) JS_UNLOCK0(P,(CX)->thread) ! 273: ! 274: #ifndef SET_OBJ_INFO ! 275: #define SET_OBJ_INFO(obj,f,l) ((void)0) ! 276: #endif ! 277: #ifndef SET_SCOPE_INFO ! 278: #define SET_SCOPE_INFO(scope,f,l) ((void)0) ! 279: #endif ! 280: ! 281: #endif /* jslock_h___ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.