/ Check-in [59728363]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change the mutex interface to be pluggable. This is an incremental checkin, there are still changes to come. (CVS 5227)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 597283637bcdc2398bf249b2bbc6ded47ad2de22
User & Date: danielk1977 2008-06-17 17:21:18
Context
2008-06-17
18:57
Add the SQLITE_CONFIG_MUTEX symbol for use with sqlite3_config(). (CVS 5228) check-in: af1835bb user: danielk1977 tags: trunk
17:21
Change the mutex interface to be pluggable. This is an incremental checkin, there are still changes to come. (CVS 5227) check-in: 59728363 user: danielk1977 tags: trunk
15:12
Add internal interfaces: PageMalloc/PageFree and ScratchMalloc/ScratchFree. (CVS 5226) check-in: 3e797d0f user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/mem2.c.

    15     15   ** to obtain the memory it needs while adding lots of additional debugging
    16     16   ** information to each allocation in order to help detect and fix memory
    17     17   ** leaks and memory usage errors.
    18     18   **
    19     19   ** This file contains implementations of the low-level memory allocation
    20     20   ** routines specified in the sqlite3_mem_methods object.
    21     21   **
    22         -** $Id: mem2.c,v 1.30 2008/06/17 15:12:01 drh Exp $
           22  +** $Id: mem2.c,v 1.31 2008/06/17 17:21:18 danielk1977 Exp $
    23     23   */
    24     24   #include "sqliteInt.h"
    25     25   
    26     26   /*
    27     27   ** This version of the memory allocator is used only if the
    28     28   ** SQLITE_MEMDEBUG macro is defined
    29     29   */
