| 2 |      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 */
 |