engine/sqlite/src/mutex.cpp
changeset 2 29cda98b007e
equal deleted inserted replaced
1:5f8e5adbbed9 2:29cda98b007e
       
     1 /*
       
     2 ** 2007 August 14
       
     3 **
       
     4 ** The author disclaims copyright to this source code.  In place of
       
     5 ** a legal notice, here is a blessing:
       
     6 **
       
     7 **    May you do good and not evil.
       
     8 **    May you find forgiveness for yourself and forgive others.
       
     9 **    May you share freely, never taking more than you give.
       
    10 **
       
    11 *************************************************************************
       
    12 ** This file contains the C functions that implement mutexes.
       
    13 **
       
    14 ** The implementation in this file does not provide any mutual
       
    15 ** exclusion and is thus suitable for use only in applications
       
    16 ** that use SQLite in a single thread.  But this implementation
       
    17 ** does do a lot of error checking on mutexes to make sure they
       
    18 ** are called correctly and at appropriate times.  Hence, this
       
    19 ** implementation is suitable for testing.
       
    20 ** debugging purposes
       
    21 **
       
    22 ** $Id: mutex.cpp 1282 2008-11-13 09:31:33Z LarsPson $
       
    23 */
       
    24 #include "sqliteInt.h"
       
    25 
       
    26 #ifdef SQLITE_MUTEX_NOOP_DEBUG
       
    27 /*
       
    28 ** In this implementation, mutexes do not provide any mutual exclusion.
       
    29 ** But the error checking is provided.  This implementation is useful
       
    30 ** for test purposes.
       
    31 */
       
    32 
       
    33 /*
       
    34 ** The mutex object
       
    35 */
       
    36 struct sqlite3_mutex {
       
    37   int id;     /* The mutex type */
       
    38   int cnt;    /* Number of entries without a matching leave */
       
    39 };
       
    40 
       
    41 /*
       
    42 ** The sqlite3_mutex_alloc() routine allocates a new
       
    43 ** mutex and returns a pointer to it.  If it returns NULL
       
    44 ** that means that a mutex could not be allocated. 
       
    45 */
       
    46 sqlite3_mutex *sqlite3_mutex_alloc(int id){
       
    47   static sqlite3_mutex aStatic[5];
       
    48   sqlite3_mutex *pNew = 0;
       
    49   switch( id ){
       
    50     case SQLITE_MUTEX_FAST:
       
    51     case SQLITE_MUTEX_RECURSIVE: {
       
    52       pNew = sqlite3_malloc(sizeof(*pNew));
       
    53       if( pNew ){
       
    54         pNew->id = id;
       
    55         pNew->cnt = 0;
       
    56       }
       
    57       break;
       
    58     }
       
    59     default: {
       
    60       assert( id-2 >= 0 );
       
    61       assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
       
    62       pNew = &aStatic[id-2];
       
    63       pNew->id = id;
       
    64       break;
       
    65     }
       
    66   }
       
    67   return pNew;
       
    68 }
       
    69 
       
    70 /*
       
    71 ** This routine deallocates a previously allocated mutex.
       
    72 */
       
    73 void sqlite3_mutex_free(sqlite3_mutex *p){
       
    74   assert( p );
       
    75   assert( p->cnt==0 );
       
    76   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
       
    77   sqlite3_free(p);
       
    78 }
       
    79 
       
    80 /*
       
    81 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
       
    82 ** to enter a mutex.  If another thread is already within the mutex,
       
    83 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
       
    84 ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
       
    85 ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
       
    86 ** be entered multiple times by the same thread.  In such cases the,
       
    87 ** mutex must be exited an equal number of times before another thread
       
    88 ** can enter.  If the same thread tries to enter any other kind of mutex
       
    89 ** more than once, the behavior is undefined.
       
    90 */
       
    91 void sqlite3_mutex_enter(sqlite3_mutex *p){
       
    92   assert( p );
       
    93   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
       
    94   p->cnt++;
       
    95 }
       
    96 int sqlite3_mutex_try(sqlite3_mutex *p){
       
    97   assert( p );
       
    98   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
       
    99   p->cnt++;
       
   100   return SQLITE_OK;
       
   101 }
       
   102 
       
   103 /*
       
   104 ** The sqlite3_mutex_leave() routine exits a mutex that was
       
   105 ** previously entered by the same thread.  The behavior
       
   106 ** is undefined if the mutex is not currently entered or
       
   107 ** is not currently allocated.  SQLite will never do either.
       
   108 */
       
   109 void sqlite3_mutex_leave(sqlite3_mutex *p){
       
   110   assert( p );
       
   111   assert( sqlite3_mutex_held(p) );
       
   112   p->cnt--;
       
   113   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
       
   114 }
       
   115 
       
   116 /*
       
   117 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
       
   118 ** intended for use inside assert() statements.
       
   119 */
       
   120 int sqlite3_mutex_held(sqlite3_mutex *p){
       
   121   return p==0 || p->cnt>0;
       
   122 }
       
   123 int sqlite3_mutex_notheld(sqlite3_mutex *p){
       
   124   return p==0 || p->cnt==0;
       
   125 }
       
   126 #endif /* SQLITE_MUTEX_NOOP_DEBUG */