js/jsd/jsd_lock.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /*
     8  * JavaScript Debugging support - Locking and threading support
     9  */
    11 /*                                                                           
    12 * ifdef JSD_USE_NSPR_LOCKS then you must build and run against NSPR2.       
    13 * Otherwise, there are stubs that can be filled in with your own locking     
    14 * code. Also, note that these stubs include a jsd_CurrentThread()            
    15 * implementation that only works on Win32 - this is needed for the inprocess 
    16 * Java-based debugger.                                                       
    17 */                                                                           
    19 #include "jsd.h"
    21 #include "js/Utility.h"
    23 #ifdef JSD_THREADSAFE
    25 #ifdef JSD_USE_NSPR_LOCKS
    27 #include "prlock.h"
    28 #include "prthread.h"
    30 #ifdef JSD_ATTACH_THREAD_HACK
    31 #include "pprthred.h"   /* need this as long as JS_AttachThread is needed */
    32 #endif
    34 struct JSDStaticLock
    35 {
    36     void*     owner;
    37     PRLock*   lock;
    38     int       count;
    39 #ifdef DEBUG
    40     uint16_t  sig;
    41 #endif
    42 };
    44 /* 
    45  * This exists to wrap non-NSPR theads (e.g. Java threads) in NSPR wrappers.
    46  * XXX We ignore the memory leak issue.
    47  * It is claimed that future versions of NSPR will automatically wrap on 
    48  * the call to PR_GetCurrentThread.
    49  *
    50  * XXX We ignore the memory leak issue - i.e. we never call PR_DetachThread.
    51  *
    52  */
    53 #undef _CURRENT_THREAD
    54 #ifdef JSD_ATTACH_THREAD_HACK
    55 #define _CURRENT_THREAD(out)                                                  \
    56 JS_BEGIN_MACRO                                                                \
    57     out = (void*) PR_GetCurrentThread();                                      \
    58     if(!out)                                                                  \
    59         out = (void*) JS_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL,     \
    60                                       nullptr);                               \
    61     MOZ_ASSERT(out);                                                          \
    62 JS_END_MACRO
    63 #else
    64 #define _CURRENT_THREAD(out)             \
    65 JS_BEGIN_MACRO                           \
    66     out = (void*) PR_GetCurrentThread(); \
    67     MOZ_ASSERT(out);                     \
    68 JS_END_MACRO
    69 #endif
    71 #ifdef DEBUG
    72 #define JSD_LOCK_SIG 0x10CC10CC
    73 void ASSERT_VALID_LOCK(JSDStaticLock* lock)
    74 {
    75     MOZ_ASSERT(lock);
    76     MOZ_ASSERT(lock->lock);
    77     MOZ_ASSERT(lock->count >= 0);
    78     MOZ_ASSERT(lock->sig == (uint16_t) JSD_LOCK_SIG);
    79 }    
    80 #else
    81 #define ASSERT_VALID_LOCK(x) ((void)0)
    82 #endif
    84 JSDStaticLock*
    85 jsd_CreateLock()
    86 {
    87     JSDStaticLock* lock;
    89     if( ! (lock = js_pod_calloc<JSDStaticLock>()) ||
    90         ! (lock->lock = PR_NewLock()) )
    91     {
    92         if(lock)
    93         {
    94             free(lock);
    95             lock = nullptr;
    96         }
    97     }
    98 #ifdef DEBUG
    99     if(lock) lock->sig = (uint16_t) JSD_LOCK_SIG;
   100 #endif
   101     return lock;
   102 }    
   104 void
   105 jsd_Lock(JSDStaticLock* lock)
   106 {
   107     void* me;
   108     ASSERT_VALID_LOCK(lock);
   109     _CURRENT_THREAD(me);
   111     if(lock->owner == me)
   112     {
   113         lock->count++;
   114         MOZ_ASSERT(lock->count > 1);
   115     }
   116     else
   117     {
   118         PR_Lock(lock->lock);            /* this can block... */
   119         MOZ_ASSERT(lock->owner == 0);
   120         MOZ_ASSERT(lock->count == 0);
   121         lock->count = 1;
   122         lock->owner = me;
   123     }
   124 }    
   126 void
   127 jsd_Unlock(JSDStaticLock* lock)
   128 {
   129     void* me;
   130     ASSERT_VALID_LOCK(lock);
   131     _CURRENT_THREAD(me);
   133     /* it's an error to unlock a lock you don't own */
   134     MOZ_ASSERT(lock->owner == me);
   135     if(lock->owner != me)
   136         return;
   138     if(--lock->count == 0)
   139     {
   140         lock->owner = nullptr;
   141         PR_Unlock(lock->lock);
   142     }
   143 }    
   145 #ifdef DEBUG
   146 bool
   147 jsd_IsLocked(JSDStaticLock* lock)
   148 {
   149     void* me;
   150     ASSERT_VALID_LOCK(lock);
   151     _CURRENT_THREAD(me);
   152     if (lock->owner != me)
   153         return false;
   154     MOZ_ASSERT(lock->count > 0);
   155     return true;
   156 }    
   157 #endif /* DEBUG */
   159 void*
   160 jsd_CurrentThread()
   161 {
   162     void* me;
   163     _CURRENT_THREAD(me);
   164     return me;
   165 }    
   168 #else  /* ! JSD_USE_NSPR_LOCKS */
   170 #ifdef WIN32    
   171 #pragma message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
   172 #pragma message("!! you are compiling the stubbed version of jsd_lock.c !!")
   173 #pragma message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
   174 #endif
   176 /*
   177  * NOTE: 'Real' versions of these locks must be reentrant in the sense that 
   178  * they support nested calls to lock and unlock. 
   179  */
   181 void*
   182 jsd_CreateLock()
   183 {
   184     return (void*)1;
   185 }    
   187 void
   188 jsd_Lock(void* lock)
   189 {
   190 }    
   192 void
   193 jsd_Unlock(void* lock)
   194 {
   195 }    
   197 #ifdef DEBUG
   198 bool
   199 jsd_IsLocked(void* lock)
   200 {
   201     return true;
   202 }    
   203 #endif /* DEBUG */
   205 /* 
   206  * This Windows only thread id code is here to allow the Java-based 
   207  * JSDebugger to work with the single threaded js.c shell (even without 
   208  * real locking and threading support).
   209  */
   211 #ifdef WIN32    
   212 /* bogus (but good enough) declaration*/
   213 extern void* __stdcall GetCurrentThreadId(void);
   214 #endif
   216 void*
   217 jsd_CurrentThread()
   218 {
   219 #ifdef WIN32    
   220     return GetCurrentThreadId();
   221 #else
   222     return (void*)1;
   223 #endif
   224 }    
   226 #endif /* JSD_USE_NSPR_LOCKS */
   228 #endif /* JSD_THREADSAFE */

mercurial