drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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 | ************************************************************************* |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 12 | ** This file contains the C functions that implement mutexes for Win32. |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 13 | */ |
| 14 | #include "sqliteInt.h" |
| 15 | |
mistachkin | 0f71054 | 2014-05-12 15:37:03 +0000 | [diff] [blame] | 16 | #if SQLITE_OS_WIN |
| 17 | /* |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 18 | ** Include code that is common to all os_*.c files |
| 19 | */ |
| 20 | #include "os_common.h" |
| 21 | |
| 22 | /* |
mistachkin | 0f71054 | 2014-05-12 15:37:03 +0000 | [diff] [blame] | 23 | ** Include the header file for the Windows VFS. |
| 24 | */ |
| 25 | #include "os_win.h" |
| 26 | #endif |
| 27 | |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 28 | /* |
| 29 | ** The code in this file is only used if we are compiling multithreaded |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 30 | ** on a Win32 system. |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 31 | */ |
drh | c7ce76a | 2007-08-30 14:10:30 +0000 | [diff] [blame] | 32 | #ifdef SQLITE_MUTEX_W32 |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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 */ |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 40 | #ifdef SQLITE_DEBUG |
drh | 72339a3 | 2010-05-13 20:19:17 +0000 | [diff] [blame] | 41 | volatile int nRef; /* Number of enterances */ |
| 42 | volatile DWORD owner; /* Thread holding this mutex */ |
mistachkin | 091881b | 2018-02-18 00:54:06 +0000 | [diff] [blame] | 43 | volatile LONG trace; /* True to trace changes */ |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 44 | #endif |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 45 | }; |
drh | a418980 | 2008-06-19 16:07:07 +0000 | [diff] [blame] | 46 | |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 47 | /* |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 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. |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 51 | */ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 52 | #define SQLITE_W32_MUTEX_INITIALIZER { 0 } |
| 53 | |
| 54 | #ifdef SQLITE_DEBUG |
mistachkin | 091881b | 2018-02-18 00:54:06 +0000 | [diff] [blame] | 55 | #define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 56 | 0L, (DWORD)0, 0 } |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 57 | #else |
mistachkin | 091881b | 2018-02-18 00:54:06 +0000 | [diff] [blame] | 58 | #define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id } |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 59 | #endif |
| 60 | |
drh | a418980 | 2008-06-19 16:07:07 +0000 | [diff] [blame] | 61 | #ifdef SQLITE_DEBUG |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 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 | } |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 69 | |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 70 | static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 71 | return p->nRef==0 || p->owner!=tid; |
| 72 | } |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 73 | |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 74 | static int winMutexNotheld(sqlite3_mutex *p){ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 75 | DWORD tid = GetCurrentThreadId(); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 76 | return winMutexNotheld2(p, tid); |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 77 | } |
drh | a418980 | 2008-06-19 16:07:07 +0000 | [diff] [blame] | 78 | #endif |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 79 | |
drh | df6a81c | 2007-09-05 14:30:42 +0000 | [diff] [blame] | 80 | /* |
drh | 539482b | 2015-09-26 03:23:29 +0000 | [diff] [blame] | 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). |
drh | 6081c1d | 2015-09-06 02:51:04 +0000 | [diff] [blame] | 84 | */ |
| 85 | void sqlite3MemoryBarrier(void){ |
drh | 2d64034 | 2015-09-06 10:31:37 +0000 | [diff] [blame] | 86 | #if defined(SQLITE_MEMORY_BARRIER) |
| 87 | SQLITE_MEMORY_BARRIER; |
| 88 | #elif defined(__GNUC__) |
| 89 | __sync_synchronize(); |
drh | 30a5831 | 2017-02-13 13:26:33 +0000 | [diff] [blame] | 90 | #elif MSVC_VERSION>=1300 |
mistachkin | 8d9837a | 2015-10-06 01:44:53 +0000 | [diff] [blame] | 91 | _ReadWriteBarrier(); |
| 92 | #elif defined(MemoryBarrier) |
drh | 6081c1d | 2015-09-06 02:51:04 +0000 | [diff] [blame] | 93 | MemoryBarrier(); |
drh | 2d64034 | 2015-09-06 10:31:37 +0000 | [diff] [blame] | 94 | #endif |
drh | 6081c1d | 2015-09-06 02:51:04 +0000 | [diff] [blame] | 95 | } |
| 96 | |
| 97 | /* |
drh | 40257ff | 2008-06-13 18:24:27 +0000 | [diff] [blame] | 98 | ** Initialize and deinitialize the mutex subsystem. |
| 99 | */ |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 100 | static sqlite3_mutex winMutex_staticMutexes[] = { |
mistachkin | 091881b | 2018-02-18 00:54:06 +0000 | [diff] [blame] | 101 | SQLITE3_MUTEX_INITIALIZER(2), |
| 102 | SQLITE3_MUTEX_INITIALIZER(3), |
| 103 | SQLITE3_MUTEX_INITIALIZER(4), |
| 104 | SQLITE3_MUTEX_INITIALIZER(5), |
| 105 | SQLITE3_MUTEX_INITIALIZER(6), |
| 106 | SQLITE3_MUTEX_INITIALIZER(7), |
| 107 | SQLITE3_MUTEX_INITIALIZER(8), |
| 108 | SQLITE3_MUTEX_INITIALIZER(9), |
| 109 | SQLITE3_MUTEX_INITIALIZER(10), |
| 110 | SQLITE3_MUTEX_INITIALIZER(11), |
| 111 | SQLITE3_MUTEX_INITIALIZER(12), |
| 112 | SQLITE3_MUTEX_INITIALIZER(13) |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 113 | }; |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 114 | |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 115 | static int winMutex_isInit = 0; |
mistachkin | 202cb64 | 2014-07-31 18:54:01 +0000 | [diff] [blame] | 116 | static int winMutex_isNt = -1; /* <0 means "need to query" */ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 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. |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 121 | */ |
mistachkin | ce64d61 | 2014-08-14 18:31:56 +0000 | [diff] [blame] | 122 | static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 123 | |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 124 | int sqlite3_win32_is_nt(void); /* os_win.c */ |
mistachkin | 9721c21 | 2012-06-18 17:15:29 +0000 | [diff] [blame] | 125 | void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 126 | |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 127 | static int winMutexInit(void){ |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 128 | /* The first to increment to 1 does actual initialization */ |
shane | 1987c8d | 2009-08-10 03:23:21 +0000 | [diff] [blame] | 129 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 130 | int i; |
drh | 9ac0650 | 2009-08-17 13:42:29 +0000 | [diff] [blame] | 131 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
drh | cf3d7a4 | 2012-03-01 20:05:41 +0000 | [diff] [blame] | 132 | #if SQLITE_OS_WINRT |
| 133 | InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0); |
| 134 | #else |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 135 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
drh | cf3d7a4 | 2012-03-01 20:05:41 +0000 | [diff] [blame] | 136 | #endif |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 137 | } |
| 138 | winMutex_isInit = 1; |
| 139 | }else{ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 140 | /* Another thread is (in the process of) initializing the static |
| 141 | ** mutexes */ |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 142 | while( !winMutex_isInit ){ |
mistachkin | f4f327c | 2012-03-13 03:35:07 +0000 | [diff] [blame] | 143 | sqlite3_win32_sleep(1); |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 144 | } |
| 145 | } |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 146 | return SQLITE_OK; |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 147 | } |
| 148 | |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 149 | static int winMutexEnd(void){ |
| 150 | /* The first to decrement to 0 does actual shutdown |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 151 | ** (which should be the last to shutdown.) */ |
shane | 1987c8d | 2009-08-10 03:23:21 +0000 | [diff] [blame] | 152 | if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 153 | if( winMutex_isInit==1 ){ |
| 154 | int i; |
drh | 9ac0650 | 2009-08-17 13:42:29 +0000 | [diff] [blame] | 155 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 156 | DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 157 | } |
| 158 | winMutex_isInit = 0; |
| 159 | } |
| 160 | } |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 161 | return SQLITE_OK; |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 162 | } |
drh | 40257ff | 2008-06-13 18:24:27 +0000 | [diff] [blame] | 163 | |
| 164 | /* |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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> |
shane | 7c7c311 | 2009-08-17 15:31:23 +0000 | [diff] [blame] | 172 | ** <li> SQLITE_MUTEX_FAST |
| 173 | ** <li> SQLITE_MUTEX_RECURSIVE |
| 174 | ** <li> SQLITE_MUTEX_STATIC_MASTER |
| 175 | ** <li> SQLITE_MUTEX_STATIC_MEM |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 176 | ** <li> SQLITE_MUTEX_STATIC_OPEN |
shane | 7c7c311 | 2009-08-17 15:31:23 +0000 | [diff] [blame] | 177 | ** <li> SQLITE_MUTEX_STATIC_PRNG |
| 178 | ** <li> SQLITE_MUTEX_STATIC_LRU |
dan | 6d4fb83 | 2011-01-26 07:25:32 +0000 | [diff] [blame] | 179 | ** <li> SQLITE_MUTEX_STATIC_PMEM |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 180 | ** <li> SQLITE_MUTEX_STATIC_APP1 |
| 181 | ** <li> SQLITE_MUTEX_STATIC_APP2 |
| 182 | ** <li> SQLITE_MUTEX_STATIC_APP3 |
mistachkin | 93de653 | 2015-07-03 21:38:09 +0000 | [diff] [blame] | 183 | ** <li> SQLITE_MUTEX_STATIC_VFS1 |
| 184 | ** <li> SQLITE_MUTEX_STATIC_VFS2 |
| 185 | ** <li> SQLITE_MUTEX_STATIC_VFS3 |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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 |
shane | 7c7c311 | 2009-08-17 15:31:23 +0000 | [diff] [blame] | 199 | ** a pointer to a static preexisting mutex. Six static mutexes are |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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() |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 208 | ** returns a different mutex on every call. But for the static |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 209 | ** mutex types, the same mutex is returned on every call that has |
| 210 | ** the same type number. |
| 211 | */ |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 212 | static sqlite3_mutex *winMutexAlloc(int iType){ |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 213 | sqlite3_mutex *p; |
| 214 | |
| 215 | switch( iType ){ |
| 216 | case SQLITE_MUTEX_FAST: |
| 217 | case SQLITE_MUTEX_RECURSIVE: { |
| 218 | p = sqlite3MallocZero( sizeof(*p) ); |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 219 | if( p ){ |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 220 | p->id = iType; |
drh | cbb3f33 | 2015-02-25 14:25:31 +0000 | [diff] [blame] | 221 | #ifdef SQLITE_DEBUG |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 222 | #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC |
| 223 | p->trace = 1; |
| 224 | #endif |
drh | 72339a3 | 2010-05-13 20:19:17 +0000 | [diff] [blame] | 225 | #endif |
mistachkin | df562d5 | 2012-03-13 01:16:57 +0000 | [diff] [blame] | 226 | #if SQLITE_OS_WINRT |
| 227 | InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 228 | #else |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 229 | InitializeCriticalSection(&p->mutex); |
mistachkin | df562d5 | 2012-03-13 01:16:57 +0000 | [diff] [blame] | 230 | #endif |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 231 | } |
| 232 | break; |
| 233 | } |
| 234 | default: { |
mistachkin | cd54bab | 2014-12-20 21:14:14 +0000 | [diff] [blame] | 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 |
shane | 61b82d6 | 2009-06-01 17:06:07 +0000 | [diff] [blame] | 241 | p = &winMutex_staticMutexes[iType-2]; |
drh | cbb3f33 | 2015-02-25 14:25:31 +0000 | [diff] [blame] | 242 | #ifdef SQLITE_DEBUG |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 243 | #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC |
mistachkin | 091881b | 2018-02-18 00:54:06 +0000 | [diff] [blame] | 244 | InterlockedCompareExchange(&p->trace, 1, 0); |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 245 | #endif |
drh | 72339a3 | 2010-05-13 20:19:17 +0000 | [diff] [blame] | 246 | #endif |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 247 | break; |
| 248 | } |
| 249 | } |
mistachkin | 091881b | 2018-02-18 00:54:06 +0000 | [diff] [blame] | 250 | assert( p==0 || p->id==iType ); |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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 | */ |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 260 | static void winMutexFree(sqlite3_mutex *p){ |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 261 | assert( p ); |
dan | 84612fe | 2010-08-10 07:12:26 +0000 | [diff] [blame] | 262 | assert( p->nRef==0 && p->owner==0 ); |
drh | 96c707a | 2015-02-13 16:36:14 +0000 | [diff] [blame] | 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; |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 269 | #endif |
drh | 96c707a | 2015-02-13 16:36:14 +0000 | [diff] [blame] | 270 | } |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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 | */ |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 284 | static void winMutexEnter(sqlite3_mutex *p){ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 285 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 286 | DWORD tid = GetCurrentThreadId(); |
| 287 | #endif |
drh | 72339a3 | 2010-05-13 20:19:17 +0000 | [diff] [blame] | 288 | #ifdef SQLITE_DEBUG |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 289 | assert( p ); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 290 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 291 | #else |
| 292 | assert( p ); |
drh | 72339a3 | 2010-05-13 20:19:17 +0000 | [diff] [blame] | 293 | #endif |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 294 | assert( winMutex_isInit==1 ); |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 295 | EnterCriticalSection(&p->mutex); |
drh | 72339a3 | 2010-05-13 20:19:17 +0000 | [diff] [blame] | 296 | #ifdef SQLITE_DEBUG |
dan | 84612fe | 2010-08-10 07:12:26 +0000 | [diff] [blame] | 297 | assert( p->nRef>0 || p->owner==0 ); |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 298 | p->owner = tid; |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 299 | p->nRef++; |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 300 | if( p->trace ){ |
mistachkin | 0d5b3b7 | 2017-02-15 18:30:57 +0000 | [diff] [blame] | 301 | OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", |
| 302 | tid, p->id, p, p->trace, p->nRef)); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 303 | } |
| 304 | #endif |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 305 | } |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 306 | |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 307 | static int winMutexTry(sqlite3_mutex *p){ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 308 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 309 | DWORD tid = GetCurrentThreadId(); |
shaneh | 1da207e | 2010-03-09 14:41:12 +0000 | [diff] [blame] | 310 | #endif |
drh | 8650506 | 2007-10-05 15:08:01 +0000 | [diff] [blame] | 311 | int rc = SQLITE_BUSY; |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 312 | assert( p ); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 313 | assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
drh | 8650506 | 2007-10-05 15:08:01 +0000 | [diff] [blame] | 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 |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 317 | ** fail. |
drh | 8650506 | 2007-10-05 15:08:01 +0000 | [diff] [blame] | 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 | */ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 325 | #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 326 | assert( winMutex_isInit==1 ); |
mistachkin | 202cb64 | 2014-07-31 18:54:01 +0000 | [diff] [blame] | 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) ){ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 333 | #ifdef SQLITE_DEBUG |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 334 | p->owner = tid; |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 335 | p->nRef++; |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 336 | #endif |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 337 | rc = SQLITE_OK; |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 338 | } |
shane | 1a38964 | 2009-01-30 16:09:22 +0000 | [diff] [blame] | 339 | #else |
| 340 | UNUSED_PARAMETER(p); |
drh | 8650506 | 2007-10-05 15:08:01 +0000 | [diff] [blame] | 341 | #endif |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 342 | #ifdef SQLITE_DEBUG |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 343 | if( p->trace ){ |
mistachkin | 0d5b3b7 | 2017-02-15 18:30:57 +0000 | [diff] [blame] | 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))); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 346 | } |
| 347 | #endif |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 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 | */ |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 357 | static void winMutexLeave(sqlite3_mutex *p){ |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 358 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
shaneh | 1da207e | 2010-03-09 14:41:12 +0000 | [diff] [blame] | 359 | DWORD tid = GetCurrentThreadId(); |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 360 | #endif |
| 361 | assert( p ); |
| 362 | #ifdef SQLITE_DEBUG |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 363 | assert( p->nRef>0 ); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 364 | assert( p->owner==tid ); |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 365 | p->nRef--; |
dan | 84612fe | 2010-08-10 07:12:26 +0000 | [diff] [blame] | 366 | if( p->nRef==0 ) p->owner = 0; |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 367 | assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
drh | 72339a3 | 2010-05-13 20:19:17 +0000 | [diff] [blame] | 368 | #endif |
drh | d42d0be | 2014-07-30 21:10:12 +0000 | [diff] [blame] | 369 | assert( winMutex_isInit==1 ); |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 370 | LeaveCriticalSection(&p->mutex); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 371 | #ifdef SQLITE_DEBUG |
| 372 | if( p->trace ){ |
mistachkin | 0d5b3b7 | 2017-02-15 18:30:57 +0000 | [diff] [blame] | 373 | OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", |
| 374 | tid, p->id, p, p->trace, p->nRef)); |
shaneh | 1f4222f | 2010-02-13 02:31:09 +0000 | [diff] [blame] | 375 | } |
| 376 | #endif |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 377 | } |
| 378 | |
dan | 558814f | 2010-06-02 05:53:53 +0000 | [diff] [blame] | 379 | sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 380 | static const sqlite3_mutex_methods sMutex = { |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 381 | winMutexInit, |
danielk1977 | 4a9d1f6 | 2008-06-19 08:51:23 +0000 | [diff] [blame] | 382 | winMutexEnd, |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 383 | winMutexAlloc, |
| 384 | winMutexFree, |
| 385 | winMutexEnter, |
| 386 | winMutexTry, |
| 387 | winMutexLeave, |
drh | a418980 | 2008-06-19 16:07:07 +0000 | [diff] [blame] | 388 | #ifdef SQLITE_DEBUG |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 389 | winMutexHeld, |
| 390 | winMutexNotheld |
drh | 1875f7a | 2008-12-08 18:19:17 +0000 | [diff] [blame] | 391 | #else |
| 392 | 0, |
| 393 | 0 |
drh | a418980 | 2008-06-19 16:07:07 +0000 | [diff] [blame] | 394 | #endif |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 395 | }; |
danielk1977 | 6d2ab0e | 2008-06-17 17:21:18 +0000 | [diff] [blame] | 396 | return &sMutex; |
drh | 437b901 | 2007-08-28 16:34:42 +0000 | [diff] [blame] | 397 | } |
mistachkin | 0174ffa | 2014-07-30 23:11:16 +0000 | [diff] [blame] | 398 | |
drh | c7ce76a | 2007-08-30 14:10:30 +0000 | [diff] [blame] | 399 | #endif /* SQLITE_MUTEX_W32 */ |