................................................................................
   317    317        0
   318    318     };
   319    319     sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
   320    320   }
   321    321   
   322    322   /*
   323    323   ** Set the number of backtrace levels kept for each allocation.
   324         -** A value of zero turns of backtracing.  The number is always rounded
          324  +** A value of zero turns off backtracing.  The number is always rounded
   325    325   ** up to a multiple of 2.
   326    326   */
   327    327   void sqlite3MemdebugBacktrace(int depth){
   328    328     if( depth<0 ){ depth = 0; }
   329    329     if( depth>20 ){ depth = 20; }
   330    330     depth = (depth+1)&0xfe;
   331    331     mem.nBacktrace = depth;

Changes to src/mutex.c.

    15     15   ** exclusion and is thus suitable for use only in applications
    16     16   ** that use SQLite in a single thread.  But this implementation
    17     17   ** does do a lot of error checking on mutexes to make sure they
    18     18   ** are called correctly and at appropriate times.  Hence, this
    19     19   ** implementation is suitable for testing.
    20     20   ** debugging purposes
    21     21   **
    22         -** $Id: mutex.c,v 1.20 2008/06/15 02:51:48 drh Exp $
           22  +** $Id: mutex.c,v 1.21 2008/06/17 17:21:18 danielk1977 Exp $
    23     23   */
    24     24   #include "sqliteInt.h"
           25  +
           26  +#ifndef SQLITE_MUTEX_NOOP
           27  +/*
           28  +** Initialize the mutex system.
           29  +*/
           30  +int sqlite3_mutex_init(void){ 
           31  +  int rc;
           32  +  if( !sqlite3Config.mutex.xMutexAlloc ){
           33  +    sqlite3_mutex_methods *p = sqlite3DefaultMutex();
           34  +    sqlite3_mutex *pMaster;
           35  +
           36  +    rc = p->xMutexInit();
           37  +    if( rc==SQLITE_OK ){
           38  +      pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
           39  +      p->xMutexEnter(pMaster);
           40  +      assert( sqlite3Config.mutex.xMutexAlloc==0 
           41  +           || sqlite3Config.mutex.xMutexAlloc==p->xMutexAlloc
           42  +      );
           43  +      if( !sqlite3Config.mutex.xMutexAlloc ){
           44  +        sqlite3Config.mutex = *p;
           45  +      }
           46  +      p->xMutexLeave(pMaster);
           47  +    }
           48  +
           49  +  }else{
           50  +    rc = sqlite3Config.mutex.xMutexInit();
           51  +  }
           52  +
           53  +  return rc;
           54  +}
           55  +
           56  +/*
           57  +** Shutdown the mutex system. This call frees resources allocated by
           58  +** sqlite3_mutex_init().
           59  +*/
           60  +int sqlite3_mutex_end(void){
           61  +  int rc = SQLITE_OK;
           62  +  rc = sqlite3Config.mutex.xMutexEnd();
           63  +  return rc;
           64  +}
           65  +
           66  +/*
           67  +** Retrieve a pointer to a static mutex or allocate a new dynamic one.
           68  +*/
           69  +sqlite3_mutex *sqlite3_mutex_alloc(int id){
           70  +  return sqlite3Config.mutex.xMutexAlloc(id);
           71  +}
           72  +
           73  +/*
           74  +** Free a dynamic mutex.
           75  +*/
           76  +void sqlite3_mutex_free(sqlite3_mutex *p){
           77  +  if( p ){
           78  +    sqlite3Config.mutex.xMutexFree(p);
           79  +  }
           80  +}
           81  +
           82  +/*
           83  +** Obtain the mutex p. If some other thread already has the mutex, block
           84  +** until it can be obtained.
           85  +*/
           86  +void sqlite3_mutex_enter(sqlite3_mutex *p){
           87  +  if( p ){
           88  +    sqlite3Config.mutex.xMutexEnter(p);
           89  +  }
           90  +}
           91  +
           92  +/*
           93  +** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
           94  +** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
           95  +*/
           96  +int sqlite3_mutex_try(sqlite3_mutex *p){
           97  +  int rc = SQLITE_OK;
           98  +  if( p ){
           99  +    return sqlite3Config.mutex.xMutexTry(p);
          100  +  }
          101  +  return rc;
          102  +}
          103  +
          104  +/*
          105  +** The sqlite3_mutex_leave() routine exits a mutex that was previously
          106  +** entered by the same thread.  The behavior is undefined if the mutex 
          107  +** is not currently entered. If a NULL pointer is passed as an argument
          108  +** this function is a no-op.
          109  +*/
          110  +void sqlite3_mutex_leave(sqlite3_mutex *p){
          111  +  if( p ){
          112  +    sqlite3Config.mutex.xMutexLeave(p);
          113  +  }
          114  +}
          115  +
          116  +#ifndef NDEBUG
          117  +/*
          118  +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
          119  +** intended for use inside assert() statements.
          120  +*/
          121  +int sqlite3_mutex_held(sqlite3_mutex *p){
          122  +  return p==0 || sqlite3Config.mutex.xMutexHeld(p);
          123  +}
          124  +int sqlite3_mutex_notheld(sqlite3_mutex *p){
          125  +  return p==0 || sqlite3Config.mutex.xMutexNotheld(p);
          126  +}
          127  +#endif
          128  +
          129  +#endif
    25    130   
    26    131   #ifdef SQLITE_MUTEX_NOOP_DEBUG
    27    132   /*
    28    133   ** In this implementation, mutexes do not provide any mutual exclusion.
    29    134   ** But the error checking is provided.  This implementation is useful
    30    135   ** for test purposes.
    31    136   */
................................................................................
    33    138   /*
    34    139   ** The mutex object
    35    140   */
    36    141   struct sqlite3_mutex {
    37    142     int id;     /* The mutex type */
    38    143     int cnt;    /* Number of entries without a matching leave */
    39    144   };
          145  +
          146  +/*
          147  +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
          148  +** intended for use inside assert() statements.
          149  +*/
          150  +static int noopMutexHeld(sqlite3_mutex *p){
          151  +  return p==0 || p->cnt>0;
          152  +}
          153  +static int noopMutexNotheld(sqlite3_mutex *p){
          154  +  return p==0 || p->cnt==0;
          155  +}
    40    156   
    41    157   /*
    42    158   ** Initialize and deinitialize the mutex subsystem.
    43    159   */
    44         -int sqlite3_mutex_init(void){ return SQLITE_OK; }
    45         -int sqlite3_mutex_end(void){ return SQLITE_OK; }
          160  +static int noopMutexInit(void){ return SQLITE_OK; }
          161  +static int noopMutexEnd(void){ return SQLITE_OK; }
    46    162   
    47    163   /*
    48    164   ** The sqlite3_mutex_alloc() routine allocates a new
    49    165   ** mutex and returns a pointer to it.  If it returns NULL
    50    166   ** that means that a mutex could not be allocated. 
    51    167   */
    52         -sqlite3_mutex *sqlite3_mutex_alloc(int id){
          168  +static sqlite3_mutex *noopMutexAlloc(int id){
    53    169     static sqlite3_mutex aStatic[6];
    54    170     sqlite3_mutex *pNew = 0;
    55    171     switch( id ){
    56    172       case SQLITE_MUTEX_FAST:
    57    173       case SQLITE_MUTEX_RECURSIVE: {
    58    174         pNew = sqlite3Malloc(sizeof(*pNew));
    59    175         if( pNew ){
................................................................................
    72    188     }
    73    189     return pNew;
    74    190   }
    75    191   
    76    192   /*
    77    193   ** This routine deallocates a previously allocated mutex.
    78    194   */
    79         -void sqlite3_mutex_free(sqlite3_mutex *p){
    80         -  if( p==0 ) return;
          195  +static void noopMutexFree(sqlite3_mutex *p){
    81    196     assert( p->cnt==0 );
    82    197     assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
    83    198     sqlite3_free(p);
    84    199   }
    85    200   
    86    201   /*
    87    202   ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
................................................................................
    90    205   ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
    91    206   ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
    92    207   ** be entered multiple times by the same thread.  In such cases the,
    93    208   ** mutex must be exited an equal number of times before another thread
    94    209   ** can enter.  If the same thread tries to enter any other kind of mutex
    95    210   ** more than once, the behavior is undefined.
    96    211   */
    97         -void sqlite3_mutex_enter(sqlite3_mutex *p){
    98         -  if( p ){
    99         -    assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
          212  +static void noopMutexEnter(sqlite3_mutex *p){
          213  +  assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
   100    214       p->cnt++;
   101    215     }
   102         -}
   103         -int sqlite3_mutex_try(sqlite3_mutex *p){
   104         -  if( p ){
   105         -    assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
          216  +static int noopMutexTry(sqlite3_mutex *p){
          217  +  assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
   106    218       p->cnt++;
   107         -  }
   108    219     return SQLITE_OK;
   109    220   }
   110    221   
   111    222   /*
   112    223   ** The sqlite3_mutex_leave() routine exits a mutex that was
   113    224   ** previously entered by the same thread.  The behavior
   114    225   ** is undefined if the mutex is not currently entered or
   115    226   ** is not currently allocated.  SQLite will never do either.
   116    227   */
   117         -void sqlite3_mutex_leave(sqlite3_mutex *p){
   118         -  if( p ){
          228  +static void noopMutexLeave(sqlite3_mutex *p){
   119    229       assert( sqlite3_mutex_held(p) );
   120    230       p->cnt--;
   121    231       assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
   122    232     }
   123         -}
          233  +
          234  +sqlite3_mutex_methods *sqlite3DefaultMutex(void){
          235  +  static sqlite3_mutex_methods sMutex = {
          236  +    noopMutexInit,
          237  +    noopMutexAlloc,
          238  +    noopMutexFree,
          239  +    noopMutexEnter,
          240  +    noopMutexTry,
          241  +    noopMutexLeave,
          242  +    noopMutexEnd,
          243  +
          244  +    noopMutexHeld,
          245  +    noopMutexNotheld
          246  +  };
   124    247   
   125         -/*
   126         -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
   127         -** intended for use inside assert() statements.
   128         -*/
   129         -int sqlite3_mutex_held(sqlite3_mutex *p){
   130         -  return p==0 || p->cnt>0;
   131         -}
   132         -int sqlite3_mutex_notheld(sqlite3_mutex *p){
   133         -  return p==0 || p->cnt==0;
          248  +  return &sMutex;
   134    249   }
   135    250   #endif /* SQLITE_MUTEX_NOOP_DEBUG */

Changes to src/mutex_unix.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the C functions that implement mutexes for pthreads
    13     13   **
    14         -** $Id: mutex_unix.c,v 1.8 2008/06/13 18:24:27 drh Exp $
           14  +** $Id: mutex_unix.c,v 1.9 2008/06/17 17:21:18 danielk1977 Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   
    18     18   /*
    19     19   ** The code in this file is only used if we are compiling threadsafe
    20     20   ** under unix with pthreads.
    21     21   **
................................................................................
    41     41   };
    42     42   #ifdef SQLITE_DEBUG
    43     43   #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
    44     44   #else
    45     45   #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0 }
    46     46   #endif
    47     47   
           48  +/*
           49  +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
           50  +** intended for use only inside assert() statements.  On some platforms,
           51  +** there might be race conditions that can cause these routines to
           52  +** deliver incorrect results.  In particular, if pthread_equal() is
           53  +** not an atomic operation, then these routines might delivery
           54  +** incorrect results.  On most platforms, pthread_equal() is a 
           55  +** comparison of two integers and is therefore atomic.  But we are
           56  +** told that HPUX is not such a platform.  If so, then these routines
           57  +** will not always work correctly on HPUX.
           58  +**
           59  +** On those platforms where pthread_equal() is not atomic, SQLite
           60  +** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
           61  +** make sure no assert() statements are evaluated and hence these
           62  +** routines are never called.
           63  +*/
           64  +#ifndef NDEBUG
           65  +static int pthreadMutexHeld(sqlite3_mutex *p){
           66  +  return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
           67  +}
           68  +static int pthreadMutexNotheld(sqlite3_mutex *p){
           69  +  return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
           70  +}
           71  +#endif
           72  +
    48     73   /*
    49     74   ** Initialize and deinitialize the mutex subsystem.
    50     75   */
    51         -int sqlite3_mutex_init(void){ return SQLITE_OK; }
    52         -int sqlite3_mutex_end(void){ return SQLITE_OK; }
           76  +static int pthreadMutexInit(void){ return SQLITE_OK; }
           77  +static int pthreadMutexEnd(void){ return SQLITE_OK; }
    53     78   
    54     79   /*
    55     80   ** The sqlite3_mutex_alloc() routine allocates a new
    56     81   ** mutex and returns a pointer to it.  If it returns NULL
    57     82   ** that means that a mutex could not be allocated.  SQLite
    58     83   ** will unwind its stack and return an error.  The argument
    59     84   ** to sqlite3_mutex_alloc() is one of these integer constants:
................................................................................
    88    113   **
    89    114   ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
    90    115   ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
    91    116   ** returns a different mutex on every call.  But for the static 
    92    117   ** mutex types, the same mutex is returned on every call that has
    93    118   ** the same type number.
    94    119   */
    95         -sqlite3_mutex *sqlite3_mutex_alloc(int iType){
          120  +static sqlite3_mutex *pthreadMutexAlloc(int iType){
    96    121     static sqlite3_mutex staticMutexes[] = {
    97    122       SQLITE3_MUTEX_INITIALIZER,
    98    123       SQLITE3_MUTEX_INITIALIZER,
    99    124       SQLITE3_MUTEX_INITIALIZER,
   100    125       SQLITE3_MUTEX_INITIALIZER,
   101    126       SQLITE3_MUTEX_INITIALIZER,
   102    127       SQLITE3_MUTEX_INITIALIZER
................................................................................
   143    168   
   144    169   
   145    170   /*
   146    171   ** This routine deallocates a previously
   147    172   ** allocated mutex.  SQLite is careful to deallocate every
   148    173   ** mutex that it allocates.
   149    174   */
   150         -void sqlite3_mutex_free(sqlite3_mutex *p){
   151         -  if( p ){
          175  +static void pthreadMutexFree(sqlite3_mutex *p){
   152    176       assert( p->nRef==0 );
   153    177       assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
   154    178       pthread_mutex_destroy(&p->mutex);
   155    179       sqlite3_free(p);
   156    180     }
   157         -}
   158    181   
   159    182   /*
   160    183   ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
   161    184   ** to enter a mutex.  If another thread is already within the mutex,
   162    185   ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
   163    186   ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
   164    187   ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
   165    188   ** be entered multiple times by the same thread.  In such cases the,
   166    189   ** mutex must be exited an equal number of times before another thread
   167    190   ** can enter.  If the same thread tries to enter any other kind of mutex
   168    191   ** more than once, the behavior is undefined.
   169    192   */
   170         -void sqlite3_mutex_enter(sqlite3_mutex *p){
   171         -  if( p==0 ) return;
   172         -  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
          193  +static void pthreadMutexEnter(sqlite3_mutex *p){
          194  +  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
   173    195   
   174    196   #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   175    197     /* If recursive mutexes are not available, then we have to grow
   176    198     ** our own.  This implementation assumes that pthread_equal()
   177    199     ** is atomic - that it cannot be deceived into thinking self
   178    200     ** and p->owner are equal if p->owner changes between two values
   179    201     ** that are not equal to self while the comparison is taking place.
................................................................................
   203    225   
   204    226   #ifdef SQLITE_DEBUG
   205    227     if( p->trace ){
   206    228       printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   207    229     }
   208    230   #endif
   209    231   }
   210         -int sqlite3_mutex_try(sqlite3_mutex *p){
          232  +static int pthreadMutexTry(sqlite3_mutex *p){
   211    233     int rc;
   212         -  if( p==0 ) return SQLITE_OK;
   213         -  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
          234  +  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
   214    235   
   215    236   #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   216    237     /* If recursive mutexes are not available, then we have to grow
   217    238     ** our own.  This implementation assumes that pthread_equal()
   218    239     ** is atomic - that it cannot be deceived into thinking self
   219    240     ** and p->owner are equal if p->owner changes between two values
   220    241     ** that are not equal to self while the comparison is taking place.
................................................................................
   259    280   
   260    281   /*
   261    282   ** The sqlite3_mutex_leave() routine exits a mutex that was
   262    283   ** previously entered by the same thread.  The behavior
   263    284   ** is undefined if the mutex is not currently entered or
   264    285   ** is not currently allocated.  SQLite will never do either.
   265    286   */
   266         -void sqlite3_mutex_leave(sqlite3_mutex *p){
   267         -  if( p==0 ) return;
          287  +static void pthreadMutexLeave(sqlite3_mutex *p){
   268    288     assert( sqlite3_mutex_held(p) );
   269    289     p->nRef--;
   270    290     assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
   271    291   
   272    292   #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   273    293     if( p->nRef==0 ){
   274    294       pthread_mutex_unlock(&p->mutex);
................................................................................
   280    300   #ifdef SQLITE_DEBUG
   281    301     if( p->trace ){
   282    302       printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   283    303     }
   284    304   #endif
   285    305   }
   286    306   
   287         -/*
   288         -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
   289         -** intended for use only inside assert() statements.  On some platforms,
   290         -** there might be race conditions that can cause these routines to
   291         -** deliver incorrect results.  In particular, if pthread_equal() is
   292         -** not an atomic operation, then these routines might delivery
   293         -** incorrect results.  On most platforms, pthread_equal() is a 
   294         -** comparison of two integers and is therefore atomic.  But we are
   295         -** told that HPUX is not such a platform.  If so, then these routines
   296         -** will not always work correctly on HPUX.
   297         -**
   298         -** On those platforms where pthread_equal() is not atomic, SQLite
   299         -** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
   300         -** make sure no assert() statements are evaluated and hence these
   301         -** routines are never called.
   302         -*/
   303         -#ifndef NDEBUG
   304         -int sqlite3_mutex_held(sqlite3_mutex *p){
   305         -  return p==0 || (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
          307  +sqlite3_mutex_methods *sqlite3DefaultMutex(void){
          308  +  static sqlite3_mutex_methods sMutex = {
          309  +    pthreadMutexInit,
          310  +    pthreadMutexAlloc,
          311  +    pthreadMutexFree,
          312  +    pthreadMutexEnter,
          313  +    pthreadMutexTry,
          314  +    pthreadMutexLeave,
          315  +    pthreadMutexEnd,
          316  +
          317  +    pthreadMutexHeld,
          318  +    pthreadMutexNotheld
          319  +  };
          320  +
          321  +  return &sMutex;
   306    322   }
   307         -int sqlite3_mutex_notheld(sqlite3_mutex *p){
   308         -  return p==0 || p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
   309         -}
   310         -#endif
          323  +
   311    324   #endif /* SQLITE_MUTEX_PTHREAD */

Changes to src/mutex_w32.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the C functions that implement mutexes for win32
    13     13   **
    14         -** $Id: mutex_w32.c,v 1.7 2008/06/13 18:24:27 drh Exp $
           14  +** $Id: mutex_w32.c,v 1.8 2008/06/17 17:21:18 danielk1977 Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   
    18     18   /*
    19     19   ** The code in this file is only used if we are compiling multithreaded
    20     20   ** on a win32 system.
    21     21   */
................................................................................
    53     53         GetVersionEx(&sInfo);
    54     54         osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
    55     55       }
    56     56       return osType==2;
    57     57     }
    58     58   #endif /* OS_WINCE */
    59     59   
           60  +/*
           61  +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
           62  +** intended for use only inside assert() statements.
           63  +*/
           64  +static int winMutexHeld(sqlite3_mutex *p){
           65  +  return p->nRef!=0 && p->owner==GetCurrentThreadId();
           66  +}
           67  +static int winMutexNotheld(sqlite3_mutex *p){
           68  +  return p->nRef==0 || p->owner!=GetCurrentThreadId();
           69  +}
           70  +
    60     71   
    61     72   /*
    62     73   ** Initialize and deinitialize the mutex subsystem.
    63     74   */
    64         -int sqlite3_mutex_init(void){ return SQLITE_OK; }
    65         -int sqlite3_mutex_end(void){ return SQLITE_OK; }
           75  +static int winMutexInit(void){ return SQLITE_OK; }
           76  +static int winMutexEnd(void){ return SQLITE_OK; }
    66     77   
    67     78   /*
    68     79   ** The sqlite3_mutex_alloc() routine allocates a new
    69     80   ** mutex and returns a pointer to it.  If it returns NULL
    70     81   ** that means that a mutex could not be allocated.  SQLite
    71     82   ** will unwind its stack and return an error.  The argument
    72     83   ** to sqlite3_mutex_alloc() is one of these integer constants:
................................................................................
    99    110   **
   100    111   ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
   101    112   ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
   102    113   ** returns a different mutex on every call.  But for the static 
   103    114   ** mutex types, the same mutex is returned on every call that has
   104    115   ** the same type number.
   105    116   */
   106         -sqlite3_mutex *sqlite3_mutex_alloc(int iType){
          117  +static sqlite3_mutex *winMutexAlloc(int iType){
   107    118     sqlite3_mutex *p;
   108    119   
   109    120     switch( iType ){
   110    121       case SQLITE_MUTEX_FAST:
   111    122       case SQLITE_MUTEX_RECURSIVE: {
   112    123         p = sqlite3MallocZero( sizeof(*p) );
   113    124         if( p ){
................................................................................
   143    154   
   144    155   
   145    156   /*
   146    157   ** This routine deallocates a previously
   147    158   ** allocated mutex.  SQLite is careful to deallocate every
   148    159   ** mutex that it allocates.
   149    160   */
   150         -void sqlite3_mutex_free(sqlite3_mutex *p){
          161  +static void winMutexFree(sqlite3_mutex *p){
   151    162     assert( p );
   152    163     assert( p->nRef==0 );
   153    164     assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
   154    165     DeleteCriticalSection(&p->mutex);
   155    166     sqlite3_free(p);
   156    167   }
   157    168   
................................................................................
   162    173   ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
   163    174   ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
   164    175   ** be entered multiple times by the same thread.  In such cases the,
   165    176   ** mutex must be exited an equal number of times before another thread
   166    177   ** can enter.  If the same thread tries to enter any other kind of mutex
   167    178   ** more than once, the behavior is undefined.
   168    179   */
   169         -void sqlite3_mutex_enter(sqlite3_mutex *p){
   170         -  if( p==0 ) return;
   171         -  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
          180  +static void winMutexEnter(sqlite3_mutex *p){
          181  +  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
   172    182     EnterCriticalSection(&p->mutex);
   173    183     p->owner = GetCurrentThreadId(); 
   174    184     p->nRef++;
   175    185   }
   176         -int sqlite3_mutex_try(sqlite3_mutex *p){
          186  +static int winMutexTry(sqlite3_mutex *p){
   177    187     int rc = SQLITE_BUSY;
   178         -  if( p==0 ) return SQLITE_OK;
   179         -  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
          188  +  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
   180    189     /*
   181    190     ** The sqlite3_mutex_try() routine is very rarely used, and when it
   182    191     ** is used it is merely an optimization.  So it is OK for it to always
   183    192     ** fail.  
   184    193     **
   185    194     ** The TryEnterCriticalSection() interface is only available on WinNT.
   186    195     ** And some windows compilers complain if you try to use it without
................................................................................
   200    209   
   201    210   /*
   202    211   ** The sqlite3_mutex_leave() routine exits a mutex that was
   203    212   ** previously entered by the same thread.  The behavior
   204    213   ** is undefined if the mutex is not currently entered or
   205    214   ** is not currently allocated.  SQLite will never do either.
   206    215   */
   207         -void sqlite3_mutex_leave(sqlite3_mutex *p){
   208         -  if( p==0 ) return;
          216  +static void winMutexLeave(sqlite3_mutex *p){
   209    217     assert( p->nRef>0 );
   210    218     assert( p->owner==GetCurrentThreadId() );
   211    219     p->nRef--;
   212    220     assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
   213    221     LeaveCriticalSection(&p->mutex);
   214    222   }
   215    223   
   216         -/*
   217         -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
   218         -** intended for use only inside assert() statements.
   219         -*/
   220         -int sqlite3_mutex_held(sqlite3_mutex *p){
   221         -  return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId());
   222         -}
   223         -int sqlite3_mutex_notheld(sqlite3_mutex *p){
   224         -  return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId();
          224  +sqlite3_mutex_methods *sqlite3DefaultMutex(void){
          225  +  static sqlite3_mutex_methods sMutex = {
          226  +    winMutexInit,
          227  +    winMutexAlloc,
          228  +    winMutexFree,
          229  +    winMutexEnter,
          230  +    winMutexTry,
          231  +    winMutexLeave,
          232  +    winMutexEnd,
          233  +
          234  +    winMutexHeld,
          235  +    winMutexNotheld
          236  +  };
          237  +
          238  +  return &sMutex;
   225    239   }
   226    240   #endif /* SQLITE_MUTEX_W32 */
          241  +

Changes to src/sqlite.h.in.

    26     26   ** on how SQLite interfaces are suppose to operate.
    27     27   **
    28     28   ** The name of this file under configuration management is "sqlite.h.in".
    29     29   ** The makefile makes some minor changes to this file (such as inserting
    30     30   ** the version number) and changes its name to "sqlite3.h" as
    31     31   ** part of the build process.
    32     32   **
    33         -** @(#) $Id: sqlite.h.in,v 1.329 2008/06/17 15:12:01 drh Exp $
           33  +** @(#) $Id: sqlite.h.in,v 1.330 2008/06/17 17:21:18 danielk1977 Exp $
    34     34   */
    35     35   #ifndef _SQLITE3_H_
    36     36   #define _SQLITE3_H_
    37     37   #include <stdarg.h>     /* Needed for the definition of va_list */
    38     38   
    39     39   /*
    40     40   ** Make sure we can call this stuff from C++.
................................................................................
  5779   5779   int sqlite3_mutex_init(void);
  5780   5780   sqlite3_mutex *sqlite3_mutex_alloc(int);
  5781   5781   void sqlite3_mutex_free(sqlite3_mutex*);
  5782   5782   void sqlite3_mutex_enter(sqlite3_mutex*);
  5783   5783   int sqlite3_mutex_try(sqlite3_mutex*);
  5784   5784   void sqlite3_mutex_leave(sqlite3_mutex*);
  5785   5785   int sqlite3_mutex_end(void);
         5786  +
         5787  +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
         5788  +struct sqlite3_mutex_methods {
         5789  +  int (*xMutexInit)(void);
         5790  +  sqlite3_mutex *(*xMutexAlloc)(int);
         5791  +  void (*xMutexFree)(sqlite3_mutex *);
         5792  +  void (*xMutexEnter)(sqlite3_mutex *);
         5793  +  int (*xMutexTry)(sqlite3_mutex *);
         5794  +  void (*xMutexLeave)(sqlite3_mutex *);
         5795  +  int (*xMutexEnd)(void);
         5796  +  int (*xMutexHeld)(sqlite3_mutex *);
         5797  +  int (*xMutexNotheld)(sqlite3_mutex *);
         5798  +};
         5799  +
  5786   5800   
  5787   5801   /*
  5788   5802   ** CAPI3REF: Mutex Verifcation Routines {F17080}
  5789   5803   **
  5790   5804   ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
  5791   5805   ** are intended for use inside assert() statements. {F17081} The SQLite core
  5792   5806   ** never uses these routines except inside an assert() and applications

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.711 2008/06/17 15:12:01 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.712 2008/06/17 17:21:18 danielk1977 Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
  1735   1735   ** Structure containing global configuration data for the SQLite library.
  1736   1736   */
  1737   1737   struct Sqlite3Config {
  1738   1738     int bMemstat;                     /* True to enable memory status */
  1739   1739     int bCoreMutex;                   /* True to enable core mutexing */
  1740   1740     int bFullMutex;                   /* True to enable full mutexing */
  1741   1741     sqlite3_mem_methods m;            /* Low-level memory allocation interface */
         1742  +  sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
  1742   1743     void *pHeap;                      /* Heap storage space */
  1743   1744     sqlite3_int64 nHeap;              /* Size of pHeap[] */
  1744   1745     int mnReq, mxReq;                 /* Min and max memory request sizes */
  1745   1746     int nTemp;                        /* Part of pHeap for temporary allos */
  1746   1747   };
  1747   1748   
  1748   1749   /*
................................................................................
  1792   1793   void *sqlite3DbRealloc(sqlite3 *, void *, int);
  1793   1794   int sqlite3MallocSize(void *);
  1794   1795   void *sqlite3ScratchMalloc(int);
  1795   1796   void sqlite3ScratchFree(void*);
  1796   1797   void *sqlite3PageMalloc(int);
  1797   1798   void sqlite3PageFree(void*);
  1798   1799   void sqlite3MemSetDefault(void);
         1800  +
         1801  +sqlite3_mutex_methods *sqlite3DefaultMutex(void);
  1799   1802   
  1800   1803   int sqlite3IsNaN(double);
  1801   1804   
  1802   1805   char *sqlite3MPrintf(sqlite3*,const char*, ...);
  1803   1806   char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
  1804   1807   #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
  1805   1808     void sqlite3DebugPrintf(const char*, ...);