Index: ext/icu/icu.c ================================================================== --- ext/icu/icu.c +++ ext/icu/icu.c @@ -347,11 +347,11 @@ ** of the locale to use. Passing an empty string ("") or SQL NULL value ** as the second argument is the same as invoking the 1 argument version ** of upper() or lower(). ** ** lower('I', 'en_us') -> 'i' -** lower('I', 'tr_tr') -> 'ı' (small dotless i) +** lower('I', 'tr_tr') -> '\u131' (small dotless i) ** ** http://www.icu-project.org/userguide/posix.html#case_mappings */ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; /* Pointer to input string */ Index: src/mutex.h ================================================================== --- src/mutex.h +++ src/mutex.h @@ -48,10 +48,17 @@ # else # define SQLITE_MUTEX_NOOP # endif #endif +/* +** Allowed values for sqlite3_mutex.magic +*/ +#define SQLITE_MUTEXMAGIC_NORMAL 0x1f7a8074 +#define SQLITE_MUTEXMAGIC_TRACE 0x1f7a8075 +#define SQLITE_MUTEXMAGIC_DEAD 0x4b0844f6 + #ifdef SQLITE_MUTEX_OMIT /* ** If this is a no-op implementation, implement everything as macros. */ #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) Index: src/mutex_w32.c ================================================================== --- src/mutex_w32.c +++ src/mutex_w32.c @@ -38,11 +38,11 @@ CRITICAL_SECTION mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ #ifdef SQLITE_DEBUG volatile int nRef; /* Number of enterances */ volatile DWORD owner; /* Thread holding this mutex */ - volatile int trace; /* True to trace changes */ + volatile u32 magic; /* True to trace changes */ #endif }; /* ** These are the initializer values used when declaring a "static" mutex @@ -219,11 +219,13 @@ p = sqlite3MallocZero( sizeof(*p) ); if( p ){ p->id = iType; #ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC - p->trace = 1; + p->magic = SQLITE_MUTEXMAGIC_TRACE; +#else + p->magic = SQLITE_MUTEXMAGIC_NORMAL; #endif #endif #if SQLITE_OS_WINRT InitializeCriticalSectionEx(&p->mutex, 0, 0); #else @@ -241,11 +243,13 @@ #endif p = &winMutex_staticMutexes[iType-2]; p->id = iType; #ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC - p->trace = 1; + p->magic = SQLITE_MUTEXMAGIC_TRACE; +#else + p->magic = SQLITE_MUTEXMAGIC_NORMAL; #endif #endif break; } } @@ -258,10 +262,11 @@ ** allocated mutex. SQLite is careful to deallocate every ** mutex that it allocates. */ static void winMutexFree(sqlite3_mutex *p){ assert( p ); + assert( (p->magic&~1)==SQLITE_MUTEXMAGIC_NORMAL ); assert( p->nRef==0 && p->owner==0 ); if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ DeleteCriticalSection(&p->mutex); sqlite3_free(p); }else{ @@ -284,25 +289,24 @@ */ static void winMutexEnter(sqlite3_mutex *p){ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) DWORD tid = GetCurrentThreadId(); #endif -#ifdef SQLITE_DEBUG assert( p ); + assert( (p->magic&~1)==SQLITE_MUTEXMAGIC_NORMAL ); +#ifdef SQLITE_DEBUG assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); -#else - assert( p ); #endif assert( winMutex_isInit==1 ); EnterCriticalSection(&p->mutex); #ifdef SQLITE_DEBUG assert( p->nRef>0 || p->owner==0 ); p->owner = tid; p->nRef++; - if( p->trace ){ - OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", - tid, p, p->trace, p->nRef)); + if( p->magic&1 ){ + OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%lu), nRef=%d\n", + tid, p, p->magic, p->nRef)); } #endif } static int winMutexTry(sqlite3_mutex *p){ @@ -309,11 +313,14 @@ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) DWORD tid = GetCurrentThreadId(); #endif int rc = SQLITE_BUSY; assert( p ); + assert( (p->magic&~1)==SQLITE_MUTEXMAGIC_NORMAL ); +#ifdef SQLITE_DEBUG assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); +#endif /* ** The sqlite3_mutex_try() routine is very rarely used, and when it ** is used it is merely an optimization. So it is OK for it to always ** fail. ** @@ -339,13 +346,13 @@ } #else UNUSED_PARAMETER(p); #endif #ifdef SQLITE_DEBUG - if( p->trace ){ - OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", - tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); + if( p->magic&1 ){ + OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%lu), owner=%lu, nRef=%d, rc=%s\n", + tid, p, p->magic, p->owner, p->nRef, sqlite3ErrName(rc))); } #endif return rc; } @@ -358,10 +365,11 @@ static void winMutexLeave(sqlite3_mutex *p){ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) DWORD tid = GetCurrentThreadId(); #endif assert( p ); + assert( (p->magic&~1)==SQLITE_MUTEXMAGIC_NORMAL ); #ifdef SQLITE_DEBUG assert( p->nRef>0 ); assert( p->owner==tid ); p->nRef--; if( p->nRef==0 ) p->owner = 0; @@ -368,13 +376,13 @@ assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); #endif assert( winMutex_isInit==1 ); LeaveCriticalSection(&p->mutex); #ifdef SQLITE_DEBUG - if( p->trace ){ - OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", - tid, p, p->trace, p->nRef)); + if( p->magic&1 ){ + OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%lu), nRef=%d\n", + tid, p, p->magic, p->nRef)); } #endif } sqlite3_mutex_methods const *sqlite3DefaultMutex(void){