modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/mutex_w32.c (about)

     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  #if SQLITE_OS_WIN
    17  /*
    18  ** Include code that is common to all os_*.c files
    19  */
    20  #include "os_common.h"
    21  
    22  /*
    23  ** Include the header file for the Windows VFS.
    24  */
    25  #include "os_win.h"
    26  #endif
    27  
    28  /*
    29  ** The code in this file is only used if we are compiling multithreaded
    30  ** on a Win32 system.
    31  */
    32  #ifdef SQLITE_MUTEX_W32
    33  
    34  /*
    35  ** Each recursive mutex is an instance of the following structure.
    36  */
    37  struct sqlite3_mutex {
    38    CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
    39    int id;                    /* Mutex type */
    40  #ifdef SQLITE_DEBUG
    41    volatile int nRef;         /* Number of enterances */
    42    volatile DWORD owner;      /* Thread holding this mutex */
    43    volatile int trace;        /* True to trace changes */
    44  #endif
    45  };
    46  
    47  /*
    48  ** These are the initializer values used when declaring a "static" mutex
    49  ** on Win32.  It should be noted that all mutexes require initialization
    50  ** on the Win32 platform.
    51  */
    52  #define SQLITE_W32_MUTEX_INITIALIZER { 0 }
    53  
    54  #ifdef SQLITE_DEBUG
    55  #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
    56                                      0L, (DWORD)0, 0 }
    57  #else
    58  #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
    59  #endif
    60  
    61  #ifdef SQLITE_DEBUG
    62  /*
    63  ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
    64  ** intended for use only inside assert() statements.
    65  */
    66  static int winMutexHeld(sqlite3_mutex *p){
    67    return p->nRef!=0 && p->owner==GetCurrentThreadId();
    68  }
    69  
    70  static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
    71    return p->nRef==0 || p->owner!=tid;
    72  }
    73  
    74  static int winMutexNotheld(sqlite3_mutex *p){
    75    DWORD tid = GetCurrentThreadId();
    76    return winMutexNotheld2(p, tid);
    77  }
    78  #endif
    79  
    80  /*
    81  ** Try to provide a memory barrier operation, needed for initialization
    82  ** and also for the xShmBarrier method of the VFS in cases when SQLite is
    83  ** compiled without mutexes (SQLITE_THREADSAFE=0).
    84  */
    85  void sqlite3MemoryBarrier(void){
    86  #if defined(SQLITE_MEMORY_BARRIER)
    87    SQLITE_MEMORY_BARRIER;
    88  #elif defined(__GNUC__)
    89    __sync_synchronize();
    90  #elif MSVC_VERSION>=1300
    91    _ReadWriteBarrier();
    92  #elif defined(MemoryBarrier)
    93    MemoryBarrier();
    94  #endif
    95  }
    96  
    97  /*
    98  ** Initialize and deinitialize the mutex subsystem.
    99  */
   100  static sqlite3_mutex winMutex_staticMutexes[] = {
   101    SQLITE3_MUTEX_INITIALIZER,
   102    SQLITE3_MUTEX_INITIALIZER,
   103    SQLITE3_MUTEX_INITIALIZER,
   104    SQLITE3_MUTEX_INITIALIZER,
   105    SQLITE3_MUTEX_INITIALIZER,
   106    SQLITE3_MUTEX_INITIALIZER,
   107    SQLITE3_MUTEX_INITIALIZER,
   108    SQLITE3_MUTEX_INITIALIZER,
   109    SQLITE3_MUTEX_INITIALIZER,
   110    SQLITE3_MUTEX_INITIALIZER,
   111    SQLITE3_MUTEX_INITIALIZER,
   112    SQLITE3_MUTEX_INITIALIZER
   113  };
   114  
   115  static int winMutex_isInit = 0;
   116  static int winMutex_isNt = -1; /* <0 means "need to query" */
   117  
   118  /* As the winMutexInit() and winMutexEnd() functions are called as part
   119  ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
   120  ** "interlocked" magic used here is probably not strictly necessary.
   121  */
   122  static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
   123  
   124  int sqlite3_win32_is_nt(void); /* os_win.c */
   125  void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
   126  
   127  static int winMutexInit(void){
   128    /* The first to increment to 1 does actual initialization */
   129    if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
   130      int i;
   131      for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
   132  #if SQLITE_OS_WINRT
   133        InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
   134  #else
   135        InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
   136  #endif
   137      }
   138      winMutex_isInit = 1;
   139    }else{
   140      /* Another thread is (in the process of) initializing the static
   141      ** mutexes */
   142      while( !winMutex_isInit ){
   143        sqlite3_win32_sleep(1);
   144      }
   145    }
   146    return SQLITE_OK;
   147  }
   148  
   149  static int winMutexEnd(void){
   150    /* The first to decrement to 0 does actual shutdown
   151    ** (which should be the last to shutdown.) */
   152    if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
   153      if( winMutex_isInit==1 ){
   154        int i;
   155        for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
   156          DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
   157        }
   158        winMutex_isInit = 0;
   159      }
   160    }
   161    return SQLITE_OK;
   162  }
   163  
   164  /*
   165  ** The sqlite3_mutex_alloc() routine allocates a new
   166  ** mutex and returns a pointer to it.  If it returns NULL
   167  ** that means that a mutex could not be allocated.  SQLite
   168  ** will unwind its stack and return an error.  The argument
   169  ** to sqlite3_mutex_alloc() is one of these integer constants:
   170  **
   171  ** <ul>
   172  ** <li>  SQLITE_MUTEX_FAST
   173  ** <li>  SQLITE_MUTEX_RECURSIVE
   174  ** <li>  SQLITE_MUTEX_STATIC_MASTER
   175  ** <li>  SQLITE_MUTEX_STATIC_MEM
   176  ** <li>  SQLITE_MUTEX_STATIC_OPEN
   177  ** <li>  SQLITE_MUTEX_STATIC_PRNG
   178  ** <li>  SQLITE_MUTEX_STATIC_LRU
   179  ** <li>  SQLITE_MUTEX_STATIC_PMEM
   180  ** <li>  SQLITE_MUTEX_STATIC_APP1
   181  ** <li>  SQLITE_MUTEX_STATIC_APP2
   182  ** <li>  SQLITE_MUTEX_STATIC_APP3
   183  ** <li>  SQLITE_MUTEX_STATIC_VFS1
   184  ** <li>  SQLITE_MUTEX_STATIC_VFS2
   185  ** <li>  SQLITE_MUTEX_STATIC_VFS3
   186  ** </ul>
   187  **
   188  ** The first two constants cause sqlite3_mutex_alloc() to create
   189  ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
   190  ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
   191  ** The mutex implementation does not need to make a distinction
   192  ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
   193  ** not want to.  But SQLite will only request a recursive mutex in
   194  ** cases where it really needs one.  If a faster non-recursive mutex
   195  ** implementation is available on the host platform, the mutex subsystem
   196  ** might return such a mutex in response to SQLITE_MUTEX_FAST.
   197  **
   198  ** The other allowed parameters to sqlite3_mutex_alloc() each return
   199  ** a pointer to a static preexisting mutex.  Six static mutexes are
   200  ** used by the current version of SQLite.  Future versions of SQLite
   201  ** may add additional static mutexes.  Static mutexes are for internal
   202  ** use by SQLite only.  Applications that use SQLite mutexes should
   203  ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
   204  ** SQLITE_MUTEX_RECURSIVE.
   205  **
   206  ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
   207  ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
   208  ** returns a different mutex on every call.  But for the static
   209  ** mutex types, the same mutex is returned on every call that has
   210  ** the same type number.
   211  */
   212  static sqlite3_mutex *winMutexAlloc(int iType){
   213    sqlite3_mutex *p;
   214  
   215    switch( iType ){
   216      case SQLITE_MUTEX_FAST:
   217      case SQLITE_MUTEX_RECURSIVE: {
   218        p = sqlite3MallocZero( sizeof(*p) );
   219        if( p ){
   220          p->id = iType;
   221  #ifdef SQLITE_DEBUG
   222  #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
   223          p->trace = 1;
   224  #endif
   225  #endif
   226  #if SQLITE_OS_WINRT
   227          InitializeCriticalSectionEx(&p->mutex, 0, 0);
   228  #else
   229          InitializeCriticalSection(&p->mutex);
   230  #endif
   231        }
   232        break;
   233      }
   234      default: {
   235  #ifdef SQLITE_ENABLE_API_ARMOR
   236        if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
   237          (void)SQLITE_MISUSE_BKPT;
   238          return 0;
   239        }
   240  #endif
   241        p = &winMutex_staticMutexes[iType-2];
   242        p->id = iType;
   243  #ifdef SQLITE_DEBUG
   244  #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
   245        p->trace = 1;
   246  #endif
   247  #endif
   248        break;
   249      }
   250    }
   251    return p;
   252  }
   253  
   254  
   255  /*
   256  ** This routine deallocates a previously
   257  ** allocated mutex.  SQLite is careful to deallocate every
   258  ** mutex that it allocates.
   259  */
   260  static void winMutexFree(sqlite3_mutex *p){
   261    assert( p );
   262    assert( p->nRef==0 && p->owner==0 );
   263    if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
   264      DeleteCriticalSection(&p->mutex);
   265      sqlite3_free(p);
   266    }else{
   267  #ifdef SQLITE_ENABLE_API_ARMOR
   268      (void)SQLITE_MISUSE_BKPT;
   269  #endif
   270    }
   271  }
   272  
   273  /*
   274  ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
   275  ** to enter a mutex.  If another thread is already within the mutex,
   276  ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
   277  ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
   278  ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
   279  ** be entered multiple times by the same thread.  In such cases the,
   280  ** mutex must be exited an equal number of times before another thread
   281  ** can enter.  If the same thread tries to enter any other kind of mutex
   282  ** more than once, the behavior is undefined.
   283  */
   284  static void winMutexEnter(sqlite3_mutex *p){
   285  #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   286    DWORD tid = GetCurrentThreadId();
   287  #endif
   288  #ifdef SQLITE_DEBUG
   289    assert( p );
   290    assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
   291  #else
   292    assert( p );
   293  #endif
   294    assert( winMutex_isInit==1 );
   295    EnterCriticalSection(&p->mutex);
   296  #ifdef SQLITE_DEBUG
   297    assert( p->nRef>0 || p->owner==0 );
   298    p->owner = tid;
   299    p->nRef++;
   300    if( p->trace ){
   301      OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
   302               tid, p->id, p, p->trace, p->nRef));
   303    }
   304  #endif
   305  }
   306  
   307  static int winMutexTry(sqlite3_mutex *p){
   308  #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   309    DWORD tid = GetCurrentThreadId();
   310  #endif
   311    int rc = SQLITE_BUSY;
   312    assert( p );
   313    assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
   314    /*
   315    ** The sqlite3_mutex_try() routine is very rarely used, and when it
   316    ** is used it is merely an optimization.  So it is OK for it to always
   317    ** fail.
   318    **
   319    ** The TryEnterCriticalSection() interface is only available on WinNT.
   320    ** And some windows compilers complain if you try to use it without
   321    ** first doing some #defines that prevent SQLite from building on Win98.
   322    ** For that reason, we will omit this optimization for now.  See
   323    ** ticket #2685.
   324    */
   325  #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400
   326    assert( winMutex_isInit==1 );
   327    assert( winMutex_isNt>=-1 && winMutex_isNt<=1 );
   328    if( winMutex_isNt<0 ){
   329      winMutex_isNt = sqlite3_win32_is_nt();
   330    }
   331    assert( winMutex_isNt==0 || winMutex_isNt==1 );
   332    if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){
   333  #ifdef SQLITE_DEBUG
   334      p->owner = tid;
   335      p->nRef++;
   336  #endif
   337      rc = SQLITE_OK;
   338    }
   339  #else
   340    UNUSED_PARAMETER(p);
   341  #endif
   342  #ifdef SQLITE_DEBUG
   343    if( p->trace ){
   344      OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
   345               tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
   346    }
   347  #endif
   348    return rc;
   349  }
   350  
   351  /*
   352  ** The sqlite3_mutex_leave() routine exits a mutex that was
   353  ** previously entered by the same thread.  The behavior
   354  ** is undefined if the mutex is not currently entered or
   355  ** is not currently allocated.  SQLite will never do either.
   356  */
   357  static void winMutexLeave(sqlite3_mutex *p){
   358  #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   359    DWORD tid = GetCurrentThreadId();
   360  #endif
   361    assert( p );
   362  #ifdef SQLITE_DEBUG
   363    assert( p->nRef>0 );
   364    assert( p->owner==tid );
   365    p->nRef--;
   366    if( p->nRef==0 ) p->owner = 0;
   367    assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
   368  #endif
   369    assert( winMutex_isInit==1 );
   370    LeaveCriticalSection(&p->mutex);
   371  #ifdef SQLITE_DEBUG
   372    if( p->trace ){
   373      OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
   374               tid, p->id, p, p->trace, p->nRef));
   375    }
   376  #endif
   377  }
   378  
   379  sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
   380    static const sqlite3_mutex_methods sMutex = {
   381      winMutexInit,
   382      winMutexEnd,
   383      winMutexAlloc,
   384      winMutexFree,
   385      winMutexEnter,
   386      winMutexTry,
   387      winMutexLeave,
   388  #ifdef SQLITE_DEBUG
   389      winMutexHeld,
   390      winMutexNotheld
   391  #else
   392      0,
   393      0
   394  #endif
   395    };
   396    return &sMutex;
   397  }
   398  
   399  #endif /* SQLITE_MUTEX_W32 */