diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 65 | ||||
-rw-r--r-- | src/os.c | 10 | ||||
-rw-r--r-- | src/sqliteInt.h | 12 |
3 files changed, 55 insertions, 32 deletions
diff --git a/src/main.c b/src/main.c index 520c16a4f..b2cfa119b 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.462 2008/06/25 17:19:01 danielk1977 Exp $ +** $Id: main.c,v 1.463 2008/06/26 08:29:34 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -66,26 +66,56 @@ char *sqlite3_temp_directory = 0; ** or for the first call after a call to sqlite3_shutdown. */ int sqlite3_initialize(void){ + static int inProgress = 0; int rc; + + /* If SQLite is already initialized, this call is a no-op. */ if( sqlite3Config.isInit ) return SQLITE_OK; + + /* Make sure the mutex system is initialized. */ rc = sqlite3MutexInit(); + if( rc==SQLITE_OK ){ -#ifndef SQLITE_MUTEX_NOOP - sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -#endif - sqlite3_mutex_enter(pMutex); - if( sqlite3Config.isInit==0 ){ - sqlite3Config.isInit = 1; - sqlite3StatusReset(); - if( rc==SQLITE_OK ) rc = sqlite3MallocInit(); - if( rc==SQLITE_OK ) rc = sqlite3_os_init(); - if( rc!=SQLITE_OK ){ - sqlite3Config.isInit = 0; - }else{ - sqlite3Config.isInit = 2; + + /* Initialize the malloc() system and the recursive pInitMutex mutex. + ** This operation is protected by the STATIC_MASTER mutex. + */ + sqlite3_mutex *pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex_enter(pMaster); + if( !sqlite3Config.isMallocInit ){ + rc = sqlite3MallocInit(); + } + if( rc==SQLITE_OK ){ + sqlite3Config.isMallocInit = 1; + if( !sqlite3Config.pInitMutex ){ + sqlite3Config.pInitMutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( sqlite3Config.bCoreMutex && !sqlite3Config.pInitMutex ){ + rc = SQLITE_NOMEM; + } } } - sqlite3_mutex_leave(pMutex); + sqlite3_mutex_leave(pMaster); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Enter the recursive pInitMutex mutex. After doing so, if the + ** sqlite3Config.isInit flag is true, then some other thread has + ** finished doing the initialization. If the inProgress flag is + ** true, then this function is being called recursively from within + ** the sqlite3_os_init() call below. In either case, exit early. + */ + sqlite3_mutex_enter(sqlite3Config.pInitMutex); + if( sqlite3Config.isInit || inProgress ){ + sqlite3_mutex_leave(sqlite3Config.pInitMutex); + return SQLITE_OK; + } + sqlite3StatusReset(); + inProgress = 1; + rc = sqlite3_os_init(); + inProgress = 0; + sqlite3Config.isInit = (rc==SQLITE_OK ? 1 : 0); + sqlite3_mutex_leave(sqlite3Config.pInitMutex); } return rc; } @@ -97,6 +127,9 @@ int sqlite3_initialize(void){ ** routine is not threadsafe. Not by a long shot. */ int sqlite3_shutdown(void){ + sqlite3_mutex_free(sqlite3Config.pInitMutex); + sqlite3Config.pInitMutex = 0; + sqlite3Config.isMallocInit = 0; sqlite3_os_end(); sqlite3MallocEnd(); sqlite3MutexEnd(); @@ -119,7 +152,7 @@ int sqlite3_config(int op, ...){ /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while ** the SQLite library is in use. */ - if( sqlite3Config.isInit==2 ) return SQLITE_MISUSE; + if( sqlite3Config.isInit ) return SQLITE_MISUSE; va_start(ap, op); switch( op ){ @@ -13,7 +13,7 @@ ** This file contains OS interface code that is common to all ** architectures. ** -** $Id: os.c,v 1.116 2008/06/25 17:19:01 danielk1977 Exp $ +** $Id: os.c,v 1.117 2008/06/26 08:29:34 danielk1977 Exp $ */ #define _SQLITE_OS_C_ 1 #include "sqliteInt.h" @@ -243,18 +243,12 @@ static void vfsUnlink(sqlite3_vfs *pVfs){ ** true. */ int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ -#ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = 0; -#endif #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); if( rc ) return rc; #endif -#ifndef SQLITE_MUTEX_NOOP - if( sqlite3Config.isInit!=1 ){ - mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); - } -#endif + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); if( makeDflt || vfsList==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 65c374d40..942396a6f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.729 2008/06/25 17:19:01 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.730 2008/06/26 08:29:34 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1734,12 +1734,6 @@ typedef struct { ** Structure containing global configuration data for the SQLite library. ** ** This structure also contains some state information. -** -** The Sqlite3Config.isInit variable indicates whether or not -** sqlite3_initialize() has already been called or not. Initially, isInit -** is 0. While sqlite3_initialize() is running, it is set to 1. After -** sqlite3_initialize has successfully run, the Sqlite3Config.isInit variable -** is set to 2. Calling sqlite3_shutdown() resets the value to 0. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ @@ -1756,7 +1750,9 @@ struct Sqlite3Config { void *pPage; /* Page cache memory */ int szPage; /* Size of each page in pPage[] */ int nPage; /* Number of pages in pPage[] */ - int isInit; /* Initialization state */ + int isInit; /* True after initialization has finished */ + int isMallocInit; /* True after malloc is initialized */ + sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ }; /* |