Index: src/mem2.c ================================================================== --- src/mem2.c +++ src/mem2.c @@ -17,11 +17,11 @@ ** leaks and memory usage errors. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem2.c,v 1.30 2008/06/17 15:12:01 drh Exp $ +** $Id: mem2.c,v 1.31 2008/06/17 17:21:18 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is used only if the @@ -319,11 +319,11 @@ sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); } /* ** Set the number of backtrace levels kept for each allocation. -** A value of zero turns of backtracing. The number is always rounded +** A value of zero turns off backtracing. The number is always rounded ** up to a multiple of 2. */ void sqlite3MemdebugBacktrace(int depth){ if( depth<0 ){ depth = 0; } if( depth>20 ){ depth = 20; } Index: src/mutex.c ================================================================== --- src/mutex.c +++ src/mutex.c @@ -17,13 +17,118 @@ ** does do a lot of error checking on mutexes to make sure they ** are called correctly and at appropriate times. Hence, this ** implementation is suitable for testing. ** debugging purposes ** -** $Id: mutex.c,v 1.20 2008/06/15 02:51:48 drh Exp $ +** $Id: mutex.c,v 1.21 2008/06/17 17:21:18 danielk1977 Exp $ */ #include "sqliteInt.h" + +#ifndef SQLITE_MUTEX_NOOP +/* +** Initialize the mutex system. +*/ +int sqlite3_mutex_init(void){ + int rc; + if( !sqlite3Config.mutex.xMutexAlloc ){ + sqlite3_mutex_methods *p = sqlite3DefaultMutex(); + sqlite3_mutex *pMaster; + + rc = p->xMutexInit(); + if( rc==SQLITE_OK ){ + pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + p->xMutexEnter(pMaster); + assert( sqlite3Config.mutex.xMutexAlloc==0 + || sqlite3Config.mutex.xMutexAlloc==p->xMutexAlloc + ); + if( !sqlite3Config.mutex.xMutexAlloc ){ + sqlite3Config.mutex = *p; + } + p->xMutexLeave(pMaster); + } + + }else{ + rc = sqlite3Config.mutex.xMutexInit(); + } + + return rc; +} + +/* +** Shutdown the mutex system. This call frees resources allocated by +** sqlite3_mutex_init(). +*/ +int sqlite3_mutex_end(void){ + int rc = SQLITE_OK; + rc = sqlite3Config.mutex.xMutexEnd(); + return rc; +} + +/* +** Retrieve a pointer to a static mutex or allocate a new dynamic one. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int id){ + return sqlite3Config.mutex.xMutexAlloc(id); +} + +/* +** Free a dynamic mutex. +*/ +void sqlite3_mutex_free(sqlite3_mutex *p){ + if( p ){ + sqlite3Config.mutex.xMutexFree(p); + } +} + +/* +** Obtain the mutex p. If some other thread already has the mutex, block +** until it can be obtained. +*/ +void sqlite3_mutex_enter(sqlite3_mutex *p){ + if( p ){ + sqlite3Config.mutex.xMutexEnter(p); + } +} + +/* +** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another +** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. +*/ +int sqlite3_mutex_try(sqlite3_mutex *p){ + int rc = SQLITE_OK; + if( p ){ + return sqlite3Config.mutex.xMutexTry(p); + } + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was previously +** entered by the same thread. The behavior is undefined if the mutex +** is not currently entered. If a NULL pointer is passed as an argument +** this function is a no-op. +*/ +void sqlite3_mutex_leave(sqlite3_mutex *p){ + if( p ){ + sqlite3Config.mutex.xMutexLeave(p); + } +} + +#ifndef NDEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +int sqlite3_mutex_held(sqlite3_mutex *p){ + return p==0 || sqlite3Config.mutex.xMutexHeld(p); +} +int sqlite3_mutex_notheld(sqlite3_mutex *p){ + return p==0 || sqlite3Config.mutex.xMutexNotheld(p); +} +#endif + +#endif #ifdef SQLITE_MUTEX_NOOP_DEBUG /* ** In this implementation, mutexes do not provide any mutual exclusion. ** But the error checking is provided. This implementation is useful @@ -35,23 +140,34 @@ */ struct sqlite3_mutex { int id; /* The mutex type */ int cnt; /* Number of entries without a matching leave */ }; + +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +static int noopMutexHeld(sqlite3_mutex *p){ + return p==0 || p->cnt>0; +} +static int noopMutexNotheld(sqlite3_mutex *p){ + return p==0 || p->cnt==0; +} /* ** Initialize and deinitialize the mutex subsystem. */ -int sqlite3_mutex_init(void){ return SQLITE_OK; } -int sqlite3_mutex_end(void){ return SQLITE_OK; } +static int noopMutexInit(void){ return SQLITE_OK; } +static int noopMutexEnd(void){ return SQLITE_OK; } /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. */ -sqlite3_mutex *sqlite3_mutex_alloc(int id){ +static sqlite3_mutex *noopMutexAlloc(int id){ static sqlite3_mutex aStatic[6]; sqlite3_mutex *pNew = 0; switch( id ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { @@ -74,12 +190,11 @@ } /* ** This routine deallocates a previously allocated mutex. */ -void sqlite3_mutex_free(sqlite3_mutex *p){ - if( p==0 ) return; +static void noopMutexFree(sqlite3_mutex *p){ assert( p->cnt==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); sqlite3_free(p); } @@ -92,44 +207,44 @@ ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ -void sqlite3_mutex_enter(sqlite3_mutex *p){ - if( p ){ - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - p->cnt++; - } -} -int sqlite3_mutex_try(sqlite3_mutex *p){ - if( p ){ - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - p->cnt++; - } +static void noopMutexEnter(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) ); + p->cnt++; +} +static int noopMutexTry(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) ); + p->cnt++; return SQLITE_OK; } /* ** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ -void sqlite3_mutex_leave(sqlite3_mutex *p){ - if( p ){ - assert( sqlite3_mutex_held(p) ); - p->cnt--; - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); - } -} - -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use inside assert() statements. -*/ -int sqlite3_mutex_held(sqlite3_mutex *p){ - return p==0 || p->cnt>0; -} -int sqlite3_mutex_notheld(sqlite3_mutex *p){ - return p==0 || p->cnt==0; +static void noopMutexLeave(sqlite3_mutex *p){ + assert( sqlite3_mutex_held(p) ); + p->cnt--; + assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); +} + +sqlite3_mutex_methods *sqlite3DefaultMutex(void){ + static sqlite3_mutex_methods sMutex = { + noopMutexInit, + noopMutexAlloc, + noopMutexFree, + noopMutexEnter, + noopMutexTry, + noopMutexLeave, + noopMutexEnd, + + noopMutexHeld, + noopMutexNotheld + }; + + return &sMutex; } #endif /* SQLITE_MUTEX_NOOP_DEBUG */ Index: src/mutex_unix.c ================================================================== --- src/mutex_unix.c +++ src/mutex_unix.c @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for pthreads ** -** $Id: mutex_unix.c,v 1.8 2008/06/13 18:24:27 drh Exp $ +** $Id: mutex_unix.c,v 1.9 2008/06/17 17:21:18 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The code in this file is only used if we are compiling threadsafe @@ -43,15 +43,40 @@ #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 } #else #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0 } #endif +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. On some platforms, +** there might be race conditions that can cause these routines to +** deliver incorrect results. In particular, if pthread_equal() is +** not an atomic operation, then these routines might delivery +** incorrect results. On most platforms, pthread_equal() is a +** comparison of two integers and is therefore atomic. But we are +** told that HPUX is not such a platform. If so, then these routines +** will not always work correctly on HPUX. +** +** On those platforms where pthread_equal() is not atomic, SQLite +** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to +** make sure no assert() statements are evaluated and hence these +** routines are never called. +*/ +#ifndef NDEBUG +static int pthreadMutexHeld(sqlite3_mutex *p){ + return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); +} +static int pthreadMutexNotheld(sqlite3_mutex *p){ + return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; +} +#endif + /* ** Initialize and deinitialize the mutex subsystem. */ -int sqlite3_mutex_init(void){ return SQLITE_OK; } -int sqlite3_mutex_end(void){ return SQLITE_OK; } +static int pthreadMutexInit(void){ return SQLITE_OK; } +static int pthreadMutexEnd(void){ return SQLITE_OK; } /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. SQLite @@ -90,11 +115,11 @@ ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ -sqlite3_mutex *sqlite3_mutex_alloc(int iType){ +static sqlite3_mutex *pthreadMutexAlloc(int iType){ static sqlite3_mutex staticMutexes[] = { SQLITE3_MUTEX_INITIALIZER, SQLITE3_MUTEX_INITIALIZER, SQLITE3_MUTEX_INITIALIZER, SQLITE3_MUTEX_INITIALIZER, @@ -145,17 +170,15 @@ /* ** This routine deallocates a previously ** allocated mutex. SQLite is careful to deallocate every ** mutex that it allocates. */ -void sqlite3_mutex_free(sqlite3_mutex *p){ - if( p ){ - assert( p->nRef==0 ); - assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); - pthread_mutex_destroy(&p->mutex); - sqlite3_free(p); - } +static void pthreadMutexFree(sqlite3_mutex *p){ + assert( p->nRef==0 ); + assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); + pthread_mutex_destroy(&p->mutex); + sqlite3_free(p); } /* ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt ** to enter a mutex. If another thread is already within the mutex, @@ -165,13 +188,12 @@ ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ -void sqlite3_mutex_enter(sqlite3_mutex *p){ - if( p==0 ) return; - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); +static void pthreadMutexEnter(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX /* If recursive mutexes are not available, then we have to grow ** our own. This implementation assumes that pthread_equal() ** is atomic - that it cannot be deceived into thinking self @@ -205,14 +227,13 @@ if( p->trace ){ printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); } #endif } -int sqlite3_mutex_try(sqlite3_mutex *p){ +static int pthreadMutexTry(sqlite3_mutex *p){ int rc; - if( p==0 ) return SQLITE_OK; - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX /* If recursive mutexes are not available, then we have to grow ** our own. This implementation assumes that pthread_equal() ** is atomic - that it cannot be deceived into thinking self @@ -261,12 +282,11 @@ ** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ -void sqlite3_mutex_leave(sqlite3_mutex *p){ - if( p==0 ) return; +static void pthreadMutexLeave(sqlite3_mutex *p){ assert( sqlite3_mutex_held(p) ); p->nRef--; assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX @@ -282,30 +302,23 @@ printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); } #endif } -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use only inside assert() statements. On some platforms, -** there might be race conditions that can cause these routines to -** deliver incorrect results. In particular, if pthread_equal() is -** not an atomic operation, then these routines might delivery -** incorrect results. On most platforms, pthread_equal() is a -** comparison of two integers and is therefore atomic. But we are -** told that HPUX is not such a platform. If so, then these routines -** will not always work correctly on HPUX. -** -** On those platforms where pthread_equal() is not atomic, SQLite -** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to -** make sure no assert() statements are evaluated and hence these -** routines are never called. -*/ -#ifndef NDEBUG -int sqlite3_mutex_held(sqlite3_mutex *p){ - return p==0 || (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); -} -int sqlite3_mutex_notheld(sqlite3_mutex *p){ - return p==0 || p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; -} -#endif +sqlite3_mutex_methods *sqlite3DefaultMutex(void){ + static sqlite3_mutex_methods sMutex = { + pthreadMutexInit, + pthreadMutexAlloc, + pthreadMutexFree, + pthreadMutexEnter, + pthreadMutexTry, + pthreadMutexLeave, + pthreadMutexEnd, + + pthreadMutexHeld, + pthreadMutexNotheld + }; + + return &sMutex; +} + #endif /* SQLITE_MUTEX_PTHREAD */ Index: src/mutex_w32.c ================================================================== --- src/mutex_w32.c +++ src/mutex_w32.c @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for win32 ** -** $Id: mutex_w32.c,v 1.7 2008/06/13 18:24:27 drh Exp $ +** $Id: mutex_w32.c,v 1.8 2008/06/17 17:21:18 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The code in this file is only used if we are compiling multithreaded @@ -55,16 +55,27 @@ } return osType==2; } #endif /* OS_WINCE */ +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. +*/ +static int winMutexHeld(sqlite3_mutex *p){ + return p->nRef!=0 && p->owner==GetCurrentThreadId(); +} +static int winMutexNotheld(sqlite3_mutex *p){ + return p->nRef==0 || p->owner!=GetCurrentThreadId(); +} + /* ** Initialize and deinitialize the mutex subsystem. */ -int sqlite3_mutex_init(void){ return SQLITE_OK; } -int sqlite3_mutex_end(void){ return SQLITE_OK; } +static int winMutexInit(void){ return SQLITE_OK; } +static int winMutexEnd(void){ return SQLITE_OK; } /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. SQLite @@ -101,11 +112,11 @@ ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ -sqlite3_mutex *sqlite3_mutex_alloc(int iType){ +static sqlite3_mutex *winMutexAlloc(int iType){ sqlite3_mutex *p; switch( iType ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { @@ -145,11 +156,11 @@ /* ** This routine deallocates a previously ** allocated mutex. SQLite is careful to deallocate every ** mutex that it allocates. */ -void sqlite3_mutex_free(sqlite3_mutex *p){ +static void winMutexFree(sqlite3_mutex *p){ assert( p ); assert( p->nRef==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); DeleteCriticalSection(&p->mutex); sqlite3_free(p); @@ -164,21 +175,19 @@ ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ -void sqlite3_mutex_enter(sqlite3_mutex *p){ - if( p==0 ) return; - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); +static void winMutexEnter(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); EnterCriticalSection(&p->mutex); p->owner = GetCurrentThreadId(); p->nRef++; } -int sqlite3_mutex_try(sqlite3_mutex *p){ +static int winMutexTry(sqlite3_mutex *p){ int rc = SQLITE_BUSY; - if( p==0 ) return SQLITE_OK; - assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); /* ** 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. ** @@ -202,25 +211,31 @@ ** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ -void sqlite3_mutex_leave(sqlite3_mutex *p){ - if( p==0 ) return; +static void winMutexLeave(sqlite3_mutex *p){ assert( p->nRef>0 ); assert( p->owner==GetCurrentThreadId() ); p->nRef--; assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); LeaveCriticalSection(&p->mutex); } -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use only inside assert() statements. -*/ -int sqlite3_mutex_held(sqlite3_mutex *p){ - return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId()); -} -int sqlite3_mutex_notheld(sqlite3_mutex *p){ - return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId(); +sqlite3_mutex_methods *sqlite3DefaultMutex(void){ + static sqlite3_mutex_methods sMutex = { + winMutexInit, + winMutexAlloc, + winMutexFree, + winMutexEnter, + winMutexTry, + winMutexLeave, + winMutexEnd, + + winMutexHeld, + winMutexNotheld + }; + + return &sMutex; } #endif /* SQLITE_MUTEX_W32 */ + Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -28,11 +28,11 @@ ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.329 2008/06/17 15:12:01 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.330 2008/06/17 17:21:18 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include /* Needed for the definition of va_list */ @@ -5781,10 +5781,24 @@ void sqlite3_mutex_free(sqlite3_mutex*); void sqlite3_mutex_enter(sqlite3_mutex*); int sqlite3_mutex_try(sqlite3_mutex*); void sqlite3_mutex_leave(sqlite3_mutex*); int sqlite3_mutex_end(void); + +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexEnd)(void); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + /* ** CAPI3REF: Mutex Verifcation Routines {F17080} ** ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.711 2008/06/17 15:12:01 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.712 2008/06/17 17:21:18 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* @@ -1737,10 +1737,11 @@ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ + sqlite3_mutex_methods mutex; /* Low-level mutex interface */ void *pHeap; /* Heap storage space */ sqlite3_int64 nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max memory request sizes */ int nTemp; /* Part of pHeap for temporary allos */ }; @@ -1794,10 +1795,12 @@ void *sqlite3ScratchMalloc(int); void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); + +sqlite3_mutex_methods *sqlite3DefaultMutex(void); int sqlite3IsNaN(double); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list);