Annotation of embedaddon/sqlite3/src/mutex_w32.c, revision 1.1.1.1

1.1       misho       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 for win32
                     13: */
                     14: #include "sqliteInt.h"
                     15: 
                     16: /*
                     17: ** The code in this file is only used if we are compiling multithreaded
                     18: ** on a win32 system.
                     19: */
                     20: #ifdef SQLITE_MUTEX_W32
                     21: 
                     22: /*
                     23: ** Each recursive mutex is an instance of the following structure.
                     24: */
                     25: struct sqlite3_mutex {
                     26:   CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
                     27:   int id;                    /* Mutex type */
                     28: #ifdef SQLITE_DEBUG
                     29:   volatile int nRef;         /* Number of enterances */
                     30:   volatile DWORD owner;      /* Thread holding this mutex */
                     31:   int trace;                 /* True to trace changes */
                     32: #endif
                     33: };
                     34: #define SQLITE_W32_MUTEX_INITIALIZER { 0 }
                     35: #ifdef SQLITE_DEBUG
                     36: #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 }
                     37: #else
                     38: #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
                     39: #endif
                     40: 
                     41: /*
                     42: ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
                     43: ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
                     44: **
                     45: ** Here is an interesting observation:  Win95, Win98, and WinME lack
                     46: ** the LockFileEx() API.  But we can still statically link against that
                     47: ** API as long as we don't call it win running Win95/98/ME.  A call to
                     48: ** this routine is used to determine if the host is Win95/98/ME or
                     49: ** WinNT/2K/XP so that we will know whether or not we can safely call
                     50: ** the LockFileEx() API.
                     51: **
                     52: ** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
                     53: ** which is only available if your application was compiled with 
                     54: ** _WIN32_WINNT defined to a value >= 0x0400.  Currently, the only
                     55: ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef 
                     56: ** this out as well.
                     57: */
                     58: #if 0
                     59: #if SQLITE_OS_WINCE
                     60: # define mutexIsNT()  (1)
                     61: #else
                     62:   static int mutexIsNT(void){
                     63:     static int osType = 0;
                     64:     if( osType==0 ){
                     65:       OSVERSIONINFO sInfo;
                     66:       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
                     67:       GetVersionEx(&sInfo);
                     68:       osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
                     69:     }
                     70:     return osType==2;
                     71:   }
                     72: #endif /* SQLITE_OS_WINCE */
                     73: #endif
                     74: 
                     75: #ifdef SQLITE_DEBUG
                     76: /*
                     77: ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
                     78: ** intended for use only inside assert() statements.
                     79: */
                     80: static int winMutexHeld(sqlite3_mutex *p){
                     81:   return p->nRef!=0 && p->owner==GetCurrentThreadId();
                     82: }
                     83: static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
                     84:   return p->nRef==0 || p->owner!=tid;
                     85: }
                     86: static int winMutexNotheld(sqlite3_mutex *p){
                     87:   DWORD tid = GetCurrentThreadId(); 
                     88:   return winMutexNotheld2(p, tid);
                     89: }
                     90: #endif
                     91: 
                     92: 
                     93: /*
                     94: ** Initialize and deinitialize the mutex subsystem.
                     95: */
                     96: static sqlite3_mutex winMutex_staticMutexes[6] = {
                     97:   SQLITE3_MUTEX_INITIALIZER,
                     98:   SQLITE3_MUTEX_INITIALIZER,
                     99:   SQLITE3_MUTEX_INITIALIZER,
                    100:   SQLITE3_MUTEX_INITIALIZER,
                    101:   SQLITE3_MUTEX_INITIALIZER,
                    102:   SQLITE3_MUTEX_INITIALIZER
                    103: };
                    104: static int winMutex_isInit = 0;
                    105: /* As winMutexInit() and winMutexEnd() are called as part
                    106: ** of the sqlite3_initialize and sqlite3_shutdown()
                    107: ** processing, the "interlocked" magic is probably not
                    108: ** strictly necessary.
                    109: */
                    110: static long winMutex_lock = 0;
                    111: 
                    112: static int winMutexInit(void){ 
                    113:   /* The first to increment to 1 does actual initialization */
                    114:   if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
                    115:     int i;
                    116:     for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
                    117:       InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
                    118:     }
                    119:     winMutex_isInit = 1;
                    120:   }else{
                    121:     /* Someone else is in the process of initing the static mutexes */
                    122:     while( !winMutex_isInit ){
                    123:       Sleep(1);
                    124:     }
                    125:   }
                    126:   return SQLITE_OK; 
                    127: }
                    128: 
                    129: static int winMutexEnd(void){ 
                    130:   /* The first to decrement to 0 does actual shutdown 
                    131:   ** (which should be the last to shutdown.) */
                    132:   if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
                    133:     if( winMutex_isInit==1 ){
                    134:       int i;
                    135:       for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
                    136:         DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
                    137:       }
                    138:       winMutex_isInit = 0;
                    139:     }
                    140:   }
                    141:   return SQLITE_OK; 
                    142: }
                    143: 
                    144: /*
                    145: ** The sqlite3_mutex_alloc() routine allocates a new
                    146: ** mutex and returns a pointer to it.  If it returns NULL
                    147: ** that means that a mutex could not be allocated.  SQLite
                    148: ** will unwind its stack and return an error.  The argument
                    149: ** to sqlite3_mutex_alloc() is one of these integer constants:
                    150: **
                    151: ** <ul>
                    152: ** <li>  SQLITE_MUTEX_FAST
                    153: ** <li>  SQLITE_MUTEX_RECURSIVE
                    154: ** <li>  SQLITE_MUTEX_STATIC_MASTER
                    155: ** <li>  SQLITE_MUTEX_STATIC_MEM
                    156: ** <li>  SQLITE_MUTEX_STATIC_MEM2
                    157: ** <li>  SQLITE_MUTEX_STATIC_PRNG
                    158: ** <li>  SQLITE_MUTEX_STATIC_LRU
                    159: ** <li>  SQLITE_MUTEX_STATIC_PMEM
                    160: ** </ul>
                    161: **
                    162: ** The first two constants cause sqlite3_mutex_alloc() to create
                    163: ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
                    164: ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
                    165: ** The mutex implementation does not need to make a distinction
                    166: ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
                    167: ** not want to.  But SQLite will only request a recursive mutex in
                    168: ** cases where it really needs one.  If a faster non-recursive mutex
                    169: ** implementation is available on the host platform, the mutex subsystem
                    170: ** might return such a mutex in response to SQLITE_MUTEX_FAST.
                    171: **
                    172: ** The other allowed parameters to sqlite3_mutex_alloc() each return
                    173: ** a pointer to a static preexisting mutex.  Six static mutexes are
                    174: ** used by the current version of SQLite.  Future versions of SQLite
                    175: ** may add additional static mutexes.  Static mutexes are for internal
                    176: ** use by SQLite only.  Applications that use SQLite mutexes should
                    177: ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
                    178: ** SQLITE_MUTEX_RECURSIVE.
                    179: **
                    180: ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
                    181: ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
                    182: ** returns a different mutex on every call.  But for the static 
                    183: ** mutex types, the same mutex is returned on every call that has
                    184: ** the same type number.
                    185: */
                    186: static sqlite3_mutex *winMutexAlloc(int iType){
                    187:   sqlite3_mutex *p;
                    188: 
                    189:   switch( iType ){
                    190:     case SQLITE_MUTEX_FAST:
                    191:     case SQLITE_MUTEX_RECURSIVE: {
                    192:       p = sqlite3MallocZero( sizeof(*p) );
                    193:       if( p ){  
                    194: #ifdef SQLITE_DEBUG
                    195:         p->id = iType;
                    196: #endif
                    197:         InitializeCriticalSection(&p->mutex);
                    198:       }
                    199:       break;
                    200:     }
                    201:     default: {
                    202:       assert( winMutex_isInit==1 );
                    203:       assert( iType-2 >= 0 );
                    204:       assert( iType-2 < ArraySize(winMutex_staticMutexes) );
                    205:       p = &winMutex_staticMutexes[iType-2];
                    206: #ifdef SQLITE_DEBUG
                    207:       p->id = iType;
                    208: #endif
                    209:       break;
                    210:     }
                    211:   }
                    212:   return p;
                    213: }
                    214: 
                    215: 
                    216: /*
                    217: ** This routine deallocates a previously
                    218: ** allocated mutex.  SQLite is careful to deallocate every
                    219: ** mutex that it allocates.
                    220: */
                    221: static void winMutexFree(sqlite3_mutex *p){
                    222:   assert( p );
                    223:   assert( p->nRef==0 && p->owner==0 );
                    224:   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
                    225:   DeleteCriticalSection(&p->mutex);
                    226:   sqlite3_free(p);
                    227: }
                    228: 
                    229: /*
                    230: ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
                    231: ** to enter a mutex.  If another thread is already within the mutex,
                    232: ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
                    233: ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
                    234: ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
                    235: ** be entered multiple times by the same thread.  In such cases the,
                    236: ** mutex must be exited an equal number of times before another thread
                    237: ** can enter.  If the same thread tries to enter any other kind of mutex
                    238: ** more than once, the behavior is undefined.
                    239: */
                    240: static void winMutexEnter(sqlite3_mutex *p){
                    241: #ifdef SQLITE_DEBUG
                    242:   DWORD tid = GetCurrentThreadId(); 
                    243:   assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
                    244: #endif
                    245:   EnterCriticalSection(&p->mutex);
                    246: #ifdef SQLITE_DEBUG
                    247:   assert( p->nRef>0 || p->owner==0 );
                    248:   p->owner = tid; 
                    249:   p->nRef++;
                    250:   if( p->trace ){
                    251:     printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
                    252:   }
                    253: #endif
                    254: }
                    255: static int winMutexTry(sqlite3_mutex *p){
                    256: #ifndef NDEBUG
                    257:   DWORD tid = GetCurrentThreadId(); 
                    258: #endif
                    259:   int rc = SQLITE_BUSY;
                    260:   assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
                    261:   /*
                    262:   ** The sqlite3_mutex_try() routine is very rarely used, and when it
                    263:   ** is used it is merely an optimization.  So it is OK for it to always
                    264:   ** fail.  
                    265:   **
                    266:   ** The TryEnterCriticalSection() interface is only available on WinNT.
                    267:   ** And some windows compilers complain if you try to use it without
                    268:   ** first doing some #defines that prevent SQLite from building on Win98.
                    269:   ** For that reason, we will omit this optimization for now.  See
                    270:   ** ticket #2685.
                    271:   */
                    272: #if 0
                    273:   if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
                    274:     p->owner = tid;
                    275:     p->nRef++;
                    276:     rc = SQLITE_OK;
                    277:   }
                    278: #else
                    279:   UNUSED_PARAMETER(p);
                    280: #endif
                    281: #ifdef SQLITE_DEBUG
                    282:   if( rc==SQLITE_OK && p->trace ){
                    283:     printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
                    284:   }
                    285: #endif
                    286:   return rc;
                    287: }
                    288: 
                    289: /*
                    290: ** The sqlite3_mutex_leave() routine exits a mutex that was
                    291: ** previously entered by the same thread.  The behavior
                    292: ** is undefined if the mutex is not currently entered or
                    293: ** is not currently allocated.  SQLite will never do either.
                    294: */
                    295: static void winMutexLeave(sqlite3_mutex *p){
                    296: #ifndef NDEBUG
                    297:   DWORD tid = GetCurrentThreadId();
                    298:   assert( p->nRef>0 );
                    299:   assert( p->owner==tid );
                    300:   p->nRef--;
                    301:   if( p->nRef==0 ) p->owner = 0;
                    302:   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
                    303: #endif
                    304:   LeaveCriticalSection(&p->mutex);
                    305: #ifdef SQLITE_DEBUG
                    306:   if( p->trace ){
                    307:     printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
                    308:   }
                    309: #endif
                    310: }
                    311: 
                    312: sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
                    313:   static const sqlite3_mutex_methods sMutex = {
                    314:     winMutexInit,
                    315:     winMutexEnd,
                    316:     winMutexAlloc,
                    317:     winMutexFree,
                    318:     winMutexEnter,
                    319:     winMutexTry,
                    320:     winMutexLeave,
                    321: #ifdef SQLITE_DEBUG
                    322:     winMutexHeld,
                    323:     winMutexNotheld
                    324: #else
                    325:     0,
                    326:     0
                    327: #endif
                    328:   };
                    329: 
                    330:   return &sMutex;
                    331: }
                    332: #endif /* SQLITE_MUTEX_W32 */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>