mirror of
https://github.com/DBD-SQLite/DBD-SQLite
synced 2025-06-07 14:19:10 -04:00
147 lines
4 KiB
C
147 lines
4 KiB
C
/*
|
|
** 2007 August 14
|
|
**
|
|
** The author disclaims copyright to this source code. In place of
|
|
** a legal notice, here is a blessing:
|
|
**
|
|
** May you do good and not evil.
|
|
** May you find forgiveness for yourself and forgive others.
|
|
** May you share freely, never taking more than you give.
|
|
**
|
|
*************************************************************************
|
|
** This file contains the C functions that implement mutexes.
|
|
**
|
|
** This file contains code that is common across all mutex implementations.
|
|
|
|
**
|
|
** $Id: mutex.c,v 1.29 2008/10/07 15:25:48 drh Exp $
|
|
*/
|
|
#include "sqliteInt.h"
|
|
|
|
#ifndef SQLITE_MUTEX_OMIT
|
|
/*
|
|
** Initialize the mutex system.
|
|
*/
|
|
int sqlite3MutexInit(void){
|
|
int rc = SQLITE_OK;
|
|
if( sqlite3GlobalConfig.bCoreMutex ){
|
|
if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
|
|
/* If the xMutexAlloc method has not been set, then the user did not
|
|
** install a mutex implementation via sqlite3_config() prior to
|
|
** sqlite3_initialize() being called. This block copies pointers to
|
|
** the default implementation into the sqlite3GlobalConfig structure.
|
|
**
|
|
** The danger is that although sqlite3_config() is not a threadsafe
|
|
** API, sqlite3_initialize() is, and so multiple threads may be
|
|
** attempting to run this function simultaneously. To guard write
|
|
** access to the sqlite3GlobalConfig structure, the 'MASTER' static mutex
|
|
** is obtained before modifying it.
|
|
*/
|
|
sqlite3_mutex_methods *p = sqlite3DefaultMutex();
|
|
sqlite3_mutex *pMaster = 0;
|
|
|
|
rc = p->xMutexInit();
|
|
if( rc==SQLITE_OK ){
|
|
pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
|
assert(pMaster);
|
|
p->xMutexEnter(pMaster);
|
|
assert( sqlite3GlobalConfig.mutex.xMutexAlloc==0
|
|
|| sqlite3GlobalConfig.mutex.xMutexAlloc==p->xMutexAlloc
|
|
);
|
|
if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
|
|
sqlite3GlobalConfig.mutex = *p;
|
|
}
|
|
p->xMutexLeave(pMaster);
|
|
}
|
|
}else{
|
|
rc = sqlite3GlobalConfig.mutex.xMutexInit();
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
** Shutdown the mutex system. This call frees resources allocated by
|
|
** sqlite3MutexInit().
|
|
*/
|
|
int sqlite3MutexEnd(void){
|
|
int rc = SQLITE_OK;
|
|
rc = sqlite3GlobalConfig.mutex.xMutexEnd();
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
|
|
*/
|
|
sqlite3_mutex *sqlite3_mutex_alloc(int id){
|
|
#ifndef SQLITE_OMIT_AUTOINIT
|
|
if( sqlite3_initialize() ) return 0;
|
|
#endif
|
|
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
|
|
}
|
|
|
|
sqlite3_mutex *sqlite3MutexAlloc(int id){
|
|
if( !sqlite3GlobalConfig.bCoreMutex ){
|
|
return 0;
|
|
}
|
|
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
|
|
}
|
|
|
|
/*
|
|
** Free a dynamic mutex.
|
|
*/
|
|
void sqlite3_mutex_free(sqlite3_mutex *p){
|
|
if( p ){
|
|
sqlite3GlobalConfig.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 ){
|
|
sqlite3GlobalConfig.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 sqlite3GlobalConfig.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 ){
|
|
sqlite3GlobalConfig.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 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
|
|
}
|
|
int sqlite3_mutex_notheld(sqlite3_mutex *p){
|
|
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
|
|
}
|
|
#endif
|
|
|
|
#endif /* SQLITE_OMIT_MUTEX */
|