]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Break up the mutex implementation into separate source files, one
authordrh <drh@noemail.net>
Tue, 28 Aug 2007 16:34:42 +0000 (16:34 +0000)
committerdrh <drh@noemail.net>
Tue, 28 Aug 2007 16:34:42 +0000 (16:34 +0000)
each for unix, w32, and os2. (CVS 4312)

FossilOrigin-Name: fc5cd71aef5ac194f51d73350d773d532020967e

Makefile.in
main.mk
manifest
manifest.uuid
src/mutex.c
src/mutex.h [new file with mode: 0644]
src/mutex_os2.c [new file with mode: 0644]
src/mutex_unix.c [new file with mode: 0644]
src/mutex_w32.c [new file with mode: 0644]
src/sqliteInt.h

index 558e543228f8630e7a1ac7df795b8d7fb1a8704f..6591af250df2b59a25d14980f9bd4aeb3637b2e9 100644 (file)
@@ -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 a68433f1f3d166719721060a83841fcc6c12bb84..0b72c9296b3be85652afc379383515a6b4241b72 100644 (file)
--- 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
 
index 0044f416eb12417ce3ea64911cbc4722b4b9c250..45b9e20fbbbd6b6f8e8b3df7fe0b7bde4fc30c99 100644 (file)
--- 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
index db8cce754b4ebaeaa5f064b8c3c77e29ec75e836..771e6f537c224279d3c18ca2c985e7de3fa98f43 100644 (file)
@@ -1 +1 @@
-5f55b2fc4ecdfc1bb68f479751b8642926fd8833
\ No newline at end of file
+fc5cd71aef5ac194f51d73350d773d532020967e
\ No newline at end of file
index 9e0de085f68b8a4d4c14ebe4c9d78eee932358a3..bb33656a2e7b14a4387cf4a5f44d37a6e25dd08b 100644 (file)
 **    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 (file)
index 0000000..d5fa022
--- /dev/null
@@ -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 (file)
index 0000000..b598f5d
--- /dev/null
@@ -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 (file)
index 0000000..287a173
--- /dev/null
@@ -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 (file)
index 0000000..e0fbe50
--- /dev/null
@@ -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 */
index bc0e8aab108ba804eca0da844bfd90168449bc33..ef69cb639c54ec65167d4e0e7967f9e4cc2603bc 100644 (file)
@@ -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>