mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Change the design of the mutex interface to allow for
both "fast" and "recursive" mutexes. (CVS 4238) FossilOrigin-Name: 160593dcc5690af715b775c81137c6e09cca6454
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Remove\sthe\sthread\sspecific\sdata\ssubsystem\sfrom\sthe\sunix\sbuild.\s\sRemove\nlegacy\scruft\sfrom\ssqliteInt.h.\s\sUse\sthe\snew\smutex\ssubsystem\sin\sthe\sPRNG.\s(CVS\s4237)
|
C Change\sthe\sdesign\sof\sthe\s\smutex\sinterface\sto\sallow\sfor\nboth\s"fast"\sand\s"recursive"\smutexes.\s(CVS\s4238)
|
||||||
D 2007-08-16T13:01:45
|
D 2007-08-16T19:40:17
|
||||||
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
||||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -88,9 +88,9 @@ F src/loadext.c aa1c6e584d39cc241226ec9390387bc2d4a23e8f
|
|||||||
F src/main.c 996df547489d4826f70629b16623d7408f55ecd7
|
F src/main.c 996df547489d4826f70629b16623d7408f55ecd7
|
||||||
F src/malloc.c 613c65f12ff0ee4edd017aa458209ab7a23cd7b1
|
F src/malloc.c 613c65f12ff0ee4edd017aa458209ab7a23cd7b1
|
||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
F src/mem1.c 08c4ee16393835b2d24ad39ce7b64c0f8c5b1df7
|
F src/mem1.c 2c6a6e3b2c9c7cb8d398a8468095032407c3e0b7
|
||||||
F src/mem2.c d0ba3b23da2e95bced1818ade8a8a2dc9526111c
|
F src/mem2.c 661ca7ebf6e4b964fecc95d24e8c89dbcfc9dfea
|
||||||
F src/mutex.c b4f963ebdcb0622b3026937826afefd8a05884e1
|
F src/mutex.c 679d5d9c99bd302c0c43ee3eba61348c44aea366
|
||||||
F src/os.c e2faefbe0f5a8ca5e3b1c49ee1b5c6cfa0f0e279
|
F src/os.c e2faefbe0f5a8ca5e3b1c49ee1b5c6cfa0f0e279
|
||||||
F src/os.h 8eff07babf74e5bc3f895f8a6c7c294dad5ff997
|
F src/os.h 8eff07babf74e5bc3f895f8a6c7c294dad5ff997
|
||||||
F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
|
F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
|
||||||
@@ -112,7 +112,7 @@ F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
|
|||||||
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
|
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
||||||
F src/sqlite.h.in 1fb6748ebd4c36b8476c03791009585fd5cfcf3b
|
F src/sqlite.h.in 8efd7d5aca057a793d221973da1f22a22e69f4db
|
||||||
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
|
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
|
||||||
F src/sqliteInt.h fa9baff32aef7ca1ecebcd014b3bd75c981829d0
|
F src/sqliteInt.h fa9baff32aef7ca1ecebcd014b3bd75c981829d0
|
||||||
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
|
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
|
||||||
@@ -529,7 +529,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P ba80ee59a72afe36817997de705ef81d876b6f35
|
P 3d60c14a32955b69e714a73372924d421899f83b
|
||||||
R 4dbfd96f907def879d1b3bfd1f2c5bd5
|
R 79bf1accc56116075f09cd253592694c
|
||||||
U drh
|
U drh
|
||||||
Z 6248f8cb69e3663b94e130d7ac9b903a
|
Z e40cc1b0395242393945aa35a1600f4d
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
3d60c14a32955b69e714a73372924d421899f83b
|
160593dcc5690af715b775c81137c6e09cca6454
|
||||||
32
src/mem1.c
32
src/mem1.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains the C functions that implement a memory
|
** This file contains the C functions that implement a memory
|
||||||
** allocation subsystem for use by SQLite.
|
** allocation subsystem for use by SQLite.
|
||||||
**
|
**
|
||||||
** $Id: mem1.c,v 1.4 2007/08/16 13:01:45 drh Exp $
|
** $Id: mem1.c,v 1.5 2007/08/16 19:40:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -81,9 +81,9 @@ static struct {
|
|||||||
sqlite3_uint64 sqlite3_memory_used(void){
|
sqlite3_uint64 sqlite3_memory_used(void){
|
||||||
sqlite3_uint64 n;
|
sqlite3_uint64 n;
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
n = mem.nowUsed;
|
n = mem.nowUsed;
|
||||||
sqlite3_mutex_leave(mem.mutex);
|
sqlite3_mutex_leave(mem.mutex);
|
||||||
return n;
|
return n;
|
||||||
@@ -97,9 +97,9 @@ sqlite3_uint64 sqlite3_memory_used(void){
|
|||||||
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
|
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
|
||||||
sqlite3_uint64 n;
|
sqlite3_uint64 n;
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
n = mem.mxUsed;
|
n = mem.mxUsed;
|
||||||
if( resetFlag ){
|
if( resetFlag ){
|
||||||
mem.mxUsed = mem.nowUsed;
|
mem.mxUsed = mem.nowUsed;
|
||||||
@@ -117,9 +117,9 @@ int sqlite3_memory_alarm(
|
|||||||
sqlite3_uint64 iThreshold
|
sqlite3_uint64 iThreshold
|
||||||
){
|
){
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
mem.alarmCallback = xCallback;
|
mem.alarmCallback = xCallback;
|
||||||
mem.alarmArg = pArg;
|
mem.alarmArg = pArg;
|
||||||
mem.alarmThreshold = iThreshold;
|
mem.alarmThreshold = iThreshold;
|
||||||
@@ -131,9 +131,17 @@ int sqlite3_memory_alarm(
|
|||||||
** Trigger the alarm
|
** Trigger the alarm
|
||||||
*/
|
*/
|
||||||
static void sqlite3MemsysAlarm(unsigned nByte){
|
static void sqlite3MemsysAlarm(unsigned nByte){
|
||||||
|
void (*xCallback)(void*,sqlite3_uint64,unsigned);
|
||||||
|
sqlite3_uint64 nowUsed;
|
||||||
|
void *pArg;
|
||||||
if( mem.alarmCallback==0 || mem.alarmBusy ) return;
|
if( mem.alarmCallback==0 || mem.alarmBusy ) return;
|
||||||
mem.alarmBusy = 1;
|
mem.alarmBusy = 1;
|
||||||
mem.alarmCallback(mem.alarmArg, mem.nowUsed, nByte);
|
xCallback = mem.alarmCallback;
|
||||||
|
nowUsed = mem.nowUsed;
|
||||||
|
pArg = mem.alarmArg;
|
||||||
|
sqlite3_mutex_leave(mem.mutex);
|
||||||
|
xCallback(pArg, nowUsed, nByte);
|
||||||
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
mem.alarmBusy = 0;
|
mem.alarmBusy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,9 +151,9 @@ static void sqlite3MemsysAlarm(unsigned nByte){
|
|||||||
void *sqlite3_malloc(unsigned int nBytes){
|
void *sqlite3_malloc(unsigned int nBytes){
|
||||||
sqlite3_uint64 *p;
|
sqlite3_uint64 *p;
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_MEM);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
if( mem.nowUsed+nBytes>=mem.alarmThreshold ){
|
if( mem.nowUsed+nBytes>=mem.alarmThreshold ){
|
||||||
sqlite3MemsysAlarm(nBytes);
|
sqlite3MemsysAlarm(nBytes);
|
||||||
}
|
}
|
||||||
@@ -179,7 +187,7 @@ void sqlite3_free(void *pPrior){
|
|||||||
p = pPrior;
|
p = pPrior;
|
||||||
p--;
|
p--;
|
||||||
nByte = (unsigned int)*p;
|
nByte = (unsigned int)*p;
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
mem.nowUsed -= nByte;
|
mem.nowUsed -= nByte;
|
||||||
free(p);
|
free(p);
|
||||||
sqlite3_mutex_leave(mem.mutex);
|
sqlite3_mutex_leave(mem.mutex);
|
||||||
@@ -202,7 +210,7 @@ void *sqlite3_realloc(void *pPrior, unsigned int nBytes){
|
|||||||
p--;
|
p--;
|
||||||
nOld = (unsigned int)p[0];
|
nOld = (unsigned int)p[0];
|
||||||
assert( mem.mutex!=0 );
|
assert( mem.mutex!=0 );
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
|
if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
|
||||||
sqlite3MemsysAlarm(nBytes-nOld);
|
sqlite3MemsysAlarm(nBytes-nOld);
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/mem2.c
30
src/mem2.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains the C functions that implement a memory
|
** This file contains the C functions that implement a memory
|
||||||
** allocation subsystem for use by SQLite.
|
** allocation subsystem for use by SQLite.
|
||||||
**
|
**
|
||||||
** $Id: mem2.c,v 1.3 2007/08/15 20:41:29 drh Exp $
|
** $Id: mem2.c,v 1.4 2007/08/16 19:40:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -147,9 +147,9 @@ static struct {
|
|||||||
sqlite3_uint64 sqlite3_memory_used(void){
|
sqlite3_uint64 sqlite3_memory_used(void){
|
||||||
sqlite3_uint64 n;
|
sqlite3_uint64 n;
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(1);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
n = mem.nowUsed;
|
n = mem.nowUsed;
|
||||||
sqlite3_mutex_leave(mem.mutex);
|
sqlite3_mutex_leave(mem.mutex);
|
||||||
return n;
|
return n;
|
||||||
@@ -163,9 +163,9 @@ sqlite3_uint64 sqlite3_memory_used(void){
|
|||||||
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
|
sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
|
||||||
sqlite3_uint64 n;
|
sqlite3_uint64 n;
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(1);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
n = mem.mxUsed;
|
n = mem.mxUsed;
|
||||||
if( resetFlag ){
|
if( resetFlag ){
|
||||||
mem.mxUsed = mem.nowUsed;
|
mem.mxUsed = mem.nowUsed;
|
||||||
@@ -183,9 +183,9 @@ int sqlite3_memory_alarm(
|
|||||||
sqlite3_uint64 iThreshold
|
sqlite3_uint64 iThreshold
|
||||||
){
|
){
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(1);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
mem.alarmCallback = xCallback;
|
mem.alarmCallback = xCallback;
|
||||||
mem.alarmArg = pArg;
|
mem.alarmArg = pArg;
|
||||||
mem.alarmThreshold = iThreshold;
|
mem.alarmThreshold = iThreshold;
|
||||||
@@ -197,9 +197,17 @@ int sqlite3_memory_alarm(
|
|||||||
** Trigger the alarm
|
** Trigger the alarm
|
||||||
*/
|
*/
|
||||||
static void sqlite3MemsysAlarm(unsigned nByte){
|
static void sqlite3MemsysAlarm(unsigned nByte){
|
||||||
|
void (*xCallback)(void*,sqlite3_uint64,unsigned);
|
||||||
|
sqlite3_uint64 nowUsed;
|
||||||
|
void *pArg;
|
||||||
if( mem.alarmCallback==0 || mem.alarmBusy ) return;
|
if( mem.alarmCallback==0 || mem.alarmBusy ) return;
|
||||||
mem.alarmBusy = 1;
|
mem.alarmBusy = 1;
|
||||||
mem.alarmCallback(mem.alarmArg, mem.nowUsed, nByte);
|
xCallback = mem.alarmCallback;
|
||||||
|
nowUsed = mem.nowUsed;
|
||||||
|
pArg = mem.alarmArg;
|
||||||
|
sqlite3_mutex_leave(mem.mutex);
|
||||||
|
xCallback(pArg, nowUsed, nByte);
|
||||||
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
mem.alarmBusy = 0;
|
mem.alarmBusy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,9 +251,9 @@ void *sqlite3_malloc(unsigned int nByte){
|
|||||||
unsigned int totalSize;
|
unsigned int totalSize;
|
||||||
|
|
||||||
if( mem.mutex==0 ){
|
if( mem.mutex==0 ){
|
||||||
mem.mutex = sqlite3_mutex_alloc(1);
|
mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
|
||||||
}
|
}
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
if( mem.nowUsed+nByte>=mem.alarmThreshold ){
|
if( mem.nowUsed+nByte>=mem.alarmThreshold ){
|
||||||
sqlite3MemsysAlarm(nByte);
|
sqlite3MemsysAlarm(nByte);
|
||||||
}
|
}
|
||||||
@@ -318,7 +326,7 @@ void sqlite3_free(void *pPrior){
|
|||||||
pHdr = sqlite3MemsysGetHeader(pPrior);
|
pHdr = sqlite3MemsysGetHeader(pPrior);
|
||||||
pBt = (void**)pHdr;
|
pBt = (void**)pHdr;
|
||||||
pBt -= pHdr->nBacktraceSlots;
|
pBt -= pHdr->nBacktraceSlots;
|
||||||
sqlite3_mutex_enter(mem.mutex, 1);
|
sqlite3_mutex_enter(mem.mutex);
|
||||||
mem.nowUsed -= pHdr->iSize;
|
mem.nowUsed -= pHdr->iSize;
|
||||||
if( pHdr->pPrev ){
|
if( pHdr->pPrev ){
|
||||||
assert( pHdr->pPrev->pNext==pHdr );
|
assert( pHdr->pPrev->pNext==pHdr );
|
||||||
|
|||||||
253
src/mutex.c
253
src/mutex.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains the C functions that implement mutexes for
|
** This file contains the C functions that implement mutexes for
|
||||||
** use by the SQLite core.
|
** use by the SQLite core.
|
||||||
**
|
**
|
||||||
** $Id: mutex.c,v 1.2 2007/08/16 10:09:03 danielk1977 Exp $
|
** $Id: mutex.c,v 1.3 2007/08/16 19:40:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -38,41 +38,30 @@
|
|||||||
/*
|
/*
|
||||||
** The sqlite3_mutex_alloc() routine allocates a new
|
** The sqlite3_mutex_alloc() routine allocates a new
|
||||||
** mutex and returns a pointer to it. If it returns NULL
|
** mutex and returns a pointer to it. If it returns NULL
|
||||||
** that means that a mutex could not be allocated. SQLite
|
** that means that a mutex could not be allocated.
|
||||||
** will unwind its stack and return an error. The argument
|
|
||||||
** to sqlite3_mutex_alloc() is usually zero, which causes
|
|
||||||
** any space required for the mutex to be obtained from
|
|
||||||
** sqlite3_malloc(). However if the argument is a positive
|
|
||||||
** integer less than SQLITE_NUM_STATIC_MUTEX, then a pointer
|
|
||||||
** to a static mutex is returned. There are a finite number
|
|
||||||
** of static mutexes. Static mutexes should not be passed
|
|
||||||
** to sqlite3_mutex_free(). The allocation of a static
|
|
||||||
** mutex cannot fail.
|
|
||||||
*/
|
*/
|
||||||
sqlite3_mutex *sqlite3_mutex_alloc(int idNotUsed){
|
sqlite3_mutex *sqlite3_mutex_alloc(int idNotUsed){
|
||||||
return (sqlite3_mutex*)sqlite3_mutex_alloc;
|
return (sqlite3_mutex*)sqlite3_mutex_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine deallocates a previously
|
** This routine deallocates a previously allocated mutex.
|
||||||
** allocated mutex. SQLite is careful to deallocate every
|
|
||||||
** mutex that it allocates.
|
|
||||||
*/
|
*/
|
||||||
void sqlite3_mutex_free(sqlite3_mutex *pNotUsed){}
|
void sqlite3_mutex_free(sqlite3_mutex *pNotUsed){}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The sqlite3_mutex_enter() routine attempts to enter a
|
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
||||||
** mutex. If another thread is already within the mutex,
|
** to enter a mutex. If another thread is already within the mutex,
|
||||||
** sqlite3_mutex_enter() will return SQLITE_BUSY if blockFlag
|
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
||||||
** is zero, or it will block and wait for the other thread to
|
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
||||||
** exit if blockFlag is non-zero. Mutexes are recursive. The
|
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
||||||
** same thread can enter a single mutex multiple times. Each
|
** be entered multiple times by the same thread. In such cases the,
|
||||||
** entrance must be matched with a corresponding exit before
|
** mutex must be exited an equal number of times before another thread
|
||||||
** another thread is able to enter the mutex.
|
** can enter. If the same thread tries to enter any other kind of mutex
|
||||||
|
** more than once, the behavior is undefined.
|
||||||
*/
|
*/
|
||||||
int sqlite3_mutex_enter(sqlite3_mutex *pNotUsed, int blockFlag){
|
void sqlite3_mutex_enter(sqlite3_mutex *pNotUsed){}
|
||||||
return SQLITE_OK;
|
int sqlite3_mutex_try(sqlite3_mutex *pNotUsed){ return SQLITE_OK; }
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The sqlite3_mutex_exit() routine exits a mutex that was
|
** The sqlite3_mutex_exit() routine exits a mutex that was
|
||||||
@@ -80,20 +69,7 @@ int sqlite3_mutex_enter(sqlite3_mutex *pNotUsed, int blockFlag){
|
|||||||
** is undefined if the mutex is not currently entered or
|
** is undefined if the mutex is not currently entered or
|
||||||
** is not currently allocated. SQLite will never do either.
|
** is not currently allocated. SQLite will never do either.
|
||||||
*/
|
*/
|
||||||
void sqlite3_mutex_leave(sqlite3_mutex *pNotUsed){
|
void sqlite3_mutex_leave(sqlite3_mutex *pNotUsed){}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** The sqlite3_mutex_serialize() routine is used to serialize
|
|
||||||
** execution of a subroutine. The subroutine given in the argument
|
|
||||||
** is invoked. But only one thread at a time is allowed to be
|
|
||||||
** running a subroutine using sqlite3_mutex_serialize().
|
|
||||||
*/
|
|
||||||
int sqlite3_mutex_serialize(void (*xCallback)(void*), void *pArg){
|
|
||||||
xCallback(pArg);
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/**************** Non-recursive Pthread Mutex Implementation *****************
|
/**************** Non-recursive Pthread Mutex Implementation *****************
|
||||||
@@ -106,6 +82,7 @@ int sqlite3_mutex_serialize(void (*xCallback)(void*), void *pArg){
|
|||||||
** Each recursive mutex is an instance of the following structure.
|
** Each recursive mutex is an instance of the following structure.
|
||||||
*/
|
*/
|
||||||
struct RMutex {
|
struct RMutex {
|
||||||
|
int recursiveMagic; /* Magic number identifying this as recursive */
|
||||||
int nRef; /* Number of entrances */
|
int nRef; /* Number of entrances */
|
||||||
pthread_mutex_t auxMutex; /* Mutex controlling access to nRef and owner */
|
pthread_mutex_t auxMutex; /* Mutex controlling access to nRef and owner */
|
||||||
pthread_mutex_t mainMutex; /* Mutex controlling the lock */
|
pthread_mutex_t mainMutex; /* Mutex controlling the lock */
|
||||||
@@ -113,98 +90,185 @@ struct RMutex {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Static mutexes
|
** Each fast mutex is an instance of the following structure
|
||||||
*/
|
*/
|
||||||
static struct RMutex rmutexes[] = {
|
struct FMutex {
|
||||||
{ 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, },
|
int fastMagic; /* Identifies this as a fast mutex */
|
||||||
{ 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, },
|
pthread_mutex_t mutex; /* The actual underlying mutex */
|
||||||
{ 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** A mutex used for serialization.
|
** Either of the above
|
||||||
|
*/
|
||||||
|
union AnyMutex {
|
||||||
|
struct RMutex r;
|
||||||
|
struct FMutex f;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Magic numbers
|
||||||
|
*/
|
||||||
|
#define SQLITE_MTX_RECURSIVE 0x4ED886ED
|
||||||
|
#define SQLITE_MTX_STATIC 0x56FCE1B4
|
||||||
|
#define SQLITE_MTX_FAST 0x245BFD4F
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Static mutexes
|
||||||
*/
|
*/
|
||||||
static RMutex serialMutex =
|
|
||||||
{0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, };
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The sqlite3_mutex_alloc() routine allocates a new
|
** The sqlite3_mutex_alloc() routine allocates a new
|
||||||
** mutex and returns a pointer to it. If it returns NULL
|
** mutex and returns a pointer to it. If it returns NULL
|
||||||
** that means that a mutex could not be allocated. SQLite
|
** that means that a mutex could not be allocated. SQLite
|
||||||
** will unwind its stack and return an error. The argument
|
** will unwind its stack and return an error. The argument
|
||||||
** to sqlite3_mutex_alloc() is usually zero, which causes
|
** to sqlite3_mutex_alloc() is one of these integer constants:
|
||||||
** any space required for the mutex to be obtained from
|
**
|
||||||
** sqlite3_malloc(). However if the argument is a positive
|
** <ul>
|
||||||
** integer less than SQLITE_NUM_STATIC_MUTEX, then a pointer
|
** <li> SQLITE_MUTEX_FAST 0
|
||||||
** to a static mutex is returned. There are a finite number
|
** <li> SQLITE_MUTEX_RECURSIVE 1
|
||||||
** of static mutexes. Static mutexes should not be passed
|
** <li> SQLITE_MUTEX_STATIC_MASTER 2
|
||||||
** to sqlite3_mutex_free(). The allocation of a static
|
** <li> SQLITE_MUTEX_STATIC_MEM 3
|
||||||
** mutex cannot fail.
|
** <li> SQLITE_MUTEX_STATIC_PRNG 4
|
||||||
|
** </ul>
|
||||||
|
**
|
||||||
|
** The first two constants cause sqlite3_mutex_alloc() to create
|
||||||
|
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
|
||||||
|
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
|
||||||
|
** The mutex implementation does not need to make a distinction
|
||||||
|
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
|
||||||
|
** not want to. But SQLite will only request a recursive mutex in
|
||||||
|
** cases where it really needs one. If a faster non-recursive mutex
|
||||||
|
** implementation is available on the host platform, the mutex subsystem
|
||||||
|
** might return such a mutex in response to SQLITE_MUTEX_FAST.
|
||||||
|
**
|
||||||
|
** The other allowed parameters to sqlite3_mutex_alloc() each return
|
||||||
|
** a pointer to a static preexisting mutex. Three static mutexes are
|
||||||
|
** used by the current version of SQLite. Future versions of SQLite
|
||||||
|
** may add additional static mutexes. Static mutexes are for internal
|
||||||
|
** use by SQLite only. Applications that use SQLite mutexes should
|
||||||
|
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
|
||||||
|
** SQLITE_MUTEX_RECURSIVE.
|
||||||
|
**
|
||||||
|
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
|
||||||
|
** 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 id){
|
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
|
||||||
struct RMutex *p;
|
static struct FMutex staticMutexes[] = {
|
||||||
if( id>0 ){
|
{ SQLITE_MTX_STATIC, PTHREAD_MUTEX_INITIALIZER },
|
||||||
if( id>sizeof(rmutexes)/sizeof(rmutexes[0]) ){
|
{ SQLITE_MTX_STATIC, PTHREAD_MUTEX_INITIALIZER },
|
||||||
p = 0;
|
{ SQLITE_MTX_STATIC, PTHREAD_MUTEX_INITIALIZER },
|
||||||
}else{
|
};
|
||||||
p = &rmutexes[id-1];
|
sqlite3_mutex *p;
|
||||||
|
switch( iType ){
|
||||||
|
case SQLITE_MUTEX_FAST: {
|
||||||
|
struct FMutex *px = sqlite3_malloc( sizeof(*px) );
|
||||||
|
if( px ){
|
||||||
|
px->fastMagic = SQLITE_MTX_FAST;
|
||||||
|
pthread_mutex_init(&px->mutex, 0);
|
||||||
}
|
}
|
||||||
}else{
|
p = (sqlite3_mutex*)px;
|
||||||
p = sqlite3_malloc( sizeof(*p) );
|
break;
|
||||||
if( p ){
|
}
|
||||||
p->nRef = 0;
|
case SQLITE_MUTEX_RECURSIVE: {
|
||||||
pthread_mutex_init(&p->mutex, 0);
|
struct RMutex *px = sqlite3_malloc( sizeof(*px) );
|
||||||
|
if( px ){
|
||||||
|
px->recursiveMagic = SQLITE_MTX_RECURSIVE;
|
||||||
|
pthread_mutex_init(&px->auxMutex, 0);
|
||||||
|
pthread_mutex_init(&px->mainMutex, 0);
|
||||||
|
px->nRef = 0;
|
||||||
|
}
|
||||||
|
p = (sqlite3_mutex*)px;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
p = &staticMutexes[iType-2];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (sqlite3_mutex*)p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine deallocates a previously
|
** This routine deallocates a previously
|
||||||
** allocated mutex. SQLite is careful to deallocate every
|
** allocated mutex. SQLite is careful to deallocate every
|
||||||
** mutex that it allocates.
|
** mutex that it allocates.
|
||||||
*/
|
*/
|
||||||
void sqlite3_mutex_free(sqlite3_mutex *pMutex){
|
void sqlite3_mutex_free(sqlite3_mutex *pMutex){
|
||||||
struct RMutex *p = (struct RMutex*)pMutex;
|
int iType = *(int*)pMutex;
|
||||||
assert( p->nRef==0 );
|
if( iType==SQLITE_MTX_FAST ){
|
||||||
|
struct FMutex *p = (struct FMutex*)pMutex;
|
||||||
pthread_mutex_destroy(&p->mutex);
|
pthread_mutex_destroy(&p->mutex);
|
||||||
sqlite3_free(p);
|
sqlite3_free(p);
|
||||||
|
}else if( iType==SQLITE_MTX_RECURSIVE ){
|
||||||
|
struct RMutex *p = (struct RMutex*)pMutex;
|
||||||
|
pthread_mutex_destroy(&p->auxMutex);
|
||||||
|
pthread_mutex_destroy(&p->mainMutex);
|
||||||
|
sqlite3_free(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The sqlite3_mutex_enter() routine attempts to enter a
|
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
||||||
** mutex. If another thread is already within the mutex,
|
** to enter a mutex. If another thread is already within the mutex,
|
||||||
** sqlite3_mutex_enter() will return SQLITE_BUSY if blockFlag
|
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
||||||
** is zero, or it will block and wait for the other thread to
|
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
||||||
** exit if blockFlag is non-zero. Mutexes are recursive. The
|
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
||||||
** same thread can enter a single mutex multiple times. Each
|
** be entered multiple times by the same thread. In such cases the,
|
||||||
** entrance must be matched with a corresponding exit before
|
** mutex must be exited an equal number of times before another thread
|
||||||
** another thread is able to enter the mutex.
|
** can enter. If the same thread tries to enter any other kind of mutex
|
||||||
|
** more than once, the behavior is undefined.
|
||||||
*/
|
*/
|
||||||
int sqlite3_mutex_enter(sqlite3_mutex *pMutex, int blockFlag){
|
void sqlite3_mutex_enter(sqlite3_mutex *pMutex){
|
||||||
|
if( SQLITE_MTX_FAST == *(int*)pMutex ){
|
||||||
|
struct FMutex *p = (struct FMutex*)pMutex;
|
||||||
|
pthread_mutex_lock(&p->mutex);
|
||||||
|
}else{
|
||||||
struct RMutex *p = (struct RMutex*)pMutex;
|
struct RMutex *p = (struct RMutex*)pMutex;
|
||||||
while(1){
|
|
||||||
pthread_mutex_lock(&p->auxMutex);
|
pthread_mutex_lock(&p->auxMutex);
|
||||||
if( p->nRef==0 ){
|
if( p->nRef==0 ){
|
||||||
p->nRef++;
|
p->nRef++;
|
||||||
p->owner = pthread_self();
|
p->owner = pthread_self();
|
||||||
pthread_mutex_lock(&p->mainMutex);
|
pthread_mutex_lock(&p->mainMutex);
|
||||||
pthread_mutex_unlock(&p->auxMutex);
|
pthread_mutex_unlock(&p->auxMutex);
|
||||||
return SQLITE_OK;
|
|
||||||
}else if( pthread_equal(p->owner, pthread_self()) ){
|
}else if( pthread_equal(p->owner, pthread_self()) ){
|
||||||
p->nRef++;
|
p->nRef++;
|
||||||
pthread_mutex_unlock(&p->auxMutex);
|
pthread_mutex_unlock(&p->auxMutex);
|
||||||
return SQLITE_OK;
|
|
||||||
}else if( !blockFlag ){
|
|
||||||
pthread_mutex_unlock(&p->auxMutex);
|
|
||||||
return SQLITE_BUSY;
|
|
||||||
}else{
|
}else{
|
||||||
|
while( p->nRef ){
|
||||||
pthread_mutex_unlock(&p->auxMutex);
|
pthread_mutex_unlock(&p->auxMutex);
|
||||||
pthread_mutex_lock(&p->mainMutex);
|
pthread_mutex_lock(&p->mainMutex);
|
||||||
pthread_mutex_unlock(&p->mainMutex);
|
pthread_mutex_unlock(&p->mainMutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
}
|
||||||
|
}
|
||||||
|
int sqlite3_mutex_try(sqlite3_mutex *pMutex){
|
||||||
|
if( SQLITE_MTX_FAST == *(int*)pMutex ){
|
||||||
|
struct FMutex *p = (struct FMutex*)pMutex;
|
||||||
|
if( pthread_mutex_trylock(&p->mutex) ){
|
||||||
|
return SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
struct RMutex *p = (struct RMutex*)pMutex;
|
||||||
|
pthread_mutex_lock(&p->auxMutex);
|
||||||
|
if( p->nRef==0 ){
|
||||||
|
p->nRef++;
|
||||||
|
p->owner = pthread_self();
|
||||||
|
pthread_mutex_lock(&p->mainMutex);
|
||||||
|
pthread_mutex_unlock(&p->auxMutex);
|
||||||
|
}else if( pthread_equal(p->owner, pthread_self()) ){
|
||||||
|
p->nRef++;
|
||||||
|
pthread_mutex_unlock(&p->auxMutex);
|
||||||
|
}else{
|
||||||
|
pthread_mutex_unlock(&p->auxMutex);
|
||||||
|
return SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -214,6 +278,10 @@ int sqlite3_mutex_enter(sqlite3_mutex *pMutex, int blockFlag){
|
|||||||
** is not currently allocated. SQLite will never do either.
|
** is not currently allocated. SQLite will never do either.
|
||||||
*/
|
*/
|
||||||
void sqlite3_mutex_leave(sqlite3_mutex *pMutex){
|
void sqlite3_mutex_leave(sqlite3_mutex *pMutex){
|
||||||
|
if( SQLITE_MTX_FAST == *(int*)pMutex ){
|
||||||
|
struct FMutex *p = (struct FMutex*)pMutex;
|
||||||
|
pthread_mutex_unlock(&p->mutex);
|
||||||
|
}else{
|
||||||
struct RMutex *p = (struct RMutex*)pMutex;
|
struct RMutex *p = (struct RMutex*)pMutex;
|
||||||
pthread_mutex_lock(&p->auxMutex);
|
pthread_mutex_lock(&p->auxMutex);
|
||||||
p->nRef--;
|
p->nRef--;
|
||||||
@@ -221,18 +289,7 @@ void sqlite3_mutex_leave(sqlite3_mutex *pMutex){
|
|||||||
pthread_mutex_unlock(&p->mainMutex);
|
pthread_mutex_unlock(&p->mainMutex);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&p->auxMutex);
|
pthread_mutex_unlock(&p->auxMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** The sqlite3_mutex_serialize() routine is used to serialize
|
|
||||||
** execution of a subroutine. The subroutine given in the argument
|
|
||||||
** is invoked. But only one thread at a time is allowed to be
|
|
||||||
** running a subroutine using sqlite3_mutex_serialize().
|
|
||||||
*/
|
|
||||||
int sqlite3_mutex_serialize(void (*xCallback)(void*), void *pArg){
|
|
||||||
sqlite3_mutex_enter(&serialMutex, 1);
|
|
||||||
xCallback(pArg);
|
|
||||||
sqlite3_mutex_leave(&serialMutex);
|
|
||||||
}
|
}
|
||||||
#endif /* non-recursive pthreads */
|
#endif /* non-recursive pthreads */
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
** the version number) and changes its name to "sqlite3.h" as
|
** the version number) and changes its name to "sqlite3.h" as
|
||||||
** part of the build process.
|
** part of the build process.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqlite.h.in,v 1.225 2007/08/16 13:01:45 drh Exp $
|
** @(#) $Id: sqlite.h.in,v 1.226 2007/08/16 19:40:17 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE3_H_
|
#ifndef _SQLITE3_H_
|
||||||
#define _SQLITE3_H_
|
#define _SQLITE3_H_
|
||||||
@@ -508,6 +508,8 @@ struct sqlite3_io_methods {
|
|||||||
** abstract type for a mutex object. The SQLite core never looks
|
** abstract type for a mutex object. The SQLite core never looks
|
||||||
** at the internal representation of an [sqlite3_mutex]. It only
|
** at the internal representation of an [sqlite3_mutex]. It only
|
||||||
** deals with pointers to the [sqlite3_mutex] object.
|
** deals with pointers to the [sqlite3_mutex] object.
|
||||||
|
**
|
||||||
|
** Mutexes are created using [sqlite3_mutex_alloc()].
|
||||||
*/
|
*/
|
||||||
typedef struct sqlite3_mutex sqlite3_mutex;
|
typedef struct sqlite3_mutex sqlite3_mutex;
|
||||||
|
|
||||||
@@ -519,19 +521,24 @@ typedef struct sqlite3_mutex sqlite3_mutex;
|
|||||||
** in the name of the object stands for "virtual file system".
|
** in the name of the object stands for "virtual file system".
|
||||||
**
|
**
|
||||||
** The iVersion field is initially 1 but may be larger for future
|
** The iVersion field is initially 1 but may be larger for future
|
||||||
** versions. szOsFile is the size of the subclassed sqlite3_file
|
** versions of SQLite. Additional fields may be appended to this
|
||||||
|
** object when the iVersion value is increased.
|
||||||
|
**
|
||||||
|
** The szOsFile field is the size of the subclassed sqlite3_file
|
||||||
** structure used by this VFS. mxPathname is the maximum length of
|
** structure used by this VFS. mxPathname is the maximum length of
|
||||||
** a pathname in this VFS.
|
** a pathname in this VFS.
|
||||||
**
|
**
|
||||||
** The nRef field is incremented and decremented by SQLite to keep
|
** The nRef field is incremented and decremented by SQLite to keep
|
||||||
** count of the number of users of the VFS. This field and
|
** count of the number of users of the VFS. This field and
|
||||||
** vfsMutex, pNext, and pPrev are the only fields in the sqlite3_vfs
|
** vfsMutex, pNext, and pPrev are the only fields in the sqlite3_vfs
|
||||||
** structure that SQLite will ever modify. These fields are modified
|
** structure that SQLite will ever modify. SQLite will only access
|
||||||
** within an sqlite3_mutex_serialize() call so that updates are threadsafe.
|
** or modify these fields while holding a particular static mutex.
|
||||||
|
** The application should never modify any fields of the sqlite3_vfs
|
||||||
|
** object once the object has been registered.
|
||||||
**
|
**
|
||||||
** The sqlite3_vfs.vfsMutex is a mutex used by the OS interface.
|
** The sqlite3_vfs.vfsMutex is a mutex used by the OS interface.
|
||||||
** It should initially be NULL. SQLite will initialize this field
|
** It should initially be NULL. SQLite will initialize this field
|
||||||
** using sqlite3_mutex_allocate() upon first use of the adaptor
|
** using sqlite3_mutex_alloc() upon first use of the adaptor
|
||||||
** by sqlite3_open_v2() and will deallocate the mutex when the
|
** by sqlite3_open_v2() and will deallocate the mutex when the
|
||||||
** last user closes. In other words, vfsMutex will be allocated
|
** last user closes. In other words, vfsMutex will be allocated
|
||||||
** when nRef transitions from 0 to 1 and will be deallocated when
|
** when nRef transitions from 0 to 1 and will be deallocated when
|
||||||
@@ -3190,43 +3197,72 @@ int sqlite3_unregister_vfs(sqlite3_vfs*);
|
|||||||
** mutex and returns a pointer to it. If it returns NULL
|
** mutex and returns a pointer to it. If it returns NULL
|
||||||
** that means that a mutex could not be allocated. SQLite
|
** that means that a mutex could not be allocated. SQLite
|
||||||
** will unwind its stack and return an error. The argument
|
** will unwind its stack and return an error. The argument
|
||||||
** to sqlite3_mutex_alloc() is usually zero, which causes
|
** to sqlite3_mutex_alloc() is one of these integer constants:
|
||||||
** any space required for the mutex to be obtained from
|
**
|
||||||
** sqlite3_malloc(). However if the argument is a positive
|
** <ul>
|
||||||
** integer less than or equal to SQLITE_MUTEX_STATIC_MAX, then a pointer
|
** <li> SQLITE_MUTEX_FAST
|
||||||
** to a static mutex is returned. There are a finite number
|
** <li> SQLITE_MUTEX_RECURSIVE
|
||||||
** of static mutexes. Static mutexes should not be passed
|
** <li> SQLITE_MUTEX_STATIC_MASTER
|
||||||
** to sqlite3_mutex_free(). Static mutexes are used internally
|
** <li> SQLITE_MUTEX_STATIC_MEM
|
||||||
** by the SQLite core and should not be used by the application.
|
** <li> SQLITE_MUTEX_STATIC_PRNG
|
||||||
|
** </ul>
|
||||||
|
**
|
||||||
|
** The first two constants cause sqlite3_mutex_alloc() to create
|
||||||
|
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
|
||||||
|
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
|
||||||
|
** The mutex implementation does not need to make a distinction
|
||||||
|
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
|
||||||
|
** not want to. But SQLite will only request a recursive mutex in
|
||||||
|
** cases where it really needs one. If a faster non-recursive mutex
|
||||||
|
** implementation is available on the host platform, the mutex subsystem
|
||||||
|
** might return such a mutex in response to SQLITE_MUTEX_FAST.
|
||||||
|
**
|
||||||
|
** The other allowed parameters to sqlite3_mutex_alloc() each return
|
||||||
|
** a pointer to a static preexisting mutex. Three static mutexes are
|
||||||
|
** used by the current version of SQLite. Future versions of SQLite
|
||||||
|
** may add additional static mutexes. Static mutexes are for internal
|
||||||
|
** use by SQLite only. Applications that use SQLite mutexes should
|
||||||
|
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
|
||||||
|
** SQLITE_MUTEX_RECURSIVE.
|
||||||
|
**
|
||||||
|
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
|
||||||
|
** 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.
|
||||||
**
|
**
|
||||||
** The sqlite3_mutex_free() routine deallocates a previously
|
** The sqlite3_mutex_free() routine deallocates a previously
|
||||||
** allocated mutex. SQLite is careful to deallocate every
|
** allocated dynamic mutex. SQLite is careful to deallocate every
|
||||||
** mutex that it allocates.
|
** dynamic mutex that it allocates. The dynamic mutexes must not be in
|
||||||
|
** use when they are deallocated. Static mutexes do not need to be
|
||||||
|
** deallocated and SQLite never bothers to do so.
|
||||||
**
|
**
|
||||||
** The sqlite3_mutex_enter() routine attempts to enter a
|
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
||||||
** mutex. If another thread is already within the mutex,
|
** to enter a mutex. If another thread is already within the mutex,
|
||||||
** sqlite3_mutex_enter() will return SQLITE_BUSY if blockFlag
|
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
||||||
** is zero, or it will block and wait for the other thread to
|
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
||||||
** exit if blockFlag is non-zero. Mutexes are recursive. The
|
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
||||||
** same thread can enter a single mutex multiple times. Each
|
** be entered multiple times by the same thread. In such cases the,
|
||||||
** entrance must be matched with a corresponding exit before
|
** mutex must be exited an equal number of times before another thread
|
||||||
** another thread is able to enter the mutex.
|
** can enter. If the same thread tries to enter any other kind of mutex
|
||||||
|
** more than once, the behavior is undefined. SQLite will never exhibit
|
||||||
|
** such behavior in its own use of mutexes.
|
||||||
**
|
**
|
||||||
** The sqlite3_mutex_exit() routine exits a mutex that was
|
** The sqlite3_mutex_exit() routine exits a mutex that was
|
||||||
** previously entered by the same thread. The behavior
|
** previously entered by the same thread. The behavior
|
||||||
** is undefined if the mutex is not currently entered or
|
** is undefined if the mutex is not currently entered or
|
||||||
** is not currently allocated. SQLite will never do either.
|
** is not currently allocated. SQLite will never do either.
|
||||||
**
|
|
||||||
** The sqlite3_mutex_serialize() routine is used to serialize
|
|
||||||
** a subroutine. The subroutine given in the argument is invoked
|
|
||||||
** while holding a static mutex. This ensures that no other
|
|
||||||
** thread is running this same subroutine at the same time.
|
|
||||||
*/
|
*/
|
||||||
sqlite3_mutex *sqlite3_mutex_alloc(int);
|
sqlite3_mutex *sqlite3_mutex_alloc(int);
|
||||||
void sqlite3_mutex_free(sqlite3_mutex*);
|
void sqlite3_mutex_free(sqlite3_mutex*);
|
||||||
int sqlite3_mutex_enter(sqlite3_mutex*, int blockFlag);
|
void sqlite3_mutex_enter(sqlite3_mutex*);
|
||||||
|
int sqlite3_mutex_try(sqlite3_mutex*);
|
||||||
void sqlite3_mutex_leave(sqlite3_mutex*);
|
void sqlite3_mutex_leave(sqlite3_mutex*);
|
||||||
int sqlite3_mutex_serialize(void(*)(void*), void*);
|
#define SQLITE_MUTEX_FAST 0
|
||||||
|
#define SQLITE_MUTEX_RECURSIVE 1
|
||||||
|
#define SQLITE_MUTEX_STATIC_MASTER 2
|
||||||
|
#define SQLITE_MUTEX_STATIC_MEM 3
|
||||||
|
#define SQLITE_MUTEX_STATIC_PRNG 4
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user