mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Break up the mutex implementation into separate source files, one
each for unix, w32, and os2. (CVS 4312) FossilOrigin-Name: fc5cd71aef5ac194f51d73350d773d532020967e
This commit is contained in:
14
Makefile.in
14
Makefile.in
@@ -124,6 +124,7 @@ LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btmutex.lo btree.lo build.lo \
|
|||||||
callback.lo complete.lo date.lo \
|
callback.lo complete.lo date.lo \
|
||||||
delete.lo expr.lo func.lo hash.lo journal.lo insert.lo loadext.lo \
|
delete.lo expr.lo func.lo hash.lo journal.lo insert.lo loadext.lo \
|
||||||
main.lo malloc.lo mem1.lo mem2.lo mutex.lo \
|
main.lo malloc.lo mem1.lo mem2.lo mutex.lo \
|
||||||
|
mutex_os2.lo mutex_unix.lo mutex_w32.lo \
|
||||||
opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
|
opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
|
||||||
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
|
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
|
||||||
select.lo table.lo tokenize.lo trigger.lo update.lo \
|
select.lo table.lo tokenize.lo trigger.lo update.lo \
|
||||||
@@ -159,6 +160,9 @@ SRC = \
|
|||||||
$(TOP)/src/mem1.c \
|
$(TOP)/src/mem1.c \
|
||||||
$(TOP)/src/mem2.c \
|
$(TOP)/src/mem2.c \
|
||||||
$(TOP)/src/mutex.c \
|
$(TOP)/src/mutex.c \
|
||||||
|
$(TOP)/src/mutex_os2.c \
|
||||||
|
$(TOP)/src/mutex_unix.c \
|
||||||
|
$(TOP)/src/mutex_w32.c \
|
||||||
$(TOP)/src/os.c \
|
$(TOP)/src/os.c \
|
||||||
$(TOP)/src/os_unix.c \
|
$(TOP)/src/os_unix.c \
|
||||||
$(TOP)/src/os_win.c \
|
$(TOP)/src/os_win.c \
|
||||||
@@ -253,6 +257,7 @@ HDR = \
|
|||||||
$(TOP)/src/btreeInt.h \
|
$(TOP)/src/btreeInt.h \
|
||||||
$(TOP)/src/hash.h \
|
$(TOP)/src/hash.h \
|
||||||
$(TOP)/src/sqliteLimit.h \
|
$(TOP)/src/sqliteLimit.h \
|
||||||
|
$(TOP)/src/mutex.h \
|
||||||
opcodes.h \
|
opcodes.h \
|
||||||
$(TOP)/src/os.h \
|
$(TOP)/src/os.h \
|
||||||
$(TOP)/src/os_common.h \
|
$(TOP)/src/os_common.h \
|
||||||
@@ -398,6 +403,15 @@ mem2.lo: $(TOP)/src/mem2.c $(HDR)
|
|||||||
mutex.lo: $(TOP)/src/mutex.c $(HDR)
|
mutex.lo: $(TOP)/src/mutex.c $(HDR)
|
||||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c
|
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c
|
||||||
|
|
||||||
|
mutex_os2.lo: $(TOP)/src/mutex_os2.c $(HDR)
|
||||||
|
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_os2.c
|
||||||
|
|
||||||
|
mutex_unix.lo: $(TOP)/src/mutex_unix.c $(HDR)
|
||||||
|
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c
|
||||||
|
|
||||||
|
mutex_w32.lo: $(TOP)/src/mutex_w32.c $(HDR)
|
||||||
|
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c
|
||||||
|
|
||||||
pager.lo: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
|
pager.lo: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
|
||||||
$(LTCOMPILE) -c $(TOP)/src/pager.c
|
$(LTCOMPILE) -c $(TOP)/src/pager.c
|
||||||
|
|
||||||
|
26
main.mk
26
main.mk
@@ -58,7 +58,8 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
|
|||||||
LIBOBJ+= alter.o analyze.o attach.o auth.o btmutex.o btree.o build.o \
|
LIBOBJ+= alter.o analyze.o attach.o auth.o btmutex.o btree.o build.o \
|
||||||
callback.o complete.o date.o delete.o \
|
callback.o complete.o date.o delete.o \
|
||||||
expr.o func.o hash.o insert.o journal.o loadext.o \
|
expr.o func.o hash.o insert.o journal.o loadext.o \
|
||||||
main.o malloc.o mem1.o mem2.o mutex.o \
|
main.o malloc.o mem1.o mem2.o mutex.o mutex_os2.o \
|
||||||
|
mutex_unix.o mutex_w32.o \
|
||||||
opcodes.o os.o os_os2.o os_unix.o os_win.o \
|
opcodes.o os.o os_os2.o os_unix.o os_win.o \
|
||||||
pager.o parse.o pragma.o prepare.o printf.o random.o \
|
pager.o parse.o pragma.o prepare.o printf.o random.o \
|
||||||
select.o table.o tclsqlite.o tokenize.o trigger.o \
|
select.o table.o tclsqlite.o tokenize.o trigger.o \
|
||||||
@@ -112,6 +113,9 @@ SRC = \
|
|||||||
$(TOP)/src/mem1.c \
|
$(TOP)/src/mem1.c \
|
||||||
$(TOP)/src/mem2.c \
|
$(TOP)/src/mem2.c \
|
||||||
$(TOP)/src/mutex.c \
|
$(TOP)/src/mutex.c \
|
||||||
|
$(TOP)/src/mutex_os2.c \
|
||||||
|
$(TOP)/src/mutex_unix.c \
|
||||||
|
$(TOP)/src/mutex_w32.c \
|
||||||
$(TOP)/src/os.c \
|
$(TOP)/src/os.c \
|
||||||
$(TOP)/src/os_os2.c \
|
$(TOP)/src/os_os2.c \
|
||||||
$(TOP)/src/os_unix.c \
|
$(TOP)/src/os_unix.c \
|
||||||
@@ -195,15 +199,10 @@ SRC += \
|
|||||||
# Source code to the test files.
|
# Source code to the test files.
|
||||||
#
|
#
|
||||||
TESTSRC = \
|
TESTSRC = \
|
||||||
$(TOP)/src/btmutex.c \
|
|
||||||
$(TOP)/src/btree.c \
|
$(TOP)/src/btree.c \
|
||||||
$(TOP)/src/date.c \
|
$(TOP)/src/date.c \
|
||||||
$(TOP)/src/func.c \
|
$(TOP)/src/func.c \
|
||||||
$(TOP)/src/insert.c \
|
$(TOP)/src/insert.c \
|
||||||
$(TOP)/src/malloc.c \
|
|
||||||
$(TOP)/src/mem1.c \
|
|
||||||
$(TOP)/src/mem2.c \
|
|
||||||
$(TOP)/src/mutex.c \
|
|
||||||
$(TOP)/src/os.c \
|
$(TOP)/src/os.c \
|
||||||
$(TOP)/src/os_os2.c \
|
$(TOP)/src/os_os2.c \
|
||||||
$(TOP)/src/os_unix.c \
|
$(TOP)/src/os_unix.c \
|
||||||
@@ -211,6 +210,7 @@ TESTSRC = \
|
|||||||
$(TOP)/src/pager.c \
|
$(TOP)/src/pager.c \
|
||||||
$(TOP)/src/pragma.c \
|
$(TOP)/src/pragma.c \
|
||||||
$(TOP)/src/printf.c \
|
$(TOP)/src/printf.c \
|
||||||
|
$(TOP)/src/select.c \
|
||||||
$(TOP)/src/test1.c \
|
$(TOP)/src/test1.c \
|
||||||
$(TOP)/src/test2.c \
|
$(TOP)/src/test2.c \
|
||||||
$(TOP)/src/test3.c \
|
$(TOP)/src/test3.c \
|
||||||
@@ -241,16 +241,17 @@ TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
|
|||||||
# Header files used by all library source files.
|
# Header files used by all library source files.
|
||||||
#
|
#
|
||||||
HDR = \
|
HDR = \
|
||||||
sqlite3.h \
|
|
||||||
$(TOP)/src/btree.h \
|
$(TOP)/src/btree.h \
|
||||||
$(TOP)/src/btreeInt.h \
|
$(TOP)/src/btreeInt.h \
|
||||||
$(TOP)/src/hash.h \
|
$(TOP)/src/hash.h \
|
||||||
$(TOP)/src/sqliteLimit.h \
|
$(TOP)/src/mutex.h \
|
||||||
opcodes.h \
|
opcodes.h \
|
||||||
$(TOP)/src/os.h \
|
$(TOP)/src/os.h \
|
||||||
$(TOP)/src/os_common.h \
|
$(TOP)/src/os_common.h \
|
||||||
|
sqlite3.h \
|
||||||
$(TOP)/src/sqlite3ext.h \
|
$(TOP)/src/sqlite3ext.h \
|
||||||
$(TOP)/src/sqliteInt.h \
|
$(TOP)/src/sqliteInt.h \
|
||||||
|
$(TOP)/src/sqliteLimit.h \
|
||||||
$(TOP)/src/vdbe.h \
|
$(TOP)/src/vdbe.h \
|
||||||
parse.h
|
parse.h
|
||||||
|
|
||||||
@@ -399,6 +400,15 @@ mem2.o: $(TOP)/src/mem2.c $(HDR)
|
|||||||
mutex.o: $(TOP)/src/mutex.c $(HDR)
|
mutex.o: $(TOP)/src/mutex.c $(HDR)
|
||||||
$(TCCX) -c $(TOP)/src/mutex.c
|
$(TCCX) -c $(TOP)/src/mutex.c
|
||||||
|
|
||||||
|
mutex_os2.o: $(TOP)/src/mutex_os2.c $(HDR)
|
||||||
|
$(TCCX) -c $(TOP)/src/mutex_os2.c
|
||||||
|
|
||||||
|
mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR)
|
||||||
|
$(TCCX) -c $(TOP)/src/mutex_unix.c
|
||||||
|
|
||||||
|
mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR)
|
||||||
|
$(TCCX) -c $(TOP)/src/mutex_w32.c
|
||||||
|
|
||||||
pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
|
pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
|
||||||
$(TCCX) -c $(TOP)/src/pager.c
|
$(TCCX) -c $(TOP)/src/pager.c
|
||||||
|
|
||||||
|
22
manifest
22
manifest
@@ -1,6 +1,6 @@
|
|||||||
C Updates\sto\sthe\ssqlite3_open()\sdocumentation.\s\sMethod\sthe\smagic\n:memory:\sfilename.\s\sTicket\s#2591.\s(CVS\s4311)
|
C Break\sup\sthe\smutex\simplementation\sinto\sseparate\ssource\sfiles,\sone\neach\sfor\sunix,\sw32,\sand\sos2.\s(CVS\s4312)
|
||||||
D 2007-08-28T15:47:45
|
D 2007-08-28T16:34:43
|
||||||
F Makefile.in e8296e112b8942a96c0ed504398bd0d43e3c67ce
|
F Makefile.in bfcc303429a5d9dcd552d807ee016c77427418c3
|
||||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
F VERSION 6200589421a0dfe968cd39c431fc62277b963540
|
F VERSION 6200589421a0dfe968cd39c431fc62277b963540
|
||||||
@@ -63,7 +63,7 @@ F ext/icu/README.txt 3b130aa66e7a681136f6add198b076a2f90d1e33
|
|||||||
F ext/icu/icu.c 61a345d8126686aa3487aa8d2d0f68abd655f7a4
|
F ext/icu/icu.c 61a345d8126686aa3487aa8d2d0f68abd655f7a4
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||||
F ltmain.sh 56abb507100ed2d4261f6dd1653dec3cf4066387
|
F ltmain.sh 56abb507100ed2d4261f6dd1653dec3cf4066387
|
||||||
F main.mk 6b817f36cdfe3c1846cf6bac96afe8f73add5fe5
|
F main.mk 6c8e14bbe8c52df32a5468e556df258ef563b4f2
|
||||||
F mkdll.sh 37fa8a7412e51b5ab2bc6d4276135f022a0feffb
|
F mkdll.sh 37fa8a7412e51b5ab2bc6d4276135f022a0feffb
|
||||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||||
F mkextw.sh 1a866b53637dab137191341cc875575a5ca110fb
|
F mkextw.sh 1a866b53637dab137191341cc875575a5ca110fb
|
||||||
@@ -104,7 +104,11 @@ F src/malloc.c d4282f50964ab1ca31f504c97b7cf2fdb4d4195d
|
|||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
F src/mem1.c afe2fbf6d7e8247c6c9f69c1481358b1cad60c08
|
F src/mem1.c afe2fbf6d7e8247c6c9f69c1481358b1cad60c08
|
||||||
F src/mem2.c 1a2ca756a285b5365d667841508cc1f98938b8d8
|
F src/mem2.c 1a2ca756a285b5365d667841508cc1f98938b8d8
|
||||||
F src/mutex.c adbad5e138e8caef8d3763280c75bfe2167812f6
|
F src/mutex.c 40e5ba09d56863895882a0204d93832e9960ea78
|
||||||
|
F src/mutex.h 4d3babe3a691533ac980967d394da512140b5143
|
||||||
|
F src/mutex_os2.c d47e9bd495583dd31263d8fe55160a31eb600a3c
|
||||||
|
F src/mutex_unix.c 84ae0344b0bd6591e3bfea2cb6d375233d39f8a4
|
||||||
|
F src/mutex_w32.c 8716478c5f1829b27fd2c9a0759230a9dc3aa9e3
|
||||||
F src/os.c a8ed3c495161475dbce255f7003144144fb425f1
|
F src/os.c a8ed3c495161475dbce255f7003144144fb425f1
|
||||||
F src/os.h 2bfbbad126a775e4d8c7d59eb4d9585a5fd7dfb5
|
F src/os.h 2bfbbad126a775e4d8c7d59eb4d9585a5fd7dfb5
|
||||||
F src/os_common.h 98862f120ca6bf7a48ce8b16f158b77d00bc9d2f
|
F src/os_common.h 98862f120ca6bf7a48ce8b16f158b77d00bc9d2f
|
||||||
@@ -128,7 +132,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
|||||||
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
||||||
F src/sqlite.h.in 679cfc7927f843cd30a7b7a0fa17173752939a36
|
F src/sqlite.h.in 679cfc7927f843cd30a7b7a0fa17173752939a36
|
||||||
F src/sqlite3ext.h 9a26028378c288af500d8b94ed079666fed5806b
|
F src/sqlite3ext.h 9a26028378c288af500d8b94ed079666fed5806b
|
||||||
F src/sqliteInt.h e681df44a19ffb6750d129802f124132ae240c83
|
F src/sqliteInt.h 8225c78e94177fa4f1052c4cf0f779838bf56c19
|
||||||
F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12
|
F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12
|
||||||
F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
|
F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
|
||||||
F src/tclsqlite.c d76af53f45c9e9f7f7d39531fa4c7bee7d0adad6
|
F src/tclsqlite.c d76af53f45c9e9f7f7d39531fa4c7bee7d0adad6
|
||||||
@@ -563,7 +567,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 e7a98b48384ea581d98dad5118ee33468d526c62
|
P 5f55b2fc4ecdfc1bb68f479751b8642926fd8833
|
||||||
R 79b1204662164ac9dfde3b22f0e8e0d8
|
R 51f416da38767e7822a0835f98d9ee97
|
||||||
U drh
|
U drh
|
||||||
Z 512659d0af1bbd911b2ca09d7e649b66
|
Z 49f77ee210b93cd481f8532fcc9bb445
|
||||||
|
@@ -1 +1 @@
|
|||||||
5f55b2fc4ecdfc1bb68f479751b8642926fd8833
|
fc5cd71aef5ac194f51d73350d773d532020967e
|
471
src/mutex.c
471
src/mutex.c
@@ -9,116 +9,22 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains the C functions that implement mutexes for
|
** This file contains the C functions that implement mutexes.
|
||||||
** use by the SQLite core.
|
|
||||||
**
|
**
|
||||||
** $Id: mutex.c,v 1.14 2007/08/27 17:27:49 danielk1977 Exp $
|
** The implementation in this file does not provide any mutual
|
||||||
*/
|
** exclusion and is thus suitable for use only in applications
|
||||||
/*
|
** that use SQLite in a single thread. But this implementation
|
||||||
** If SQLITE_MUTEX_APPDEF is defined, then this whole module is
|
** does do a lot of error checking on mutexes to make sure they
|
||||||
** omitted and equivalent functionality must be provided by the
|
** are called correctly and at appropriate times. Hence, this
|
||||||
** application that links against the SQLite library.
|
** implementation is suitable for testing.
|
||||||
*/
|
** debugging purposes
|
||||||
#ifndef SQLITE_MUTEX_APPDEF
|
**
|
||||||
|
** $Id: mutex.c,v 1.15 2007/08/28 16:34:43 drh Exp $
|
||||||
|
|
||||||
/* This is the beginning of internal implementation of mutexes
|
|
||||||
** for SQLite.
|
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
/*
|
|
||||||
** Figure out what version of the code to use. The choices are
|
|
||||||
**
|
|
||||||
** SQLITE_MUTEX_NOOP For single-threaded applications that
|
|
||||||
** do not desire error checking.
|
|
||||||
**
|
|
||||||
** SQLITE_MUTEX_NOOP_DEBUG For single-threaded applications with
|
|
||||||
** error checking to help verify that mutexes
|
|
||||||
** are being used correctly even though they
|
|
||||||
** are not needed. Used when SQLITE_DEBUG is
|
|
||||||
** defined on single-threaded builds.
|
|
||||||
**
|
|
||||||
** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix.
|
|
||||||
**
|
|
||||||
** SQLITE_MUTEX_WIN For multi-threaded applications on Win32.
|
|
||||||
*/
|
|
||||||
#define SQLITE_MUTEX_NOOP 1 /* The default */
|
|
||||||
#if defined(SQLITE_DEBUG) && !SQLITE_THREADSAFE
|
|
||||||
# undef SQLITE_MUTEX_NOOP
|
|
||||||
# define SQLITE_MUTEX_NOOP_DEBUG
|
|
||||||
#endif
|
|
||||||
#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_UNIX
|
|
||||||
# undef SQLITE_MUTEX_NOOP
|
|
||||||
# define SQLITE_MUTEX_PTHREAD
|
|
||||||
#endif
|
|
||||||
#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_WIN
|
|
||||||
# undef SQLITE_MUTEX_NOOP
|
|
||||||
# define SQLITE_MUTEX_WIN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SQLITE_MUTEX_NOOP
|
|
||||||
/************************ No-op Mutex Implementation **********************
|
|
||||||
**
|
|
||||||
** This first implementation of mutexes is really a no-op. In other words,
|
|
||||||
** no real locking occurs. This implementation is appropriate for use
|
|
||||||
** in single threaded applications which do not want the extra overhead
|
|
||||||
** of thread locking primitives.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
** 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 idNotUsed){
|
|
||||||
return (sqlite3_mutex*)8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** This routine deallocates a previously allocated mutex.
|
|
||||||
*/
|
|
||||||
void sqlite3_mutex_free(sqlite3_mutex *pNotUsed){}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
|
||||||
** to enter a mutex. If another thread is already within the mutex,
|
|
||||||
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
|
||||||
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
|
||||||
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
|
||||||
** 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 *pNotUsed){}
|
|
||||||
int sqlite3_mutex_try(sqlite3_mutex *pNotUsed){ 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 *pNotUsed){}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
|
|
||||||
** intended for use inside assert() statements.
|
|
||||||
*/
|
|
||||||
int sqlite3_mutex_held(sqlite3_mutex *pNotUsed){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int sqlite3_mutex_notheld(sqlite3_mutex *pNotUsed){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_MUTEX_NOOP */
|
|
||||||
|
|
||||||
#ifdef SQLITE_MUTEX_NOOP_DEBUG
|
#ifdef SQLITE_MUTEX_NOOP_DEBUG
|
||||||
/*************** Error-checking No-op Mutex Implementation *******************
|
/*
|
||||||
**
|
|
||||||
** In this implementation, mutexes do not provide any mutual exclusion.
|
** In this implementation, mutexes do not provide any mutual exclusion.
|
||||||
** But the error checking is provided. This implementation is useful
|
** But the error checking is provided. This implementation is useful
|
||||||
** for test purposes.
|
** for test purposes.
|
||||||
@@ -218,358 +124,3 @@ int sqlite3_mutex_notheld(sqlite3_mutex *p){
|
|||||||
return p==0 || p->cnt==0;
|
return p==0 || p->cnt==0;
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_MUTEX_NOOP_DEBUG */
|
#endif /* SQLITE_MUTEX_NOOP_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SQLITE_MUTEX_PTHREAD
|
|
||||||
/******************** Pthread Mutex Implementation *********************
|
|
||||||
**
|
|
||||||
** This implementation of mutexes is built using a version of pthreads that
|
|
||||||
** has native support for recursive mutexes.
|
|
||||||
*/
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Each recursive mutex is an instance of the following structure.
|
|
||||||
*/
|
|
||||||
struct sqlite3_mutex {
|
|
||||||
pthread_mutex_t mutex; /* Mutex controlling the lock */
|
|
||||||
int id; /* Mutex type */
|
|
||||||
int nRef; /* Number of entrances */
|
|
||||||
pthread_t owner; /* Thread that is within this mutex */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
** 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
|
|
||||||
** will unwind its stack and return an error. The argument
|
|
||||||
** to sqlite3_mutex_alloc() is one of these integer constants:
|
|
||||||
**
|
|
||||||
** <ul>
|
|
||||||
** <li> SQLITE_MUTEX_FAST
|
|
||||||
** <li> SQLITE_MUTEX_RECURSIVE
|
|
||||||
** <li> SQLITE_MUTEX_STATIC_MASTER
|
|
||||||
** <li> SQLITE_MUTEX_STATIC_MEM
|
|
||||||
** <li> SQLITE_MUTEX_STATIC_MEM2
|
|
||||||
** <li> SQLITE_MUTEX_STATIC_PRNG
|
|
||||||
** <li> SQLITE_MUTEX_STATIC_LRU
|
|
||||||
** </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 iType){
|
|
||||||
static sqlite3_mutex staticMutexes[] = {
|
|
||||||
{ PTHREAD_MUTEX_INITIALIZER, },
|
|
||||||
{ PTHREAD_MUTEX_INITIALIZER, },
|
|
||||||
{ PTHREAD_MUTEX_INITIALIZER, },
|
|
||||||
{ PTHREAD_MUTEX_INITIALIZER, },
|
|
||||||
{ PTHREAD_MUTEX_INITIALIZER, },
|
|
||||||
};
|
|
||||||
sqlite3_mutex *p;
|
|
||||||
switch( iType ){
|
|
||||||
case SQLITE_MUTEX_RECURSIVE: {
|
|
||||||
p = sqlite3MallocZero( sizeof(*p) );
|
|
||||||
if( p ){
|
|
||||||
pthread_mutexattr_t recursiveAttr;
|
|
||||||
pthread_mutexattr_init(&recursiveAttr);
|
|
||||||
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
|
|
||||||
pthread_mutex_init(&p->mutex, &recursiveAttr);
|
|
||||||
pthread_mutexattr_destroy(&recursiveAttr);
|
|
||||||
p->id = iType;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SQLITE_MUTEX_FAST: {
|
|
||||||
p = sqlite3MallocZero( sizeof(*p) );
|
|
||||||
if( p ){
|
|
||||||
p->id = iType;
|
|
||||||
pthread_mutex_init(&p->mutex, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
assert( iType-2 >= 0 );
|
|
||||||
assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
|
|
||||||
p = &staticMutexes[iType-2];
|
|
||||||
p->id = iType;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** This routine deallocates a previously
|
|
||||||
** allocated mutex. SQLite is careful to deallocate every
|
|
||||||
** mutex that it allocates.
|
|
||||||
*/
|
|
||||||
void sqlite3_mutex_free(sqlite3_mutex *p){
|
|
||||||
assert( 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,
|
|
||||||
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
|
||||||
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
|
||||||
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
|
||||||
** 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){
|
|
||||||
assert( p );
|
|
||||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
|
||||||
pthread_mutex_lock(&p->mutex);
|
|
||||||
p->owner = pthread_self();
|
|
||||||
p->nRef++;
|
|
||||||
}
|
|
||||||
int sqlite3_mutex_try(sqlite3_mutex *p){
|
|
||||||
int rc;
|
|
||||||
assert( p );
|
|
||||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
|
||||||
if( pthread_mutex_trylock(&p->mutex)==0 ){
|
|
||||||
p->owner = pthread_self();
|
|
||||||
p->nRef++;
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
}else{
|
|
||||||
rc = SQLITE_BUSY;
|
|
||||||
}
|
|
||||||
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 or
|
|
||||||
** is not currently allocated. SQLite will never do either.
|
|
||||||
*/
|
|
||||||
void sqlite3_mutex_leave(sqlite3_mutex *p){
|
|
||||||
assert( p );
|
|
||||||
assert( sqlite3_mutex_held(p) );
|
|
||||||
p->nRef--;
|
|
||||||
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
|
|
||||||
pthread_mutex_unlock(&p->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** 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
|
|
||||||
#endif /* SQLITE_MUTEX_PTHREAD */
|
|
||||||
|
|
||||||
#ifdef SQLITE_MUTEX_WIN
|
|
||||||
/********************** Windows Mutex Implementation **********************
|
|
||||||
**
|
|
||||||
** This implementation of mutexes is built using the win32 API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Each recursive mutex is an instance of the following structure.
|
|
||||||
*/
|
|
||||||
struct sqlite3_mutex {
|
|
||||||
CRITICAL_SECTION mutex; /* Mutex controlling the lock */
|
|
||||||
int id; /* Mutex type */
|
|
||||||
int nRef; /* Number of enterances */
|
|
||||||
DWORD owner; /* Thread holding this mutex */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
** 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
|
|
||||||
** will unwind its stack and return an error. The argument
|
|
||||||
** to sqlite3_mutex_alloc() is one of these integer constants:
|
|
||||||
**
|
|
||||||
** <ul>
|
|
||||||
** <li> SQLITE_MUTEX_FAST 0
|
|
||||||
** <li> SQLITE_MUTEX_RECURSIVE 1
|
|
||||||
** <li> SQLITE_MUTEX_STATIC_MASTER 2
|
|
||||||
** <li> SQLITE_MUTEX_STATIC_MEM 3
|
|
||||||
** <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 iType){
|
|
||||||
sqlite3_mutex *p;
|
|
||||||
|
|
||||||
switch( iType ){
|
|
||||||
case SQLITE_MUTEX_FAST:
|
|
||||||
case SQLITE_MUTEX_RECURSIVE: {
|
|
||||||
p = sqlite3MallocZero( sizeof(*p) );
|
|
||||||
if( p ){
|
|
||||||
p->id = iType;
|
|
||||||
InitializeCriticalSection(&p->mutex);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
static sqlite3_mutex staticMutexes[5];
|
|
||||||
static int isInit = 0;
|
|
||||||
while( !isInit ){
|
|
||||||
static long lock = 0;
|
|
||||||
if( InterlockedIncrement(&lock)==1 ){
|
|
||||||
int i;
|
|
||||||
for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
|
|
||||||
InitializeCriticalSection(&staticMutexes[i].mutex);
|
|
||||||
}
|
|
||||||
isInit = 1;
|
|
||||||
}else{
|
|
||||||
Sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert( iType-2 >= 0 );
|
|
||||||
assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
|
|
||||||
p = &staticMutexes[iType-2];
|
|
||||||
p->id = iType;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** This routine deallocates a previously
|
|
||||||
** allocated mutex. SQLite is careful to deallocate every
|
|
||||||
** mutex that it allocates.
|
|
||||||
*/
|
|
||||||
void sqlite3_mutex_free(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
|
||||||
** to enter a mutex. If another thread is already within the mutex,
|
|
||||||
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
|
||||||
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
|
||||||
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
|
||||||
** 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){
|
|
||||||
assert( p );
|
|
||||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
|
||||||
EnterCriticalSection(&p->mutex);
|
|
||||||
p->owner = GetCurrentThreadId();
|
|
||||||
p->nRef++;
|
|
||||||
}
|
|
||||||
int sqlite3_mutex_try(sqlite3_mutex *p){
|
|
||||||
int rc;
|
|
||||||
assert( p );
|
|
||||||
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
|
||||||
if( TryEnterCriticalSection(&p->mutex) ){
|
|
||||||
p->owner = GetCurrentThreadId();
|
|
||||||
p->nRef++;
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
}else{
|
|
||||||
rc = SQLITE_BUSY;
|
|
||||||
}
|
|
||||||
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 or
|
|
||||||
** is not currently allocated. SQLite will never do either.
|
|
||||||
*/
|
|
||||||
void sqlite3_mutex_leave(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();
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_MUTEX_WIN */
|
|
||||||
|
|
||||||
#endif /* !defined(SQLITE_MUTEX_APPDEF) */
|
|
||||||
|
82
src/mutex.h
Normal file
82
src/mutex.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
** 2007 August 28
|
||||||
|
**
|
||||||
|
** 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 common header for all mutex implementations.
|
||||||
|
** The sqliteInt.h header #includes this file so that it is available
|
||||||
|
** to all source files. We break it out in an effort to keep the code
|
||||||
|
** better organized.
|
||||||
|
**
|
||||||
|
** NOTE: source files should *not* #include this header file directly.
|
||||||
|
** Source files should #include the sqliteInt.h file and let that file
|
||||||
|
** include this one indirectly.
|
||||||
|
**
|
||||||
|
** $Id: mutex.h,v 1.1 2007/08/28 16:34:43 drh Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SQLITE_MUTEX_APPDEF
|
||||||
|
/*
|
||||||
|
** If SQLITE_MUTEX_APPDEF is defined, then this whole module is
|
||||||
|
** omitted and equivalent functionality must be provided by the
|
||||||
|
** application that links against the SQLite library.
|
||||||
|
*/
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
** Figure out what version of the code to use. The choices are
|
||||||
|
**
|
||||||
|
** SQLITE_MUTEX_NOOP For single-threaded applications that
|
||||||
|
** do not desire error checking.
|
||||||
|
**
|
||||||
|
** SQLITE_MUTEX_NOOP_DEBUG For single-threaded applications with
|
||||||
|
** error checking to help verify that mutexes
|
||||||
|
** are being used correctly even though they
|
||||||
|
** are not needed. Used when SQLITE_DEBUG is
|
||||||
|
** defined on single-threaded builds.
|
||||||
|
**
|
||||||
|
** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix.
|
||||||
|
**
|
||||||
|
** SQLITE_MUTEX_WIN For multi-threaded applications on Win32.
|
||||||
|
**
|
||||||
|
** SQLITE_MUTEX_OS2 For multi-threaded applications on OS/2.
|
||||||
|
*/
|
||||||
|
#define SQLITE_MUTEX_NOOP 1 /* The default */
|
||||||
|
#if defined(SQLITE_DEBUG) && !SQLITE_THREADSAFE
|
||||||
|
# undef SQLITE_MUTEX_NOOP
|
||||||
|
# define SQLITE_MUTEX_NOOP_DEBUG
|
||||||
|
#endif
|
||||||
|
#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_UNIX
|
||||||
|
# undef SQLITE_MUTEX_NOOP
|
||||||
|
# define SQLITE_MUTEX_PTHREADS
|
||||||
|
#endif
|
||||||
|
#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_WIN
|
||||||
|
# undef SQLITE_MUTEX_NOOP
|
||||||
|
# define SQLITE_MUTEX_WIN
|
||||||
|
#endif
|
||||||
|
#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_OS2
|
||||||
|
# undef SQLITE_MUTEX_NOOP
|
||||||
|
# define SQLITE_MUTEX_OS2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SQLITE_MUTEX_NOOP
|
||||||
|
/*
|
||||||
|
** If this is a no-op implementation, implement everything as macros.
|
||||||
|
*/
|
||||||
|
#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
|
||||||
|
#define sqlite3_mutex_free(X)
|
||||||
|
#define sqlite3_mutex_enter(X)
|
||||||
|
#define sqlite3_mutex_try(X) SQLITE_OK
|
||||||
|
#define sqlite3_mutex_leave(X)
|
||||||
|
#define sqlite3_mutex_held(X) 1
|
||||||
|
#define sqlite3_mutex_notheld(X) 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SQLITE_MUTEX_APPDEF */
|
124
src/mutex_os2.c
Normal file
124
src/mutex_os2.c
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
** 2007 August 28
|
||||||
|
**
|
||||||
|
** 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 for OS/2
|
||||||
|
**
|
||||||
|
** $Id: mutex_os2.c,v 1.1 2007/08/28 16:34:43 drh Exp $
|
||||||
|
*/
|
||||||
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
|
||||||
|
** See the mutex.h file for details.
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_MUTEX_OS2
|
||||||
|
|
||||||
|
/**** FIX ME:
|
||||||
|
***** This is currently a no-op implementation suitable for use
|
||||||
|
***** in single-threaded applications only. Somebody please replace
|
||||||
|
***** this with a real mutex implementation for OS/2.
|
||||||
|
****/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The mutex object
|
||||||
|
*/
|
||||||
|
struct sqlite3_mutex {
|
||||||
|
int id; /* The mutex type */
|
||||||
|
int cnt; /* Number of entries without a matching leave */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 aStatic[4];
|
||||||
|
sqlite3_mutex *pNew = 0;
|
||||||
|
switch( id ){
|
||||||
|
case SQLITE_MUTEX_FAST:
|
||||||
|
case SQLITE_MUTEX_RECURSIVE: {
|
||||||
|
pNew = sqlite3_malloc(sizeof(*pNew));
|
||||||
|
if( pNew ){
|
||||||
|
pNew->id = id;
|
||||||
|
pNew->cnt = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert( id-2 >= 0 );
|
||||||
|
assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
|
||||||
|
pNew = &aStatic[id-2];
|
||||||
|
pNew->id = id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This routine deallocates a previously allocated mutex.
|
||||||
|
*/
|
||||||
|
void sqlite3_mutex_free(sqlite3_mutex *p){
|
||||||
|
assert( p );
|
||||||
|
assert( p->cnt==0 );
|
||||||
|
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||||
|
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,
|
||||||
|
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
||||||
|
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
||||||
|
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
||||||
|
** 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){
|
||||||
|
assert( p );
|
||||||
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
|
p->cnt++;
|
||||||
|
}
|
||||||
|
int sqlite3_mutex_try(sqlite3_mutex *p){
|
||||||
|
assert( p );
|
||||||
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(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){
|
||||||
|
assert( 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;
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_MUTEX_OS2 */
|
205
src/mutex_unix.c
Normal file
205
src/mutex_unix.c
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
** 2007 August 28
|
||||||
|
**
|
||||||
|
** 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 for pthreads
|
||||||
|
**
|
||||||
|
** $Id: mutex_unix.c,v 1.1 2007/08/28 16:34:43 drh Exp $
|
||||||
|
*/
|
||||||
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The code in this file is only used if we are compiling threadsafe
|
||||||
|
** under unix with pthreads.
|
||||||
|
**
|
||||||
|
** Note that this implementation requires a version of pthreads that
|
||||||
|
** supports recursive mutexes.
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_MUTEX_PTHREADS
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Each recursive mutex is an instance of the following structure.
|
||||||
|
*/
|
||||||
|
struct sqlite3_mutex {
|
||||||
|
pthread_mutex_t mutex; /* Mutex controlling the lock */
|
||||||
|
int id; /* Mutex type */
|
||||||
|
int nRef; /* Number of entrances */
|
||||||
|
pthread_t owner; /* Thread that is within this mutex */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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
|
||||||
|
** will unwind its stack and return an error. The argument
|
||||||
|
** to sqlite3_mutex_alloc() is one of these integer constants:
|
||||||
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> SQLITE_MUTEX_FAST
|
||||||
|
** <li> SQLITE_MUTEX_RECURSIVE
|
||||||
|
** <li> SQLITE_MUTEX_STATIC_MASTER
|
||||||
|
** <li> SQLITE_MUTEX_STATIC_MEM
|
||||||
|
** <li> SQLITE_MUTEX_STATIC_MEM2
|
||||||
|
** <li> SQLITE_MUTEX_STATIC_PRNG
|
||||||
|
** <li> SQLITE_MUTEX_STATIC_LRU
|
||||||
|
** </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 iType){
|
||||||
|
static sqlite3_mutex staticMutexes[] = {
|
||||||
|
{ PTHREAD_MUTEX_INITIALIZER, },
|
||||||
|
{ PTHREAD_MUTEX_INITIALIZER, },
|
||||||
|
{ PTHREAD_MUTEX_INITIALIZER, },
|
||||||
|
{ PTHREAD_MUTEX_INITIALIZER, },
|
||||||
|
{ PTHREAD_MUTEX_INITIALIZER, },
|
||||||
|
};
|
||||||
|
sqlite3_mutex *p;
|
||||||
|
switch( iType ){
|
||||||
|
case SQLITE_MUTEX_RECURSIVE: {
|
||||||
|
p = sqlite3MallocZero( sizeof(*p) );
|
||||||
|
if( p ){
|
||||||
|
pthread_mutexattr_t recursiveAttr;
|
||||||
|
pthread_mutexattr_init(&recursiveAttr);
|
||||||
|
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
pthread_mutex_init(&p->mutex, &recursiveAttr);
|
||||||
|
pthread_mutexattr_destroy(&recursiveAttr);
|
||||||
|
p->id = iType;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SQLITE_MUTEX_FAST: {
|
||||||
|
p = sqlite3MallocZero( sizeof(*p) );
|
||||||
|
if( p ){
|
||||||
|
p->id = iType;
|
||||||
|
pthread_mutex_init(&p->mutex, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert( iType-2 >= 0 );
|
||||||
|
assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
|
||||||
|
p = &staticMutexes[iType-2];
|
||||||
|
p->id = iType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This routine deallocates a previously
|
||||||
|
** allocated mutex. SQLite is careful to deallocate every
|
||||||
|
** mutex that it allocates.
|
||||||
|
*/
|
||||||
|
void sqlite3_mutex_free(sqlite3_mutex *p){
|
||||||
|
assert( 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,
|
||||||
|
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
||||||
|
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
||||||
|
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
||||||
|
** 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){
|
||||||
|
assert( p );
|
||||||
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
|
pthread_mutex_lock(&p->mutex);
|
||||||
|
p->owner = pthread_self();
|
||||||
|
p->nRef++;
|
||||||
|
}
|
||||||
|
int sqlite3_mutex_try(sqlite3_mutex *p){
|
||||||
|
int rc;
|
||||||
|
assert( p );
|
||||||
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
|
if( pthread_mutex_trylock(&p->mutex)==0 ){
|
||||||
|
p->owner = pthread_self();
|
||||||
|
p->nRef++;
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
}else{
|
||||||
|
rc = SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
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 or
|
||||||
|
** is not currently allocated. SQLite will never do either.
|
||||||
|
*/
|
||||||
|
void sqlite3_mutex_leave(sqlite3_mutex *p){
|
||||||
|
assert( p );
|
||||||
|
assert( sqlite3_mutex_held(p) );
|
||||||
|
p->nRef--;
|
||||||
|
assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
|
||||||
|
pthread_mutex_unlock(&p->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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
|
||||||
|
#endif /* SQLITE_MUTEX_PTHREAD */
|
181
src/mutex_w32.c
Normal file
181
src/mutex_w32.c
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
** 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 for win32
|
||||||
|
**
|
||||||
|
** $Id: mutex_w32.c,v 1.1 2007/08/28 16:34:43 drh Exp $
|
||||||
|
*/
|
||||||
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The code in this file is only used if we are compiling multithreaded
|
||||||
|
** on a win32 system.
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_MUTEX_WIN32
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Each recursive mutex is an instance of the following structure.
|
||||||
|
*/
|
||||||
|
struct sqlite3_mutex {
|
||||||
|
CRITICAL_SECTION mutex; /* Mutex controlling the lock */
|
||||||
|
int id; /* Mutex type */
|
||||||
|
int nRef; /* Number of enterances */
|
||||||
|
DWORD owner; /* Thread holding this mutex */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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
|
||||||
|
** will unwind its stack and return an error. The argument
|
||||||
|
** to sqlite3_mutex_alloc() is one of these integer constants:
|
||||||
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> SQLITE_MUTEX_FAST 0
|
||||||
|
** <li> SQLITE_MUTEX_RECURSIVE 1
|
||||||
|
** <li> SQLITE_MUTEX_STATIC_MASTER 2
|
||||||
|
** <li> SQLITE_MUTEX_STATIC_MEM 3
|
||||||
|
** <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 iType){
|
||||||
|
sqlite3_mutex *p;
|
||||||
|
|
||||||
|
switch( iType ){
|
||||||
|
case SQLITE_MUTEX_FAST:
|
||||||
|
case SQLITE_MUTEX_RECURSIVE: {
|
||||||
|
p = sqlite3MallocZero( sizeof(*p) );
|
||||||
|
if( p ){
|
||||||
|
p->id = iType;
|
||||||
|
InitializeCriticalSection(&p->mutex);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
static sqlite3_mutex staticMutexes[5];
|
||||||
|
static int isInit = 0;
|
||||||
|
while( !isInit ){
|
||||||
|
static long lock = 0;
|
||||||
|
if( InterlockedIncrement(&lock)==1 ){
|
||||||
|
int i;
|
||||||
|
for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
|
||||||
|
InitializeCriticalSection(&staticMutexes[i].mutex);
|
||||||
|
}
|
||||||
|
isInit = 1;
|
||||||
|
}else{
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert( iType-2 >= 0 );
|
||||||
|
assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
|
||||||
|
p = &staticMutexes[iType-2];
|
||||||
|
p->id = iType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This routine deallocates a previously
|
||||||
|
** allocated mutex. SQLite is careful to deallocate every
|
||||||
|
** mutex that it allocates.
|
||||||
|
*/
|
||||||
|
void sqlite3_mutex_free(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
||||||
|
** to enter a mutex. If another thread is already within the mutex,
|
||||||
|
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
||||||
|
** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
|
||||||
|
** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
|
||||||
|
** 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){
|
||||||
|
assert( p );
|
||||||
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
|
EnterCriticalSection(&p->mutex);
|
||||||
|
p->owner = GetCurrentThreadId();
|
||||||
|
p->nRef++;
|
||||||
|
}
|
||||||
|
int sqlite3_mutex_try(sqlite3_mutex *p){
|
||||||
|
int rc;
|
||||||
|
assert( p );
|
||||||
|
assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
|
||||||
|
if( TryEnterCriticalSection(&p->mutex) ){
|
||||||
|
p->owner = GetCurrentThreadId();
|
||||||
|
p->nRef++;
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
}else{
|
||||||
|
rc = SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
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 or
|
||||||
|
** is not currently allocated. SQLite will never do either.
|
||||||
|
*/
|
||||||
|
void sqlite3_mutex_leave(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();
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_MUTEX_WIN */
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.603 2007/08/28 02:27:52 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.604 2007/08/28 16:34:43 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -73,6 +73,7 @@
|
|||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
#include "mutex.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
Reference in New Issue
Block a user