/ Check-in [5059644c]
Login

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

Overview
Comment:Implement the 'CONFIG_SINGLETHREAD' and 'CONFIG_MULTITHREAD' configuration modes. (CVS 5234)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5059644c4bc5f6679afd939e0bc26080f42a9918
User & Date: danielk1977 2008-06-18 17:09:10
Context
2008-06-18
17:59
Fix a test case in mutex1.test that was failing when sqlite was compiled with SQLITE_THREADSAFE=0. (CVS 5235) check-in: d1a87c3b user: danielk1977 tags: trunk
17:09
Implement the 'CONFIG_SINGLETHREAD' and 'CONFIG_MULTITHREAD' configuration modes. (CVS 5234) check-in: 5059644c user: danielk1977 tags: trunk
15:34
Make sure aggregate functions can take any number of arguments up to the limit imposed by SQLITE_LIMIT_FUNCTION_ARGS. Ticket #3179. Modify the group_concat() function to take an unlimited number of arguments in order to facilitate testing this behavior. (CVS 5233) check-in: 70c6739f user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     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         -** $Id: btree.c,v 1.465 2008/06/17 15:12:01 drh Exp $
           12  +** $Id: btree.c,v 1.466 2008/06/18 17:09:10 danielk1977 Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** See the header comment on "btreeInt.h" for additional information.
    16     16   ** Including a description of file format and an overview of operation.
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   
................................................................................
  1197   1197           db->flags |= SQLITE_SharedCache;
  1198   1198         }
  1199   1199         if( !zFullPathname ){
  1200   1200           sqlite3_free(p);
  1201   1201           return SQLITE_NOMEM;
  1202   1202         }
  1203   1203         sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
  1204         -      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
         1204  +      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  1205   1205         sqlite3_mutex_enter(mutexShared);
  1206   1206         for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
  1207   1207           assert( pBt->nRef>0 );
  1208   1208           if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
  1209   1209                    && sqlite3PagerVfs(pBt->pPager)==pVfs ){
  1210   1210             p->pBt = pBt;
  1211   1211             pBt->nRef++;
................................................................................
  1294   1294      
  1295   1295   #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  1296   1296       /* Add the new BtShared object to the linked list sharable BtShareds.
  1297   1297       */
  1298   1298       if( p->sharable ){
  1299   1299         sqlite3_mutex *mutexShared;
  1300   1300         pBt->nRef = 1;
  1301         -      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
  1302         -      if( SQLITE_THREADSAFE ){
  1303         -        pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
         1301  +      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
         1302  +      if( SQLITE_THREADSAFE && sqlite3Config.bCoreMutex ){
         1303  +        pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
  1304   1304           if( pBt->mutex==0 ){
  1305   1305             rc = SQLITE_NOMEM;
  1306   1306             db->mallocFailed = 0;
  1307   1307             goto btree_open_out;
  1308   1308           }
  1309   1309         }
  1310   1310         sqlite3_mutex_enter(mutexShared);
................................................................................
  1369   1369   static int removeFromSharingList(BtShared *pBt){
  1370   1370   #ifndef SQLITE_OMIT_SHARED_CACHE
  1371   1371     sqlite3_mutex *pMaster;
  1372   1372     BtShared *pList;
  1373   1373     int removed = 0;
  1374   1374   
  1375   1375     assert( sqlite3_mutex_notheld(pBt->mutex) );
  1376         -  pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
         1376  +  pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  1377   1377     sqlite3_mutex_enter(pMaster);
  1378   1378     pBt->nRef--;
  1379   1379     if( pBt->nRef<=0 ){
  1380   1380       if( sqlite3SharedCacheList==pBt ){
  1381   1381         sqlite3SharedCacheList = pBt->pNext;
  1382   1382       }else{
  1383   1383         pList = sqlite3SharedCacheList;

Changes to src/date.c.

    12     12   ** This file contains the C functions that implement date and time
    13     13   ** functions for SQLite.  
    14     14   **
    15     15   ** There is only one exported symbol in this file - the function
    16     16   ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
    17     17   ** All other code has file scope.
    18     18   **
    19         -** $Id: date.c,v 1.84 2008/06/15 02:51:47 drh Exp $
           19  +** $Id: date.c,v 1.85 2008/06/18 17:09:10 danielk1977 Exp $
    20     20   **
    21     21   ** SQLite processes all times and dates as Julian Day numbers.  The
    22     22   ** dates and times are stored as the number of days since noon
    23     23   ** in Greenwich on November 24, 4714 B.C. according to the Gregorian
    24     24   ** calendar system. 
    25     25   **
    26     26   ** 1970-01-01 00:00:00 is JD 2440587.5
................................................................................
   470    470       y.h = sLocal.tm_hour;
   471    471       y.m = sLocal.tm_min;
   472    472       y.s = sLocal.tm_sec;
   473    473     }
   474    474   #else
   475    475     {
   476    476       struct tm *pTm;
   477         -    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
          477  +    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   478    478       pTm = localtime(&t);
   479    479       y.Y = pTm->tm_year + 1900;
   480    480       y.M = pTm->tm_mon + 1;
   481    481       y.D = pTm->tm_mday;
   482    482       y.h = pTm->tm_hour;
   483    483       y.m = pTm->tm_min;
   484    484       y.s = pTm->tm_sec;
   485         -    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
          485  +    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   486    486     }
   487    487   #endif
   488    488     y.validYMD = 1;
   489    489     y.validHMS = 1;
   490    490     y.validJD = 0;
   491    491     y.validTZ = 0;
   492    492     computeJD(&y);
................................................................................
  1027   1027       struct tm sNow;
  1028   1028       gmtime_r(&t, &sNow);
  1029   1029       strftime(zBuf, 20, zFormat, &sNow);
  1030   1030     }
  1031   1031   #else
  1032   1032     {
  1033   1033       struct tm *pTm;
  1034         -    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
         1034  +    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  1035   1035       pTm = gmtime(&t);
  1036   1036       strftime(zBuf, 20, zFormat, pTm);
  1037         -    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
         1037  +    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
  1038   1038     }
  1039   1039   #endif
  1040   1040   
  1041   1041     sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  1042   1042   }
  1043   1043   #endif
  1044   1044   

Changes to src/loadext.c.

     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 code used to dynamically load extensions into
    13     13   ** the SQLite library.
    14     14   **
    15         -** $Id: loadext.c,v 1.48 2008/06/13 18:24:27 drh Exp $
           15  +** $Id: loadext.c,v 1.49 2008/06/18 17:09:10 danielk1977 Exp $
    16     16   */
    17     17   
    18     18   #ifndef SQLITE_CORE
    19     19     #define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
    20     20   #endif
    21     21   #include "sqlite3ext.h"
    22     22   #include "sqliteInt.h"
................................................................................
   474    474     if( rc ){
   475    475       return rc;
   476    476     }else
   477    477   #endif
   478    478     {
   479    479       int i;
   480    480   #ifndef SQLITE_MUTEX_NOOP
   481         -    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
          481  +    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   482    482   #endif
   483    483       sqlite3_mutex_enter(mutex);
   484    484       for(i=0; i<autoext.nExt; i++){
   485    485         if( autoext.aExt[i]==xInit ) break;
   486    486       }
   487    487       if( i==autoext.nExt ){
   488    488         int nByte = (autoext.nExt+1)*sizeof(autoext.aExt[0]);
................................................................................
   507    507   */
   508    508   void sqlite3_reset_auto_extension(void){
   509    509   #ifndef SQLITE_OMIT_AUTOINIT
   510    510     if( sqlite3_initialize()==SQLITE_OK )
   511    511   #endif
   512    512     {
   513    513   #ifndef SQLITE_MUTEX_NOOP
   514         -    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
          514  +    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   515    515   #endif
   516    516       sqlite3_mutex_enter(mutex);
   517    517       sqlite3_free(autoext.aExt);
   518    518       autoext.aExt = 0;
   519    519       autoext.nExt = 0;
   520    520       sqlite3_mutex_leave(mutex);
   521    521     }
................................................................................
   533    533     if( autoext.nExt==0 ){
   534    534       /* Common case: early out without every having to acquire a mutex */
   535    535       return SQLITE_OK;
   536    536     }
   537    537     for(i=0; go; i++){
   538    538       char *zErrmsg = 0;
   539    539   #ifndef SQLITE_MUTEX_NOOP
   540         -    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
          540  +    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   541    541   #endif
   542    542       sqlite3_mutex_enter(mutex);
   543    543       if( i>=autoext.nExt ){
   544    544         xInit = 0;
   545    545         go = 0;
   546    546       }else{
   547    547         xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.448 2008/06/18 13:27:47 drh Exp $
           17  +** $Id: main.c,v 1.449 2008/06/18 17:09:10 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <ctype.h>
    21     21   
    22     22   #ifdef SQLITE_ENABLE_FTS3
    23     23   # include "fts3.h"
    24     24   #endif
................................................................................
    72     72   ** or for the first call after a call to sqlite3_shutdown.
    73     73   */
    74     74   int sqlite3_initialize(void){
    75     75     int rc;
    76     76     if( sqlite3IsInit ) return SQLITE_OK;
    77     77     rc = sqlite3_mutex_init();
    78     78     if( rc==SQLITE_OK ){
    79         -    sqlite3_mutex *pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
           79  +    sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
    80     80       sqlite3_mutex_enter(pMutex);
    81     81       if( sqlite3IsInit==0 ){
    82     82         sqlite3IsInit = 1;
    83     83         if( rc==SQLITE_OK ) rc = sqlite3MallocInit();
    84     84         if( rc==SQLITE_OK ) rc = sqlite3_os_init();
    85     85         if( rc!=SQLITE_OK ){
    86     86           sqlite3IsInit = 0;
................................................................................
  1204   1204                  SQLITE_OPEN_SUBJOURNAL | 
  1205   1205                  SQLITE_OPEN_MASTER_JOURNAL
  1206   1206                );
  1207   1207   
  1208   1208     /* Allocate the sqlite data structure */
  1209   1209     db = sqlite3MallocZero( sizeof(sqlite3) );
  1210   1210     if( db==0 ) goto opendb_out;
  1211         -  db->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
  1212         -  if( db->mutex==0 ){
  1213         -    sqlite3_free(db);
  1214         -    db = 0;
  1215         -    goto opendb_out;
         1211  +  if( sqlite3Config.bFullMutex ){
         1212  +    db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
         1213  +    if( db->mutex==0 ){
         1214  +      sqlite3_free(db);
         1215  +      db = 0;
         1216  +      goto opendb_out;
         1217  +    }
  1216   1218     }
  1217   1219     sqlite3_mutex_enter(db->mutex);
  1218   1220     db->errMask = 0xff;
  1219   1221     db->priorNewRowid = 0;
  1220   1222     db->nDb = 2;
  1221   1223     db->magic = SQLITE_MAGIC_BUSY;
  1222   1224     db->aDb = db->aDbStatic;
................................................................................
  1359   1361     db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
  1360   1362     sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
  1361   1363                             SQLITE_DEFAULT_LOCKING_MODE);
  1362   1364   #endif
  1363   1365   
  1364   1366   opendb_out:
  1365   1367     if( db ){
  1366         -    assert( db->mutex!=0 );
         1368  +    assert( db->mutex!=0 || sqlite3Config.bFullMutex==0 );
  1367   1369       sqlite3_mutex_leave(db->mutex);
  1368   1370     }
  1369   1371     if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
  1370   1372       sqlite3_close(db);
  1371   1373       db = 0;
  1372   1374     }
  1373   1375     *ppDb = db;

Changes to src/malloc.c.

     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   **
    13     13   ** Memory allocation functions used throughout sqlite.
    14     14   **
    15         -** $Id: malloc.c,v 1.18 2008/06/17 15:12:01 drh Exp $
           15  +** $Id: malloc.c,v 1.19 2008/06/18 17:09:10 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <stdarg.h>
    19     19   #include <ctype.h>
    20     20   
    21     21   /*
    22     22   ** This routine runs when the memory allocator sees that the
................................................................................
    98     98   ** Initialize the memory allocation subsystem.
    99     99   */
   100    100   int sqlite3MallocInit(void){
   101    101     if( sqlite3Config.m.xMalloc==0 ){
   102    102       sqlite3MemSetDefault();
   103    103     }
   104    104     memset(&mem0, 0, sizeof(mem0));
   105         -  if( sqlite3Config.bMemstat && sqlite3Config.bCoreMutex ){
   106         -    mem0.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
          105  +  if( sqlite3Config.bMemstat ){
          106  +    mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
   107    107     }
   108    108     return sqlite3Config.m.xInit(sqlite3Config.m.pAppData);
   109    109   }
   110    110   
   111    111   /*
   112    112   ** Deinitialize the memory allocation subsystem.
   113    113   */

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.31 2008/06/17 17:21:18 danielk1977 Exp $
           22  +** $Id: mem2.c,v 1.32 2008/06/18 17:09:10 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   */
................................................................................
   158    158     return pHdr->iSize;
   159    159   }
   160    160   
   161    161   /*
   162    162   ** Initialize the memory allocation subsystem.
   163    163   */
   164    164   static int sqlite3MemInit(void *NotUsed){
   165         -  mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
          165  +  mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
   166    166     return SQLITE_OK;
   167    167   }
   168    168   
   169    169   /*
   170    170   ** Deinitialize the memory allocation subsystem.
   171    171   */
   172    172   static void sqlite3MemShutdown(void *NotUsed){

Changes to src/mem3.c.

    16     16   ** use of malloc().  All dynamically allocatable memory is
    17     17   ** contained in a static array, mem.aPool[].  The size of this
    18     18   ** fixed memory pool is SQLITE_MEMORY_SIZE bytes.
    19     19   **
    20     20   ** This version of the memory allocation subsystem is used if
    21     21   ** and only if SQLITE_MEMORY_SIZE is defined.
    22     22   **
    23         -** $Id: mem3.c,v 1.13 2008/06/13 18:24:27 drh Exp $
           23  +** $Id: mem3.c,v 1.14 2008/06/18 17:09:10 danielk1977 Exp $
    24     24   */
    25     25   #include "sqliteInt.h"
    26     26   
    27     27   /*
    28     28   ** This version of the memory allocator is used only when 
    29     29   ** SQLITE_MEMORY_SIZE is defined.
    30     30   */
................................................................................
   210    210   ** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
   211    211   **
   212    212   ** Also:  Initialize the memory allocation subsystem the first time
   213    213   ** this routine is called.
   214    214   */
   215    215   static void memsys3Enter(void){
   216    216     if( mem.mutex==0 ){
   217         -    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
          217  +    mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
   218    218       mem.aPool[0].u.hdr.size4x = SQLITE_MEMORY_SIZE/2 + 2;
   219    219       mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.prevSize = SQLITE_MEMORY_SIZE/8;
   220    220       mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.size4x = 1;
   221    221       mem.iMaster = 1;
   222    222       mem.szMaster = SQLITE_MEMORY_SIZE/8;
   223    223       mem.mnMaster = mem.szMaster;
   224    224     }

Changes to src/mem4.c.

     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 a memory
    13     13   ** allocation subsystem for use by SQLite.  
    14     14   **
    15         -** $Id: mem4.c,v 1.2 2008/02/14 23:26:56 drh Exp $
           15  +** $Id: mem4.c,v 1.3 2008/06/18 17:09:10 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** This version of the memory allocator attempts to obtain memory
    21     21   ** from mmap() if the size of the allocation is close to the size
    22     22   ** of a virtual memory page.  If the size of the allocation is different
................................................................................
   108    108   
   109    109   /*
   110    110   ** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
   111    111   ** The mmap() region is initialized the first time this routine is called.
   112    112   */
   113    113   static void memsys4Enter(void){
   114    114     if( mem.mutex==0 ){
   115         -    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
          115  +    mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
   116    116     }
   117    117     sqlite3_mutex_enter(mem.mutex);
   118    118   }
   119    119   
   120    120   /*
   121    121   ** Attempt to free memory to the mmap heap.  This only works if
   122    122   ** the pointer p is within the range of memory addresses that

Changes to src/mem5.c.

    16     16   ** use of malloc().  All dynamically allocatable memory is
    17     17   ** contained in a static array, mem.aPool[].  The size of this
    18     18   ** fixed memory pool is SQLITE_POW2_MEMORY_SIZE bytes.
    19     19   **
    20     20   ** This version of the memory allocation subsystem is used if
    21     21   ** and only if SQLITE_POW2_MEMORY_SIZE is defined.
    22     22   **
    23         -** $Id: mem5.c,v 1.5 2008/06/13 18:24:27 drh Exp $
           23  +** $Id: mem5.c,v 1.6 2008/06/18 17:09:10 danielk1977 Exp $
    24     24   */
    25     25   #include "sqliteInt.h"
    26     26   
    27     27   /*
    28     28   ** This version of the memory allocator is used only when 
    29     29   ** SQLITE_POW2_MEMORY_SIZE is defined.
    30     30   */
................................................................................
   189    189   */
   190    190   static void memsys5Enter(void){
   191    191     if( mem.mutex==0 ){
   192    192       int i;
   193    193       assert( sizeof(Mem5Block)==POW2_MIN );
   194    194       assert( (SQLITE_POW2_MEMORY_SIZE % POW2_MAX)==0 );
   195    195       assert( SQLITE_POW2_MEMORY_SIZE>=POW2_MAX );
   196         -    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
          196  +    mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
   197    197       sqlite3_mutex_enter(mem.mutex);
   198    198       for(i=0; i<NSIZE; i++) mem.aiFreelist[i] = -1;
   199    199       for(i=0; i<=NBLOCK-SZ_MAX; i += SZ_MAX){
   200    200         mem.aCtrl[i] = (NSIZE-1) | CTRL_FREE;
   201    201         memsys5Link(i, NSIZE-1);
   202    202       }
   203    203     }else{

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.23 2008/06/18 09:45:56 danielk1977 Exp $
           22  +** $Id: mutex.c,v 1.24 2008/06/18 17:09:10 danielk1977 Exp $
    23     23   */
    24     24   #include "sqliteInt.h"
    25     25   
    26     26   #ifndef SQLITE_MUTEX_NOOP
    27     27   /*
    28     28   ** Initialize the mutex system.
    29     29   */
    30     30   int sqlite3_mutex_init(void){ 
    31         -  int rc;
    32         -  if( !sqlite3Config.mutex.xMutexAlloc ){
    33         -    /* If the xMutexAlloc method has not been set, then the user did not
    34         -    ** install a mutex implementation via sqlite3_config() prior to 
    35         -    ** sqlite3_initialize() being called. This block copies pointers to
    36         -    ** the default implementation into the sqlite3Config structure.
    37         -    **
    38         -    ** The danger is that although sqlite3_config() is not a threadsafe
    39         -    ** API, sqlite3_initialize() is, and so multiple threads may be
    40         -    ** attempting to run this function simultaneously. To guard write
    41         -    ** access to the sqlite3Config structure, the 'MASTER' static mutex
    42         -    ** is obtained before modifying it.
    43         -    */
    44         -    sqlite3_mutex_methods *p = sqlite3DefaultMutex();
    45         -    sqlite3_mutex *pMaster;
    46         -
    47         -    rc = p->xMutexInit();
    48         -    if( rc==SQLITE_OK ){
    49         -      pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
    50         -      assert(pMaster);
    51         -      p->xMutexEnter(pMaster);
    52         -      assert( sqlite3Config.mutex.xMutexAlloc==0 
    53         -           || sqlite3Config.mutex.xMutexAlloc==p->xMutexAlloc
    54         -      );
    55         -      if( !sqlite3Config.mutex.xMutexAlloc ){
    56         -        sqlite3Config.mutex = *p;
           31  +  int rc = SQLITE_OK;
           32  +  if( sqlite3Config.bCoreMutex ){
           33  +    if( !sqlite3Config.mutex.xMutexAlloc ){
           34  +      /* If the xMutexAlloc method has not been set, then the user did not
           35  +      ** install a mutex implementation via sqlite3_config() prior to 
           36  +      ** sqlite3_initialize() being called. This block copies pointers to
           37  +      ** the default implementation into the sqlite3Config structure.
           38  +      **
           39  +      ** The danger is that although sqlite3_config() is not a threadsafe
           40  +      ** API, sqlite3_initialize() is, and so multiple threads may be
           41  +      ** attempting to run this function simultaneously. To guard write
           42  +      ** access to the sqlite3Config structure, the 'MASTER' static mutex
           43  +      ** is obtained before modifying it.
           44  +      */
           45  +      sqlite3_mutex_methods *p = sqlite3DefaultMutex();
           46  +      sqlite3_mutex *pMaster = 0;
           47  +  
           48  +      rc = p->xMutexInit();
           49  +      if( rc==SQLITE_OK ){
           50  +        pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
           51  +        assert(pMaster);
           52  +        p->xMutexEnter(pMaster);
           53  +        assert( sqlite3Config.mutex.xMutexAlloc==0 
           54  +             || sqlite3Config.mutex.xMutexAlloc==p->xMutexAlloc
           55  +        );
           56  +        if( !sqlite3Config.mutex.xMutexAlloc ){
           57  +          sqlite3Config.mutex = *p;
           58  +        }
           59  +        p->xMutexLeave(pMaster);
    57     60         }
    58         -      p->xMutexLeave(pMaster);
           61  +    }else{
           62  +      rc = sqlite3Config.mutex.xMutexInit();
    59     63       }
    60         -  }else{
    61         -    rc = sqlite3Config.mutex.xMutexInit();
    62     64     }
    63     65   
    64     66     return rc;
    65     67   }
    66     68   
    67     69   /*
    68     70   ** Shutdown the mutex system. This call frees resources allocated by
................................................................................
    76     78   
    77     79   /*
    78     80   ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
    79     81   */
    80     82   sqlite3_mutex *sqlite3_mutex_alloc(int id){
    81     83     return sqlite3Config.mutex.xMutexAlloc(id);
    82     84   }
           85  +
           86  +sqlite3_mutex *sqlite3MutexAlloc(int id){
           87  +  if( !sqlite3Config.bCoreMutex ){
           88  +    return 0;
           89  +  }
           90  +  return sqlite3Config.mutex.xMutexAlloc(id);
           91  +}
    83     92   
    84     93   /*
    85     94   ** Free a dynamic mutex.
    86     95   */
    87     96   void sqlite3_mutex_free(sqlite3_mutex *p){
    88     97     if( p ){
    89     98       sqlite3Config.mutex.xMutexFree(p);

Changes to src/os.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   ******************************************************************************
    12     12   **
    13     13   ** This file contains OS interface code that is common to all
    14     14   ** architectures.
    15     15   **
    16         -** $Id: os.c,v 1.113 2008/06/15 02:51:48 drh Exp $
           16  +** $Id: os.c,v 1.114 2008/06/18 17:09:10 danielk1977 Exp $
    17     17   */
    18     18   #define _SQLITE_OS_C_ 1
    19     19   #include "sqliteInt.h"
    20     20   #undef _SQLITE_OS_C_
    21     21   
    22     22   /*
    23     23   ** The default SQLite sqlite3_vfs implementations do not allocate
................................................................................
   203    203     sqlite3_mutex *mutex;
   204    204   #endif
   205    205   #ifndef SQLITE_OMIT_AUTOINIT
   206    206     int rc = sqlite3_initialize();
   207    207     if( rc ) return 0;
   208    208   #endif
   209    209   #ifndef SQLITE_MUTEX_NOOP
   210         -  mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
          210  +  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   211    211   #endif
   212    212     sqlite3_vfs *pVfs = 0;
   213    213     static int isInit = 0;
   214    214     sqlite3_mutex_enter(mutex);
   215    215     if( !isInit ){
   216    216       vfsList = sqlite3OsDefaultVfs();
   217    217       isInit = 1;
................................................................................
   224    224     return pVfs;
   225    225   }
   226    226   
   227    227   /*
   228    228   ** Unlink a VFS from the linked list
   229    229   */
   230    230   static void vfsUnlink(sqlite3_vfs *pVfs){
   231         -  assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
          231  +  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
   232    232     if( pVfs==0 ){
   233    233       /* No-op */
   234    234     }else if( vfsList==pVfs ){
   235    235       vfsList = pVfs->pNext;
   236    236     }else if( vfsList ){
   237    237       sqlite3_vfs *p = vfsList;
   238    238       while( p->pNext && p->pNext!=pVfs ){
................................................................................
   254    254     sqlite3_mutex *mutex;
   255    255   #endif
   256    256   #ifndef SQLITE_OMIT_AUTOINIT
   257    257     int rc = sqlite3_initialize();
   258    258     if( rc ) return rc;
   259    259   #endif
   260    260   #ifndef SQLITE_MUTEX_NOOP
   261         -  mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
          261  +  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   262    262   #endif
   263    263     sqlite3_vfs_find(0);  /* Make sure we are initialized */
   264    264     sqlite3_mutex_enter(mutex);
   265    265     vfsUnlink(pVfs);
   266    266     if( makeDflt || vfsList==0 ){
   267    267       pVfs->pNext = vfsList;
   268    268       vfsList = pVfs;
................................................................................
   276    276   }
   277    277   
   278    278   /*
   279    279   ** Unregister a VFS so that it is no longer accessible.
   280    280   */
   281    281   int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
   282    282   #ifndef SQLITE_MUTEX_NOOP
   283         -  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
          283  +  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   284    284   #endif
   285    285     sqlite3_mutex_enter(mutex);
   286    286     vfsUnlink(pVfs);
   287    287     sqlite3_mutex_leave(mutex);
   288    288     return SQLITE_OK;
   289    289   }
   290    290   

Changes to src/os_unix.c.

     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   **
    13     13   ** This file contains code that is specific to Unix systems.
    14     14   **
    15         -** $Id: os_unix.c,v 1.187 2008/06/13 18:24:27 drh Exp $
           15  +** $Id: os_unix.c,v 1.188 2008/06/18 17:09:10 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #if OS_UNIX              /* This file is used on unix only */
    19     19   
    20     20   /* #define SQLITE_ENABLE_LOCKING_STYLE 0 */
    21     21   
    22     22   /*
................................................................................
   363    363   } sqlite3LockingStyle;
   364    364   #endif /* SQLITE_ENABLE_LOCKING_STYLE */
   365    365   
   366    366   /*
   367    367   ** Helper functions to obtain and relinquish the global mutex.
   368    368   */
   369    369   static void enterMutex(){
   370         -  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
          370  +  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   371    371   }
   372    372   static void leaveMutex(){
   373         -  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
          373  +  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   374    374   }
   375    375   
   376    376   #if SQLITE_THREADSAFE
   377    377   /*
   378    378   ** This variable records whether or not threads can override each others
   379    379   ** locks.
   380    380   **

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.458 2008/06/17 15:12:01 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.459 2008/06/18 17:09:10 danielk1977 Exp $
    22     22   */
    23     23   #ifndef SQLITE_OMIT_DISKIO
    24     24   #include "sqliteInt.h"
    25     25   #include <assert.h>
    26     26   #include <string.h>
    27     27   
    28     28   /*
................................................................................
   514    514   */
   515    515   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   516    516     static void pagerEnter(Pager *p){
   517    517       p->iInUseDB++;
   518    518       if( p->iInUseMM && p->iInUseDB==1 ){
   519    519   #ifndef SQLITE_MUTEX_NOOP
   520    520         sqlite3_mutex *mutex;
   521         -      mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
          521  +      mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
   522    522   #endif
   523    523         p->iInUseDB = 0;
   524    524         sqlite3_mutex_enter(mutex);
   525    525         p->iInUseDB = 1;
   526    526         sqlite3_mutex_leave(mutex);
   527    527       }
   528    528       assert( p->iInUseMM==0 );
................................................................................
   612    612   ** memory-management is enabled, also add the page to the global 
   613    613   ** list of free pages.
   614    614   */
   615    615   static void lruListAdd(PgHdr *pPg){
   616    616     listAdd(&pPg->pPager->lru, &pPg->free, pPg);
   617    617   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   618    618     if( !pPg->pPager->memDb ){
   619         -    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
          619  +    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   620    620       listAdd(&sqlite3LruPageList, &pPg->gfree, pPg);
   621         -    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
          621  +    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   622    622     }
   623    623   #endif
   624    624   }
   625    625   
   626    626   /* 
   627    627   ** Remove page pPg from the list of free pages for the associated pager.
   628    628   ** If memory-management is enabled, also remove pPg from the global list
   629    629   ** of free pages.
   630    630   */
   631    631   static void lruListRemove(PgHdr *pPg){
   632    632     listRemove(&pPg->pPager->lru, &pPg->free, pPg);
   633    633   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   634    634     if( !pPg->pPager->memDb ){
   635         -    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
          635  +    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   636    636       listRemove(&sqlite3LruPageList, &pPg->gfree, pPg);
   637         -    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
          637  +    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   638    638     }
   639    639   #endif
   640    640   }
   641    641   
   642    642   /* 
   643    643   ** This function is called just after the needSync flag has been cleared
   644    644   ** from all pages managed by pPager (usually because the journal file
................................................................................
   647    647   ** variable also.
   648    648   */
   649    649   static void lruListSetFirstSynced(Pager *pPager){
   650    650     pPager->lru.pFirstSynced = pPager->lru.pFirst;
   651    651   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   652    652     if( !pPager->memDb ){
   653    653       PgHdr *p;
   654         -    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
          654  +    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   655    655       for(p=sqlite3LruPageList.pFirst; p && p->needSync; p=p->gfree.pNext);
   656    656       assert(p==pPager->lru.pFirstSynced || p==sqlite3LruPageList.pFirstSynced);
   657    657       sqlite3LruPageList.pFirstSynced = p;
   658         -    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
          658  +    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   659    659     }
   660    660   #endif
   661    661   }
   662    662   
   663    663   /*
   664    664   ** Return true if page *pPg has already been written to the statement
   665    665   ** journal (or statement snapshot has been created, if *pPg is part
................................................................................
  2360   2360     /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  2361   2361     *ppPager = pPager;
  2362   2362   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  2363   2363     pPager->iInUseMM = 0;
  2364   2364     pPager->iInUseDB = 0;
  2365   2365     if( !memDb ){
  2366   2366   #ifndef SQLITE_MUTEX_NOOP
  2367         -    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
         2367  +    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
  2368   2368   #endif
  2369   2369       sqlite3_mutex_enter(mutex);
  2370   2370       pPager->pNext = sqlite3PagerList;
  2371   2371       if( sqlite3PagerList ){
  2372   2372         assert( sqlite3PagerList->pPrev==0 );
  2373   2373         sqlite3PagerList->pPrev = pPager;
  2374   2374       }
................................................................................
  2747   2747   ** a hot journal may be left in the filesystem but no error is returned
  2748   2748   ** to the caller.
  2749   2749   */
  2750   2750   int sqlite3PagerClose(Pager *pPager){
  2751   2751   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  2752   2752     if( !MEMDB ){
  2753   2753   #ifndef SQLITE_MUTEX_NOOP
  2754         -    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
         2754  +    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
  2755   2755   #endif
  2756   2756       sqlite3_mutex_enter(mutex);
  2757   2757       if( pPager->pPrev ){
  2758   2758         pPager->pPrev->pNext = pPager->pNext;
  2759   2759       }else{
  2760   2760         sqlite3PagerList = pPager->pNext;
  2761   2761       }
................................................................................
  3274   3274     BusyHandler *savedBusy;     /* Saved copy of the busy handler */
  3275   3275     int rc = SQLITE_OK;
  3276   3276   
  3277   3277     /* Acquire the memory-management mutex
  3278   3278     */
  3279   3279   #ifndef SQLITE_MUTEX_NOOP
  3280   3280     sqlite3_mutex *mutex;       /* The MEM2 mutex */
  3281         -  mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
         3281  +  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
  3282   3282   #endif
  3283   3283     sqlite3_mutex_enter(mutex);
  3284   3284   
  3285   3285     /* Signal all database connections that memory management wants
  3286   3286     ** to have access to the pagers.
  3287   3287     */
  3288   3288     for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){
................................................................................
  3292   3292     while( rc==SQLITE_OK && (nReq<0 || nReleased<nReq) ){
  3293   3293       PgHdr *pPg;
  3294   3294       PgHdr *pRecycled;
  3295   3295    
  3296   3296       /* Try to find a page to recycle that does not require a sync(). If
  3297   3297       ** this is not possible, find one that does require a sync().
  3298   3298       */
  3299         -    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
         3299  +    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
  3300   3300       pPg = sqlite3LruPageList.pFirstSynced;
  3301   3301       while( pPg && (pPg->needSync || pPg->pPager->iInUseDB) ){
  3302   3302         pPg = pPg->gfree.pNext;
  3303   3303       }
  3304   3304       if( !pPg ){
  3305   3305         pPg = sqlite3LruPageList.pFirst;
  3306   3306         while( pPg && pPg->pPager->iInUseDB ){
  3307   3307           pPg = pPg->gfree.pNext;
  3308   3308         }
  3309   3309       }
  3310         -    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
         3310  +    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
  3311   3311   
  3312   3312       /* If pPg==0, then the block above has failed to find a page to
  3313   3313       ** recycle. In this case return early - no further memory will
  3314   3314       ** be released.
  3315   3315       */
  3316   3316       if( !pPg ) break;
  3317   3317   

Changes to src/random.c.

    11     11   *************************************************************************
    12     12   ** This file contains code to implement a pseudo-random number
    13     13   ** generator (PRNG) for SQLite.
    14     14   **
    15     15   ** Random numbers are used by some of the database backends in order
    16     16   ** to generate random integer keys for tables or random filenames.
    17     17   **
    18         -** $Id: random.c,v 1.23 2008/03/21 16:45:47 drh Exp $
           18  +** $Id: random.c,v 1.24 2008/06/18 17:09:10 danielk1977 Exp $
    19     19   */
    20     20   #include "sqliteInt.h"
    21     21   
    22     22   
    23     23   /* All threads share a single random number generator.
    24     24   ** This structure is the current state of the generator.
    25     25   */
................................................................................
    88     88   }
    89     89   
    90     90   /*
    91     91   ** Return N random bytes.
    92     92   */
    93     93   void sqlite3_randomness(int N, void *pBuf){
    94     94     unsigned char *zBuf = pBuf;
    95         -  static sqlite3_mutex *mutex = 0;
    96         -  if( mutex==0 ){
    97         -    mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PRNG);
    98         -  }
           95  +  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
    99     96     sqlite3_mutex_enter(mutex);
   100     97     while( N-- ){
   101     98       *(zBuf++) = randomByte();
   102     99     }
   103    100     sqlite3_mutex_leave(mutex);
   104    101   }
   105    102   

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.713 2008/06/18 13:27:47 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.714 2008/06/18 17:09:10 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
................................................................................
  1802   1802   void *sqlite3ScratchMalloc(int);
  1803   1803   void sqlite3ScratchFree(void*);
  1804   1804   void *sqlite3PageMalloc(int);
  1805   1805   void sqlite3PageFree(void*);
  1806   1806   void sqlite3MemSetDefault(void);
  1807   1807   
  1808   1808   sqlite3_mutex_methods *sqlite3DefaultMutex(void);
         1809  +sqlite3_mutex *sqlite3MutexAlloc(int);
  1809   1810   
  1810   1811   int sqlite3IsNaN(double);
  1811   1812   
  1812   1813   char *sqlite3MPrintf(sqlite3*,const char*, ...);
  1813   1814   char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
  1814   1815   #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
  1815   1816     void sqlite3DebugPrintf(const char*, ...);

Changes to src/test3.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the btree.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test3.c,v 1.97 2008/06/06 11:11:26 danielk1977 Exp $
           16  +** $Id: test3.c,v 1.98 2008/06/18 17:09:10 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "btreeInt.h"
    20     20   #include "tcl.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
................................................................................
    74     74       return TCL_ERROR;
    75     75     }
    76     76     if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
    77     77     if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR;
    78     78     nRefSqlite3++;
    79     79     if( nRefSqlite3==1 ){
    80     80       sDb.pVfs = sqlite3_vfs_find(0);
    81         -    sDb.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
           81  +    sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
    82     82       sqlite3_mutex_enter(sDb.mutex);
    83     83     }
    84     84     rc = sqlite3BtreeOpen(argv[1], &sDb, &pBt, flags,
    85     85        SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
    86     86     if( rc!=SQLITE_OK ){
    87     87       Tcl_AppendResult(interp, errorName(rc), 0);
    88     88       return TCL_ERROR;

Changes to src/test_mutex.c.

     6      6   **
     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   ** 
    13         -** $Id: test_mutex.c,v 1.1 2008/06/18 09:45:56 danielk1977 Exp $
           13  +** $Id: test_mutex.c,v 1.2 2008/06/18 17:09:10 danielk1977 Exp $
    14     14   */
    15     15   
    16     16   #include "tcl.h"
    17     17   #include "sqlite3.h"
    18     18   #include <stdlib.h>
    19     19   #include <assert.h>
    20     20   #include <string.h>
................................................................................
   242    242     }
   243    243   
   244    244     for(ii=0; ii<8; ii++){
   245    245       g.aCounter[ii] = 0;
   246    246     }
   247    247     return TCL_OK;
   248    248   }
          249  +
          250  +/*
          251  +** sqlite3_config OPTION
          252  +*/
          253  +static int test_config(
          254  +  void * clientData,
          255  +  Tcl_Interp *interp,
          256  +  int objc,
          257  +  Tcl_Obj *CONST objv[]
          258  +){
          259  +  struct ConfigOption {
          260  +    const char *zName;
          261  +    int iValue;
          262  +  } aOpt[] = {
          263  +    {"singlethread", SQLITE_CONFIG_SINGLETHREAD},
          264  +    {"multithread",  SQLITE_CONFIG_MULTITHREAD},
          265  +    {"serialized",   SQLITE_CONFIG_SERIALIZED},
          266  +    {0, 0}
          267  +  };
          268  +  int s = sizeof(struct ConfigOption);
          269  +  int i;
          270  +  int rc;
          271  +
          272  +  if( objc!=2 ){
          273  +    Tcl_WrongNumArgs(interp, 1, objv, "");
          274  +    return TCL_ERROR;
          275  +  }
          276  +
          277  +  if( Tcl_GetIndexFromObjStruct(interp, objv[1], aOpt, s, "flag", 0, &i) ){
          278  +    return TCL_ERROR;
          279  +  }
          280  +
          281  +  rc = sqlite3_config(aOpt[i].iValue);
          282  +  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
          283  +  return TCL_OK;
          284  +}
   249    285   
   250    286   int Sqlitetest_mutex_Init(Tcl_Interp *interp){
   251    287     static struct {
   252    288       char *zName;
   253    289       Tcl_ObjCmdProc *xProc;
   254    290     } aCmd[] = {
   255    291       { "sqlite3_shutdown",        (Tcl_ObjCmdProc*)test_shutdown },
   256    292       { "sqlite3_initialize",      (Tcl_ObjCmdProc*)test_initialize },
          293  +    { "sqlite3_config",          (Tcl_ObjCmdProc*)test_config },
   257    294   
   258    295       { "install_mutex_counters",  (Tcl_ObjCmdProc*)test_install_mutex_counters },
   259    296       { "read_mutex_counters",     (Tcl_ObjCmdProc*)test_read_mutex_counters },
   260    297       { "clear_mutex_counters",    (Tcl_ObjCmdProc*)test_clear_mutex_counters },
   261    298     };
   262    299     int i;
   263    300     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
   264    301       Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
   265    302     }
   266    303     memset(&g, 0, sizeof(g));
   267    304     return SQLITE_OK;
   268    305   }
   269    306   

Changes to src/vdbeapi.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains code use to implement APIs that are part of the
    14     14   ** VDBE.
    15     15   **
    16         -** $Id: vdbeapi.c,v 1.132 2008/05/16 15:24:58 danielk1977 Exp $
           16  +** $Id: vdbeapi.c,v 1.133 2008/06/18 17:09:10 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "vdbeInt.h"
    20     20   
    21     21   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
    22     22   /*
    23     23   ** The following structure contains pointers to the end points of a
................................................................................
    64     64   
    65     65   /*
    66     66   ** Add vdbe p to the end of the statement lru list. It is assumed that
    67     67   ** p is not already part of the list when this is called. The lru list
    68     68   ** is protected by the SQLITE_MUTEX_STATIC_LRU mutex.
    69     69   */
    70     70   static void stmtLruAdd(Vdbe *p){
    71         -  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
           71  +  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
    72     72   
    73     73     if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){
    74         -    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
           74  +    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
    75     75       return;
    76     76     }
    77     77   
    78     78     assert( stmtLruCheck() );
    79     79   
    80     80     if( !sqlite3LruStatements.pFirst ){
    81     81       assert( !sqlite3LruStatements.pLast );
................................................................................
    86     86       p->pLruPrev = sqlite3LruStatements.pLast;
    87     87       sqlite3LruStatements.pLast->pLruNext = p;
    88     88       sqlite3LruStatements.pLast = p;
    89     89     }
    90     90   
    91     91     assert( stmtLruCheck() );
    92     92   
    93         -  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
           93  +  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
    94     94   }
    95     95   
    96     96   /*
    97     97   ** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove
    98     98   ** statement p from the least-recently-used statement list. If the 
    99     99   ** statement is not currently part of the list, this call is a no-op.
   100    100   */
................................................................................
   119    119   
   120    120   /*
   121    121   ** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove
   122    122   ** statement p from the least-recently-used statement list. If the 
   123    123   ** statement is not currently part of the list, this call is a no-op.
   124    124   */
   125    125   static void stmtLruRemove(Vdbe *p){
   126         -  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
          126  +  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
   127    127     stmtLruRemoveNomutex(p);
   128         -  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
          128  +  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
   129    129   }
   130    130   
   131    131   /*
   132    132   ** Try to release n bytes of memory by freeing buffers associated 
   133    133   ** with the memory registers of currently unused vdbes.
   134    134   */
   135    135   int sqlite3VdbeReleaseMemory(int n){
   136    136     Vdbe *p;
   137    137     Vdbe *pNext;
   138    138     int nFree = 0;
   139    139   
   140         -  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
          140  +  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
   141    141     for(p=sqlite3LruStatements.pFirst; p && nFree<n; p=pNext){
   142    142       pNext = p->pLruNext;
   143    143   
   144    144       /* For each statement handle in the lru list, attempt to obtain the
   145    145       ** associated database mutex. If it cannot be obtained, continue
   146    146       ** to the next statement handle. It is not possible to block on
   147    147       ** the database mutex - that could cause deadlock.
................................................................................
   148    148       */
   149    149       if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){
   150    150         nFree += sqlite3VdbeReleaseBuffers(p);
   151    151         stmtLruRemoveNomutex(p);
   152    152         sqlite3_mutex_leave(p->db->mutex);
   153    153       }
   154    154     }
   155         -  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
          155  +  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
   156    156   
   157    157     return nFree;
   158    158   }
   159    159   
   160    160   /*
   161    161   ** Call sqlite3Reprepare() on the statement. Remove it from the
   162    162   ** lru list before doing so, as Reprepare() will free all the

Changes to test/mutex1.test.

     5      5   #
     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12         -# $Id: mutex1.test,v 1.1 2008/06/18 09:45:56 danielk1977 Exp $
           12  +# $Id: mutex1.test,v 1.2 2008/06/18 17:09:10 danielk1977 Exp $
    13     13   
    14     14   set testdir [file dirname $argv0]
    15     15   source $testdir/tester.tcl
    16     16   
    17     17   proc mutex_counters {varname} {
    18     18     upvar $varname var
    19     19     set var(total) 0
................................................................................
    71     71   } {SQLITE_OK}
    72     72   
    73     73   do_test mutex1-1.9 {
    74     74     mutex_counters counters
    75     75     list $counters(total) $counters(static_master)
    76     76   } {0 0}
    77     77   
           78  +#-------------------------------------------------------------------------
           79  +# Tests mutex1-2.* test the three thread-safety related modes that
           80  +# can be selected using sqlite3_config:
           81  +#
           82  +#   * Serialized mode,
           83  +#   * Multi-threaded mode,
           84  +#   * Single-threaded mode.
           85  +#
           86  +
           87  +foreach {mode mutexes} {
           88  +  singlethread {}
           89  +  multithread  {fast static_master static_mem static_prng}
           90  +  serialized   {fast recursive static_master static_mem static_prng}
           91  +} {
           92  +  do_test mutex1.2.$mode.1 {
           93  +    catch {db close}
           94  +    sqlite3_shutdown
           95  +    sqlite3_config $mode
           96  +  } SQLITE_OK
           97  +
           98  +  do_test mutex1.2.$mode.2 {
           99  +    clear_mutex_counters
          100  +    sqlite3 db test.db
          101  +    catchsql { CREATE TABLE abc(a, b, c) }
          102  +    db eval {
          103  +      INSERT INTO abc VALUES(1, 2, 3);
          104  +    }
          105  +  } {}
          106  +
          107  +  do_test mutex1.2.$mode.3 {
          108  +    mutex_counters counters
          109  +
          110  +    set res [list]
          111  +    foreach {key value} [array get counters] {
          112  +      if {$key ne "total" && $value > 0} {
          113  +        lappend res $key
          114  +      }
          115  +    }
          116  +    lsort $res
          117  +  } $mutexes
          118  +}
    78    119   
    79    120   do_test mutex1-X {
          121  +  db close
    80    122     sqlite3_shutdown
    81    123     clear_mutex_counters
    82    124     install_mutex_counters 0
    83    125   } {SQLITE_OK}
    84    126   
    85    127   finish_test
    86    128   

Added test/mutex2.test.

            1  +# 2007 March 26
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file runs some other test files after calling sqlite3_config to
           13  +# set the thread-safety mode to SQLITE_CONFIG_SINGLETHREAD and
           14  +# SQLITE_CONFIG_MULTITHREAD (instead of the default SQLITE_CONFIG_SERIALIZED).
           15  +#
           16  +# $Id: mutex2.test,v 1.1 2008/06/18 17:09:10 danielk1977 Exp $
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +
           21  +ifcapable {!pager_pragmas} {
           22  +  finish_test
           23  +  return
           24  +}
           25  +
           26  +rename finish_test really_finish_test2
           27  +proc finish_test {} {}
           28  +set ISQUICK 1
           29  +
           30  +rename do_test really_do_test
           31  +proc do_test {args} {
           32  +  set sc [concat really_do_test "mutex2-${::thread_mode}.[lindex $args 0]" \
           33  +      [lrange $args 1 end]]
           34  +  eval $sc
           35  +}
           36  +
           37  +foreach ::thread_mode {singlethread multithread} {
           38  +  do_test mutex2-$::thread_mode.0 {
           39  +    catch {db close}
           40  +    sqlite3_shutdown
           41  +    sqlite3_config $::thread_mode
           42  +  } SQLITE_OK
           43  +
           44  +  source $testdir/delete.test
           45  +  source $testdir/delete2.test
           46  +  source $testdir/insert.test
           47  +  source $testdir/rollback.test
           48  +  source $testdir/select1.test
           49  +  source $testdir/select2.test
           50  +  source $testdir/trans.test
           51  +  source $testdir/update.test
           52  +  source $testdir/vacuum.test
           53  +  source $testdir/types.test
           54  +  source $testdir/types2.test
           55  +  source $testdir/types3.test
           56  +
           57  +  #source $testdir/malloc.test
           58  +  #source $testdir/ioerr.test
           59  +}
           60  +
           61  +do_test mutex2-X {
           62  +  catch {db close}
           63  +  sqlite3_shutdown
           64  +  sqlite3_config serialized
           65  +} SQLITE_OK
           66  +
           67  +rename finish_test ""
           68  +rename really_finish_test2 finish_test
           69  +rename do_test ""
           70  +rename really_do_test do_test
           71  +finish_test
           72  +

Changes to test/quick.test.

     2      2   #    May you do good and not evil.
     3      3   #    May you find forgiveness for yourself and forgive others.
     4      4   #    May you share freely, never taking more than you give.
     5      5   #
     6      6   #***********************************************************************
     7      7   # This file runs all tests.
     8      8   #
     9         -# $Id: quick.test,v 1.78 2008/04/19 20:34:19 drh Exp $
            9  +# $Id: quick.test,v 1.79 2008/06/18 17:09:10 danielk1977 Exp $
    10     10   
    11     11   proc lshift {lvar} {
    12     12     upvar $lvar l
    13     13     set ret [lindex $l 0]
    14     14     set l [lrange $l 1 end]
    15     15     return $ret
    16     16   }
................................................................................
    60     60     malloc.test
    61     61     malloc2.test
    62     62     malloc3.test
    63     63     malloc4.test
    64     64     memleak.test
    65     65     misc7.test
    66     66     misuse.test
           67  +  mutex2.test
    67     68     onefile.test
    68     69     quick.test
    69     70     soak.test
    70     71     speed1.test
    71     72     speed1p.test
    72     73     speed2.test
    73     74     speed3.test

Changes to test/veryquick.test.

     2      2   #    May you do good and not evil.
     3      3   #    May you find forgiveness for yourself and forgive others.
     4      4   #    May you share freely, never taking more than you give.
     5      5   #
     6      6   #***********************************************************************
     7      7   # This file runs all tests.
     8      8   #
     9         -# $Id: veryquick.test,v 1.3 2008/04/19 20:34:19 drh Exp $
            9  +# $Id: veryquick.test,v 1.4 2008/06/18 17:09:10 danielk1977 Exp $
    10     10   
    11     11   proc lshift {lvar} {
    12     12     upvar $lvar l
    13     13     set ret [lindex $l 0]
    14     14     set l [lrange $l 1 end]
    15     15     return $ret
    16     16   }
................................................................................
    82     82     mallocD.test
    83     83     mallocE.test
    84     84     mallocF.test
    85     85     mallocG.test
    86     86     memleak.test
    87     87     misc7.test
    88     88     misuse.test
           89  +  mutex2.test
    89     90     onefile.test
    90     91     quick.test
    91     92     soak.test
    92     93     speed1.test
    93     94     speed1p.test
    94     95     speed2.test
    95     96     speed3.test