extensions/sqlite/sqlite-source/mutex.c
author Matt Woodrow <pred@alliedmods.net>
Mon Aug 17 10:53:54 2009 +1200 (2009-08-17)
changeset 2771 ea849fc91a9b
parent 1645 27307df4d711
permissions -rw-r--r--
Forgot makefiles patch
     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$
    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 */