aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in14
-rw-r--r--main.mk26
-rw-r--r--manifest22
-rw-r--r--manifest.uuid2
-rw-r--r--src/mutex.c471
-rw-r--r--src/mutex.h82
-rw-r--r--src/mutex_os2.c124
-rw-r--r--src/mutex_unix.c205
-rw-r--r--src/mutex_w32.c181
-rw-r--r--src/sqliteInt.h3
10 files changed, 651 insertions, 479 deletions
diff --git a/Makefile.in b/Makefile.in
index 558e54322..6591af250 100644
--- a/Makefile.in
+++ b/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 \
delete.lo expr.lo func.lo hash.lo journal.lo insert.lo loadext.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 \
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
select.lo table.lo tokenize.lo trigger.lo update.lo \
@@ -159,6 +160,9 @@ SRC = \
$(TOP)/src/mem1.c \
$(TOP)/src/mem2.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_unix.c \
$(TOP)/src/os_win.c \
@@ -253,6 +257,7 @@ HDR = \
$(TOP)/src/btreeInt.h \
$(TOP)/src/hash.h \
$(TOP)/src/sqliteLimit.h \
+ $(TOP)/src/mutex.h \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
@@ -398,6 +403,15 @@ mem2.lo: $(TOP)/src/mem2.c $(HDR)
mutex.lo: $(TOP)/src/mutex.c $(HDR)
$(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
$(LTCOMPILE) -c $(TOP)/src/pager.c
diff --git a/main.mk b/main.mk
index a68433f1f..0b72c9296 100644
--- a/main.mk
+++ b/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 \
callback.o complete.o date.o delete.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 \
pager.o parse.o pragma.o prepare.o printf.o random.o \
select.o table.o tclsqlite.o tokenize.o trigger.o \
@@ -112,6 +113,9 @@ SRC = \
$(TOP)/src/mem1.c \
$(TOP)/src/mem2.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_os2.c \
$(TOP)/src/os_unix.c \
@@ -195,15 +199,10 @@ SRC += \
# Source code to the test files.
#
TESTSRC = \
- $(TOP)/src/btmutex.c \
$(TOP)/src/btree.c \
$(TOP)/src/date.c \
$(TOP)/src/func.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_os2.c \
$(TOP)/src/os_unix.c \
@@ -211,6 +210,7 @@ TESTSRC = \
$(TOP)/src/pager.c \
$(TOP)/src/pragma.c \
$(TOP)/src/printf.c \
+ $(TOP)/src/select.c \
$(TOP)/src/test1.c \
$(TOP)/src/test2.c \
$(TOP)/src/test3.c \
@@ -241,16 +241,17 @@ TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
# Header files used by all library source files.
#
HDR = \
- sqlite3.h \
$(TOP)/src/btree.h \
$(TOP)/src/btreeInt.h \
$(TOP)/src/hash.h \
- $(TOP)/src/sqliteLimit.h \
+ $(TOP)/src/mutex.h \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
+ sqlite3.h \
$(TOP)/src/sqlite3ext.h \
$(TOP)/src/sqliteInt.h \
+ $(TOP)/src/sqliteLimit.h \
$(TOP)/src/vdbe.h \
parse.h
@@ -399,6 +400,15 @@ mem2.o: $(TOP)/src/mem2.c $(HDR)
mutex.o: $(TOP)/src/mutex.c $(HDR)
$(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
$(TCCX) -c $(TOP)/src/pager.c
diff --git a/manifest b/manifest
index 0044f416e..45b9e20fb 100644
--- a/manifest
+++ b/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)
-D 2007-08-28T15:47:45
-F Makefile.in e8296e112b8942a96c0ed504398bd0d43e3c67ce
+C Break\sup\sthe\smutex\simplementation\sinto\sseparate\ssource\sfiles,\sone\neach\sfor\sunix,\sw32,\sand\sos2.\s(CVS\s4312)
+D 2007-08-28T16:34:43
+F Makefile.in bfcc303429a5d9dcd552d807ee016c77427418c3
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F VERSION 6200589421a0dfe968cd39c431fc62277b963540
@@ -63,7 +63,7 @@ F ext/icu/README.txt 3b130aa66e7a681136f6add198b076a2f90d1e33
F ext/icu/icu.c 61a345d8126686aa3487aa8d2d0f68abd655f7a4
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
F ltmain.sh 56abb507100ed2d4261f6dd1653dec3cf4066387
-F main.mk 6b817f36cdfe3c1846cf6bac96afe8f73add5fe5
+F main.mk 6c8e14bbe8c52df32a5468e556df258ef563b4f2
F mkdll.sh 37fa8a7412e51b5ab2bc6d4276135f022a0feffb
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 1a866b53637dab137191341cc875575a5ca110fb
@@ -104,7 +104,11 @@ F src/malloc.c d4282f50964ab1ca31f504c97b7cf2fdb4d4195d
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
F src/mem1.c afe2fbf6d7e8247c6c9f69c1481358b1cad60c08
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.h 2bfbbad126a775e4d8c7d59eb4d9585a5fd7dfb5
F src/os_common.h 98862f120ca6bf7a48ce8b16f158b77d00bc9d2f
@@ -128,7 +132,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
F src/sqlite.h.in 679cfc7927f843cd30a7b7a0fa17173752939a36
F src/sqlite3ext.h 9a26028378c288af500d8b94ed079666fed5806b
-F src/sqliteInt.h e681df44a19ffb6750d129802f124132ae240c83
+F src/sqliteInt.h 8225c78e94177fa4f1052c4cf0f779838bf56c19
F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12
F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
F src/tclsqlite.c d76af53f45c9e9f7f7d39531fa4c7bee7d0adad6
@@ -563,7 +567,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P e7a98b48384ea581d98dad5118ee33468d526c62
-R 79b1204662164ac9dfde3b22f0e8e0d8
+P 5f55b2fc4ecdfc1bb68f479751b8642926fd8833
+R 51f416da38767e7822a0835f98d9ee97
U drh
-Z 512659d0af1bbd911b2ca09d7e649b66
+Z 49f77ee210b93cd481f8532fcc9bb445
diff --git a/manifest.uuid b/manifest.uuid
index db8cce754..771e6f537 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-5f55b2fc4ecdfc1bb68f479751b8642926fd8833 \ No newline at end of file
+fc5cd71aef5ac194f51d73350d773d532020967e \ No newline at end of file
diff --git a/src/mutex.c b/src/mutex.c
index 9e0de085f..bb33656a2 100644
--- a/src/mutex.c
+++ b/src/mutex.c
@@ -9,116 +9,22 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This file contains the C functions that implement mutexes for
-** use by the SQLite core.
+** This file contains the C functions that implement mutexes.
**
-** $Id: mutex.c,v 1.14 2007/08/27 17:27:49 danielk1977 Exp $
-*/
-/*
-** 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.
-*/
-#ifndef SQLITE_MUTEX_APPDEF
-
-
-/* This is the beginning of internal implementation of mutexes
-** for SQLite.
-*/
-#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.
+** 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
+** does do a lot of error checking on mutexes to make sure they
+** are called correctly and at appropriate times. Hence, this
+** implementation is suitable for testing.
+** debugging purposes
**
-** 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.
+** $Id: mutex.c,v 1.15 2007/08/28 16:34:43 drh Exp $
*/
-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 */
+#include "sqliteInt.h"
#ifdef SQLITE_MUTEX_NOOP_DEBUG
-/*************** Error-checking No-op Mutex Implementation *******************
-**
+/*
** In this implementation, mutexes do not provide any mutual exclusion.
** But the error checking is provided. This implementation is useful
** for test purposes.
@@ -218,358 +124,3 @@ int sqlite3_mutex_notheld(sqlite3_mutex *p){
return p==0 || p->cnt==0;
}
#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) */
diff --git a/src/mutex.h b/src/mutex.h
new file mode 100644
index 000000000..d5fa02237
--- /dev/null
+++ b/src/mutex.h
@@ -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 */
diff --git a/src/mutex_os2.c b/src/mutex_os2.c
new file mode 100644
index 000000000..b598f5d90
--- /dev/null
+++ b/src/mutex_os2.c
@@ -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 */
diff --git a/src/mutex_unix.c b/src/mutex_unix.c
new file mode 100644
index 000000000..287a173c5
--- /dev/null
+++ b/src/mutex_unix.c
@@ -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 */
diff --git a/src/mutex_w32.c b/src/mutex_w32.c
new file mode 100644
index 000000000..e0fbe50df
--- /dev/null
+++ b/src/mutex_w32.c
@@ -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 */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index bc0e8aab1..ef69cb639 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** 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_
#define _SQLITEINT_H_
@@ -73,6 +73,7 @@
#include "sqlite3.h"
#include "hash.h"
#include "parse.h"
+#include "mutex.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>