LCOV - code coverage report
Current view: directory - js/jsd - jsd_lock.c (source / functions) Found Hit Coverage
Test: app.info Lines: 45 40 88.9 %
Date: 2012-06-02 Functions: 6 6 100.0 %

       1                 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : /*
      39                 :  * JavaScript Debugging support - Locking and threading support
      40                 :  */
      41                 : 
      42                 : /*                                                                           
      43                 : * ifdef JSD_USE_NSPR_LOCKS then you musat build and run against NSPR2.       
      44                 : * Otherwise, there are stubs that can be filled in with your own locking     
      45                 : * code. Also, note that these stubs include a jsd_CurrentThread()            
      46                 : * implementation that only works on Win32 - this is needed for the inprocess 
      47                 : * Java-based debugger.                                                       
      48                 : */                                                                           
      49                 : 
      50                 : #include "jsd.h"
      51                 : 
      52                 : #ifdef JSD_THREADSAFE
      53                 : 
      54                 : #ifdef JSD_USE_NSPR_LOCKS
      55                 : 
      56                 : #include "prlock.h"
      57                 : #include "prthread.h"
      58                 : 
      59                 : #ifdef JSD_ATTACH_THREAD_HACK
      60                 : #include "pprthred.h"   /* need this as long as JS_AttachThread is needed */
      61                 : #endif
      62                 : 
      63                 : struct JSDStaticLock
      64                 : {
      65                 :     void*     owner;
      66                 :     PRLock*   lock;
      67                 :     int       count;
      68                 : #ifdef DEBUG
      69                 :     uint16_t  sig;
      70                 : #endif
      71                 : };
      72                 : 
      73                 : /* 
      74                 :  * This exists to wrap non-NSPR theads (e.g. Java threads) in NSPR wrappers.
      75                 :  * XXX We ignore the memory leak issue.
      76                 :  * It is claimed that future versions of NSPR will automatically wrap on 
      77                 :  * the call to PR_GetCurrentThread.
      78                 :  *
      79                 :  * XXX We ignore the memory leak issue - i.e. we never call PR_DetachThread.
      80                 :  *
      81                 :  */
      82                 : #undef _CURRENT_THREAD
      83                 : #ifdef JSD_ATTACH_THREAD_HACK
      84                 : #define _CURRENT_THREAD(out)                                                  \
      85                 : JS_BEGIN_MACRO                                                                \
      86                 :     out = (void*) PR_GetCurrentThread();                                      \
      87                 :     if(!out)                                                                  \
      88                 :         out = (void*) JS_AttachThread(PR_USER_THREAD,PR_PRIORITY_NORMAL,NULL);\
      89                 :     JS_ASSERT(out);                                                           \
      90                 : JS_END_MACRO
      91                 : #else
      92                 : #define _CURRENT_THREAD(out)             \
      93                 : JS_BEGIN_MACRO                           \
      94                 :     out = (void*) PR_GetCurrentThread(); \
      95                 :     JS_ASSERT(out);                      \
      96                 : JS_END_MACRO
      97                 : #endif
      98                 : 
      99                 : #ifdef DEBUG
     100                 : #define JSD_LOCK_SIG 0x10CC10CC
     101        14381058 : void ASSERT_VALID_LOCK(JSDStaticLock* lock)
     102                 : {
     103        14381058 :     JS_ASSERT(lock);
     104        14381058 :     JS_ASSERT(lock->lock);
     105        14381058 :     JS_ASSERT(lock->count >= 0);
     106        14381058 :     JS_ASSERT(lock->sig == (uint16_t) JSD_LOCK_SIG);
     107        14381058 : }    
     108                 : #else
     109                 : #define ASSERT_VALID_LOCK(x) ((void)0)
     110                 : #endif
     111                 : 
     112                 : void*
     113            1680 : jsd_CreateLock()
     114                 : {
     115                 :     JSDStaticLock* lock;
     116                 : 
     117            3360 :     if( ! (lock = calloc(1, sizeof(JSDStaticLock))) || 
     118            1680 :         ! (lock->lock = PR_NewLock()) )
     119                 :     {
     120               0 :         if(lock)
     121                 :         {
     122               0 :             free(lock);
     123               0 :             lock = NULL;
     124                 :         }
     125                 :     }
     126                 : #ifdef DEBUG
     127            1680 :     if(lock) lock->sig = (uint16_t) JSD_LOCK_SIG;
     128                 : #endif
     129            1680 :     return lock;
     130                 : }    
     131                 : 
     132                 : void
     133         6794855 : jsd_Lock(JSDStaticLock* lock)
     134                 : {
     135                 :     void* me;
     136         6794855 :     ASSERT_VALID_LOCK(lock);
     137         6794855 :     _CURRENT_THREAD(me);
     138                 : 
     139         6794855 :     if(lock->owner == me)
     140                 :     {
     141          151653 :         lock->count++;
     142          151653 :         JS_ASSERT(lock->count > 1);
     143                 :     }
     144                 :     else
     145                 :     {
     146         6643202 :         PR_Lock(lock->lock);            /* this can block... */
     147         6643202 :         JS_ASSERT(lock->owner == 0);
     148         6643202 :         JS_ASSERT(lock->count == 0);
     149         6643202 :         lock->count = 1;
     150         6643202 :         lock->owner = me;
     151                 :     }
     152         6794855 : }    
     153                 : 
     154                 : void
     155         6794855 : jsd_Unlock(JSDStaticLock* lock)
     156                 : {
     157                 :     void* me;
     158         6794855 :     ASSERT_VALID_LOCK(lock);
     159         6794855 :     _CURRENT_THREAD(me);
     160                 : 
     161                 :     /* it's an error to unlock a lock you don't own */
     162         6794855 :     JS_ASSERT(lock->owner == me);
     163         6794855 :     if(lock->owner != me)
     164               0 :         return;
     165                 : 
     166         6794855 :     if(--lock->count == 0)
     167                 :     {
     168         6643202 :         lock->owner = NULL;
     169         6643202 :         PR_Unlock(lock->lock);
     170                 :     }
     171                 : }    
     172                 : 
     173                 : #ifdef DEBUG
     174                 : JSBool
     175          791348 : jsd_IsLocked(JSDStaticLock* lock)
     176                 : {
     177                 :     void* me;
     178          791348 :     ASSERT_VALID_LOCK(lock);
     179          791348 :     _CURRENT_THREAD(me);
     180          791348 :     if (lock->owner != me)
     181               0 :         return JS_FALSE;
     182          791348 :     JS_ASSERT(lock->count > 0);
     183          791348 :     return JS_TRUE;
     184                 : }    
     185                 : #endif /* DEBUG */
     186                 : 
     187                 : void*
     188              10 : jsd_CurrentThread()
     189                 : {
     190                 :     void* me;
     191              10 :     _CURRENT_THREAD(me);
     192              10 :     return me;
     193                 : }    
     194                 : 
     195                 : 
     196                 : #else  /* ! JSD_USE_NSPR_LOCKS */
     197                 : 
     198                 : #ifdef WIN32    
     199                 : #pragma message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
     200                 : #pragma message("!! you are compiling the stubbed version of jsd_lock.c !!")
     201                 : #pragma message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
     202                 : #endif
     203                 : 
     204                 : /*
     205                 :  * NOTE: 'Real' versions of these locks must be reentrant in the sense that 
     206                 :  * they support nested calls to lock and unlock. 
     207                 :  */
     208                 : 
     209                 : void*
     210                 : jsd_CreateLock()
     211                 : {
     212                 :     return (void*)1;
     213                 : }    
     214                 : 
     215                 : void
     216                 : jsd_Lock(void* lock)
     217                 : {
     218                 : }    
     219                 : 
     220                 : void
     221                 : jsd_Unlock(void* lock)
     222                 : {
     223                 : }    
     224                 : 
     225                 : #ifdef DEBUG
     226                 : JSBool
     227                 : jsd_IsLocked(void* lock)
     228                 : {
     229                 :     return JS_TRUE;
     230                 : }    
     231                 : #endif /* DEBUG */
     232                 : 
     233                 : /* 
     234                 :  * This Windows only thread id code is here to allow the Java-based 
     235                 :  * JSDebugger to work with the single threaded js.c shell (even without 
     236                 :  * real locking and threading support).
     237                 :  */
     238                 : 
     239                 : #ifdef WIN32    
     240                 : /* bogus (but good enough) declaration*/
     241                 : extern void* __stdcall GetCurrentThreadId(void);
     242                 : #endif
     243                 : 
     244                 : void*
     245                 : jsd_CurrentThread()
     246                 : {
     247                 : #ifdef WIN32    
     248                 :     return GetCurrentThreadId();
     249                 : #else
     250                 :     return (void*)1;
     251                 : #endif
     252                 : }    
     253                 : 
     254                 : #endif /* JSD_USE_NSPR_LOCKS */
     255                 : 
     256                 : #endif /* JSD_THREADSAFE */

Generated by: LCOV version 1.7