]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add internal locking to the test_async.c backend. So that more than one connection...
authordanielk1977 <danielk1977@noemail.net>
Tue, 4 Sep 2007 14:31:47 +0000 (14:31 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Tue, 4 Sep 2007 14:31:47 +0000 (14:31 +0000)
FossilOrigin-Name: 17ca684c124445f17d1e36c37e169056c5fd4569

manifest
manifest.uuid
src/hash.c
src/hash.h
src/test_async.c
test/async.test

index 0a3424a6f3dabf236371e531ffb3b5e8b59e9db7..e13e704a1ddb264a8802e206f1280522c4d1926b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Clarify\sdocumentation\son\sthe\sreturn\svalue\sfrom\ssqlite3_column_blob()\sfor\na\szero-length\sBLOB.\s\sClarify\sthe\sdocumentation\son\swhat\shappens\swhen\syou\nhave\sa\szeroblob()\swith\sa\snegative\slength.\s\sAdditional\stest\scases\sbut\sno\nchanges\sto\scode.\s\sTicket\s#2623.\s(CVS\s4395)
-D 2007-09-04T12:18:42
+C Add\sinternal\slocking\sto\sthe\stest_async.c\sbackend.\sSo\sthat\smore\sthan\sone\sconnection\smay\sbe\sused\sfrom\swithin\sa\ssingle\sprocess.\s(CVS\s4396)
+D 2007-09-04T14:31:47
 F Makefile.in cbfb898945536a8f9ea8b897e1586dd1fdbcc5db
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -92,8 +92,8 @@ F src/delete.c 849846d06d29851dde0d9f424a5de5817eb140d1
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
 F src/expr.c 7853a8161ec0b0fce62fc8da921db557899f1ec1
 F src/func.c 9d88141c4cffb3a04719e5a0fda65cde34bfa1e5
-F src/hash.c 06c69a3a038b713c43353c79023372bcfe7f5180
-F src/hash.h 3ad3da76bfb954978d227bf495568b0e6da2c19e
+F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
+F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
 F src/insert.c df9712e1f67201573a9677d3a2fe401d52d84dda
 F src/journal.c a45147d798f4d8dbdeed200ca7f740579bd8591b
 F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
@@ -145,7 +145,7 @@ F src/test6.c 0513982dfef4da2a4154b538d2bf538b84ca21d3
 F src/test7.c a9d509d0e9ad214b4772696f49f6e61be26213d1
 F src/test8.c f113aa3723a52113d0fa7c28155ecd37e7e04077
 F src/test9.c b46c8fe02ac7cca1a7316436d8d38d50c66f4b2f
-F src/test_async.c dcb562dc81bf6851294b9260c8b61971169d5707
+F src/test_async.c c6f5f75f8ccf5d8be1076c45a9c3d5fd995249b9
 F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436
 F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c
 F src/test_config.c 6fb459214b27952b143f45e35200d94096d54cc6
@@ -180,7 +180,7 @@ F test/alter2.test 50c3f554b8236d179d72511c0a4f23c5eb7f2af3
 F test/alter3.test a6eec8f454be9b6ce73d8d7dc711453675a10ce7
 F test/altermalloc.test 1f4d2d66750bea1a78cd9f0b7dba5bfb155dd6cf
 F test/analyze.test 2f55535aa335785db1a2f97d3f3831c16c09f8b0
-F test/async.test 464dc7c7ccb144e8c82ecca429e6d7cd1c96bd6e
+F test/async.test b5547f56b329fa2ea5bce80f25c1d91eff36b47b
 F test/async2.test a8ef7abfda880b171b2f0a8476300816e33a808a
 F test/attach.test b849e1baae863c3a6132ff8b9b1baf356ab6c178
 F test/attach2.test 78bc1a25ea8785c7571b44f5947ada2bd5d78127
@@ -569,7 +569,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 2eadef90162590a7b947c38acf0016d0c55821c7
-R a5be8e3038cc725b3d325f8649b6f5b5
-U drh
-Z 9f6f2dde9339d174ebf4469c17340052
+P 63ca02a5b2700858f0eceadc9b58b942d473b191
+R 5cb983fe15fecf887cd0939edebbb838
+U danielk1977
+Z 34bdd4fc38cb5e365ec1bd9364840893
index e5e64f7833aee25747a35fe48c6e80cb76661ba4..bab485086e99c371be516e9213b2ab88fd0e2e32 100644 (file)
@@ -1 +1 @@
-63ca02a5b2700858f0eceadc9b58b942d473b191
\ No newline at end of file
+17ca684c124445f17d1e36c37e169056c5fd4569
\ No newline at end of file
index d01ab92f723ce36e49c6dd2ff8c74f8bcff6d7d1..a88d16b06bf26cb89a3dd351ec403ba99b496c9b 100644 (file)
@@ -12,7 +12,7 @@
 ** This is the implementation of generic hash-tables
 ** used in SQLite.
 **
-** $Id: hash.c,v 1.23 2007/09/03 15:03:21 danielk1977 Exp $
+** $Id: hash.c,v 1.24 2007/09/04 14:31:47 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <assert.h>
@@ -310,10 +310,11 @@ static void removeElementGivenHash(
 }
 
 /* Attempt to locate an element of the hash table pH with a key
-** that matches pKey,nKey.  Return the data for this element if it is
-** found, or NULL if there is no match.
+** that matches pKey,nKey.  Return a pointer to the corresponding 
+** HashElem structure for this element if it is found, or NULL
+** otherwise.
 */
-void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
+HashElem *sqlite3HashFindElem(const Hash *pH, const void *pKey, int nKey){
   int h;             /* A hash on key */
   HashElem *elem;    /* The element that matches key */
   int (*xHash)(const void*,int);  /* The hash function */
@@ -324,6 +325,16 @@ void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
   h = (*xHash)(pKey,nKey);
   assert( (pH->htsize & (pH->htsize-1))==0 );
   elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
+  return elem;
+}
+
+/* Attempt to locate an element of the hash table pH with a key
+** that matches pKey,nKey.  Return the data for this element if it is
+** found, or NULL if there is no match.
+*/
+void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
+  HashElem *elem;    /* The element that matches key */
+  elem = sqlite3HashFindElem(pH, pKey, nKey);
   return elem ? elem->data : 0;
 }
 
index 275ac75454396f1209e3fcf0741bc578aa6ebcc9..e3274e9e4419013c95760b684d120068ac3ceae5 100644 (file)
@@ -12,7 +12,7 @@
 ** This is the header file for the generic hash-table implemenation
 ** used in SQLite.
 **
-** $Id: hash.h,v 1.10 2007/08/16 04:30:40 drh Exp $
+** $Id: hash.h,v 1.11 2007/09/04 14:31:47 danielk1977 Exp $
 */
 #ifndef _SQLITE_HASH_H_
 #define _SQLITE_HASH_H_
@@ -81,6 +81,7 @@ struct HashElem {
 void sqlite3HashInit(Hash*, int keytype, int copyKey);
 void *sqlite3HashInsert(Hash*, const void *pKey, int nKey, void *pData);
 void *sqlite3HashFind(const Hash*, const void *pKey, int nKey);
+HashElem *sqlite3HashFindElem(const Hash*, const void *pKey, int nKey);
 void sqlite3HashClear(Hash*);
 
 /*
index 7e382fbd5b27a16daf49cd08301d67d664094dee..77c676b4a840c474cc833f086d50cb0f137ef0f7 100644 (file)
@@ -151,7 +151,7 @@ static void asyncTrace(const char *zFormat, ...){
 **     queue in mid operation.
 **    
 **
-**         asyncLock, asyncUnlock, asyncLockState, asyncCheckReservedLock
+**         asyncLock, asyncUnlock, asyncCheckReservedLock
 **    
 **     These primitives implement in-process locking using a hash table
 **     on the file name.  Files are locked correctly for connections coming
@@ -252,18 +252,14 @@ static struct TestAsyncStaticData {
 #define ASYNC_SYNC          2
 #define ASYNC_TRUNCATE      3
 #define ASYNC_CLOSE         4
-#define ASYNC_OPENDIRECTORY 5
-#define ASYNC_SETFULLSYNC   6
-#define ASYNC_DELETE        7
-#define ASYNC_OPENEXCLUSIVE 8
-#define ASYNC_SYNCDIRECTORY 9
+#define ASYNC_DELETE        5
+#define ASYNC_OPENEXCLUSIVE 6
 
 /* Names of opcodes.  Used for debugging only.
 ** Make sure these stay in sync with the macros above!
 */
 static const char *azOpcodeName[] = {
-  "NOOP", "WRITE", "SYNC", "TRUNCATE", "CLOSE",
-  "OPENDIR", "SETFULLSYNC", "DELETE", "OPENEX", "SYNCDIR",
+  "NOOP", "WRITE", "SYNC", "TRUNCATE", "CLOSE", "DELETE", "OPENEX"
 };
 
 /*
@@ -273,6 +269,9 @@ static const char *azOpcodeName[] = {
 ** The interpretation of the iOffset and nByte variables varies depending 
 ** on the value of AsyncWrite.op:
 **
+** ASYNC_NOOP:
+**     No values used.
+**
 ** ASYNC_WRITE:
 **     iOffset -> Offset in file to write to.
 **     nByte   -> Number of bytes of data to write (pointed to by zBuf).
@@ -288,15 +287,6 @@ static const char *azOpcodeName[] = {
 **     iOffset -> Unused.
 **     nByte   -> Unused.
 **
-** ASYNC_OPENDIRECTORY:
-**     iOffset -> Unused.
-**     nByte   -> Number of bytes of zBuf points to (directory name).
-**
-** ASYNC_SETFULLSYNC:
-**     iOffset -> Unused.
-**     nByte   -> New value for the full-sync flag.
-**
-**
 ** ASYNC_DELETE:
 **     iOffset -> Contains the "syncDir" flag.
 **     nByte   -> Number of bytes of zBuf points to (file name).
@@ -320,6 +310,23 @@ struct AsyncWrite {
   AsyncWrite *pNext;  /* Next write operation (to any file) */
 };
 
+/*
+** An instance of the following structure is allocated along with each
+** AsyncFileData structure (see AsyncFileData.lock), but is only used if the
+** file was opened with the SQLITE_OPEN_MAIN_DB.
+**
+** The global async.aLock[] hash table maps from database file-name to a
+** linked-list of AsyncLock structures corresponding to handles opened on the
+** file. The AsyncLock structures are linked into the list when the file is
+** opened and removed when it is closed. Mutex async.lockMutex must be held
+** before accessing any AsyncLock structure or the async.aLock[] table.
+*/
+typedef struct AsyncLock AsyncLock;
+struct AsyncLock {
+  int eLock;
+  AsyncLock *pNext;
+};
+
 /* 
 ** The AsyncFile structure is a subclass of sqlite3_file used for 
 ** asynchronous IO. 
@@ -340,6 +347,7 @@ struct AsyncFileData {
   int nName;                 /* Number of characters in zName */
   sqlite3_file *pBaseRead;   /* Read handle to the underlying Os file */
   sqlite3_file *pBaseWrite;  /* Write handle to the underlying Os file */
+  AsyncLock lock;
 };
 
 /*
@@ -436,6 +444,12 @@ static int addNewAsyncWrite(
 */
 static int asyncClose(sqlite3_file *pFile){
   AsyncFileData *p = ((AsyncFile *)pFile)->pData;
+
+  /* Unlock the file, if it is locked */
+  pthread_mutex_lock(&async.lockMutex);
+  p->lock.eLock = 0;
+  pthread_mutex_unlock(&async.lockMutex);
+
   return addNewAsyncWrite(p, ASYNC_CLOSE, 0, 0, 0);
 }
 
@@ -488,9 +502,10 @@ static int asyncRead(sqlite3_file *pFile, void *zOut, int iAmt, i64 iOffset){
 
   if( rc==SQLITE_OK ){
     AsyncWrite *pWrite;
+    char *zName = p->zName;
 
     for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){
-      if( pWrite->pFileData==p && pWrite->op==ASYNC_WRITE ){
+      if( pWrite->op==ASYNC_WRITE && pWrite->pFileData->zName==zName ){
         int iBeginOut = (pWrite->iOffset-iOffset);
         int iBeginIn = -iBeginOut;
         int nCopy;
@@ -558,7 +573,9 @@ int asyncFileSize(sqlite3_file *pFile, i64 *piSize){
   if( rc==SQLITE_OK ){
     AsyncWrite *pWrite;
     for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){
-      if( pWrite->pFileData==p ){
+      if( pWrite->op==ASYNC_DELETE && strcmp(p->zName, pWrite->zBuf)==0 ){
+        s = 0;
+      }else if( pWrite->pFileData && pWrite->pFileData->zName==p->zName){
         switch( pWrite->op ){
           case ASYNC_WRITE:
             s = MAX(pWrite->iOffset + (i64)(pWrite->nByte), s);
@@ -583,30 +600,65 @@ int asyncFileSize(sqlite3_file *pFile, i64 *piSize){
 ** cannot see our internal hash table (obviously) and will thus not
 ** honor our locks.
 */
-static int asyncLock(sqlite3_file *pFile, int lockType){
+static int asyncLock(sqlite3_file *pFile, int eLock){
+  int rc = SQLITE_OK;
+  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
+
+  pthread_mutex_lock(&async.lockMutex);
+  if( p->lock.eLock<eLock ){
+    AsyncLock *pLock;
+    pLock = (AsyncLock *)sqlite3HashFind(&async.aLock, p->zName, p->nName);
+    assert(pLock);
+    for(/*no-op*/; pLock; pLock=pLock->pNext){
+      if( pLock!=&p->lock && (
+        (eLock==SQLITE_LOCK_EXCLUSIVE && pLock->eLock>=SQLITE_LOCK_SHARED) ||
+        (eLock==SQLITE_LOCK_PENDING && pLock->eLock>=SQLITE_LOCK_RESERVED) ||
+        (eLock==SQLITE_LOCK_RESERVED && pLock->eLock>=SQLITE_LOCK_RESERVED) ||
+        (eLock==SQLITE_LOCK_SHARED && pLock->eLock>=SQLITE_LOCK_PENDING)
+      )){
+        rc = SQLITE_BUSY;
+      }
+    }
+    if( rc==SQLITE_OK ){
+      p->lock.eLock = eLock;
+    }
+  }
+  pthread_mutex_unlock(&async.lockMutex);
+
+  ASYNC_TRACE(("LOCK %d (%s) rc=%d\n", eLock, p->zName, rc));
+  return rc;
+}
+static int asyncUnlock(sqlite3_file *pFile, int eLock){
   AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  ASYNC_TRACE(("LOCK %d (%s)\n", lockType, p->zName));
+  AsyncLock *pLock = &p->lock;
   pthread_mutex_lock(&async.lockMutex);
-  sqlite3HashInsert(&async.aLock, p->zName, p->nName, (void*)lockType);
+  if( pLock->eLock>eLock ){
+    pLock->eLock = eLock;
+  }
   pthread_mutex_unlock(&async.lockMutex);
   return SQLITE_OK;
 }
-static int asyncUnlock(sqlite3_file *pFile, int lockType){
-  return asyncLock(pFile, lockType);
-}
 
 /*
 ** This function is called when the pager layer first opens a database file
 ** and is checking for a hot-journal.
 */
 static int asyncCheckReservedLock(sqlite3_file *pFile){
+  int ret = 0;
+  AsyncLock *pLock;
   AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  int rc;
+
   pthread_mutex_lock(&async.lockMutex);
-  rc = (int)sqlite3HashFind(&async.aLock, p->zName, p->nName);
+  pLock = (AsyncLock *)sqlite3HashFind(&async.aLock, p->zName, p->nName);
+  for(/*no-op*/; pLock; pLock=pLock->pNext){
+    if( pLock->eLock>=SQLITE_LOCK_RESERVED ){
+      ret = 1;
+    }
+  }
   pthread_mutex_unlock(&async.lockMutex);
-  ASYNC_TRACE(("CHECK-LOCK %d (%s)\n", rc, p->zName));
-  return rc>SHARED_LOCK;
+
+  ASYNC_TRACE(("CHECK-LOCK %d (%s)\n", ret, p->zName));
+  return ret;
 }
 
 /* 
@@ -656,16 +708,16 @@ static int asyncOpen(
 
   sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
   AsyncFile *p = (AsyncFile *)pFile;
-  int nName = strlen(zName);;
+  int nName = strlen(zName)+1;
   int rc;
   int nByte;
   AsyncFileData *pData;
 
   nByte = (
     sizeof(AsyncFileData) +        /* AsyncFileData structure */
-    2 * pVfs->szOsFile +           /* AsyncFileData.zName */
-    nName + 1                      /* AsyncFileData.pBaseRead and pBaseWrite */
-  );
+    2 * pVfs->szOsFile +           /* AsyncFileData.pBaseRead and pBaseWrite */
+    nName                          /* AsyncFileData.zName */
+  ); 
   pData = sqlite3_malloc(nByte);
   if( !pData ){
     return SQLITE_NOMEM;
@@ -673,9 +725,9 @@ static int asyncOpen(
   memset(pData, 0, nByte);
   pData->zName = (char *)&pData[1];
   pData->nName = nName;
-  pData->pBaseRead = (sqlite3_file *)&pData->zName[nName+1];
-  pData->pBaseWrite = (sqlite3_file *)&pData->zName[nName+1+pVfs->szOsFile];
-  memcpy(pData->zName, zName, nName+1);
+  pData->pBaseRead = (sqlite3_file *)&pData->zName[nName];
+  pData->pBaseWrite = (sqlite3_file *)&pData->zName[nName+pVfs->szOsFile];
+  memcpy(pData->zName, zName, nName);
 
   if( flags&SQLITE_OPEN_EXCLUSIVE ){
     rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (i64)flags, 0, 0);
@@ -688,9 +740,23 @@ static int asyncOpen(
   }
 
   if( rc==SQLITE_OK ){
+    HashElem *pElem;
     p->pMethod = &async_methods;
     p->pData = pData;
     incrOpenFileCount();
+
+    /* Link AsyncFileData.lock into the linked list of AsyncLock structures
+    ** for this file. Obtain the async.lockMutex mutex before doing so.
+    */
+    AsyncLock *pNext;
+    pthread_mutex_lock(&async.lockMutex);
+    pNext = sqlite3HashInsert(
+        &async.aLock, pData->zName, pData->nName, (void *)&pData->lock
+    );
+    pData->lock.pNext = pNext;
+    pElem = sqlite3HashFindElem(&async.aLock, pData->zName, pData->nName);
+    pData->zName = (char *)sqliteHashKey(pElem);
+    pthread_mutex_unlock(&async.lockMutex);
   }else{
     sqlite3OsClose(pData->pBaseRead);
     sqlite3OsClose(pData->pBaseWrite);
@@ -748,13 +814,61 @@ static int asyncGetTempName(sqlite3_vfs *pAsyncVfs, char *zBufOut){
   sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
   return pVfs->xGetTempName(pVfs, zBufOut);
 }
+
+/*
+** Fill in zPathOut with the full path to the file identified by zPath.
+*/
 static int asyncFullPathname(
   sqlite3_vfs *pAsyncVfs, 
   const char *zPath, 
   char *zPathOut
 ){
+  int rc;
   sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  return sqlite3OsFullPathname(pVfs, zPath, zPathOut);
+  rc = sqlite3OsFullPathname(pVfs, zPath, zPathOut);
+
+  /* Because of the way intra-process file locking works, this backend
+  ** needs to return a canonical path. The following block assumes the
+  ** file-system uses unix style paths. 
+  */
+  if( rc==SQLITE_OK ){
+    int iIn;
+    int iOut = 0;
+    int nPathOut = strlen(zPathOut);
+
+    for(iIn=0; iIn<nPathOut; iIn++){
+
+      /* Replace any occurences of "//" with "/" */
+      if( iIn<=(nPathOut-2) && zPathOut[iIn]=='/' && zPathOut[iIn+1]=='/'
+      ){
+        continue;
+      }
+
+      /* Replace any occurences of "/./" with "/" */
+      if( iIn<=(nPathOut-3) 
+       && zPathOut[iIn]=='/' && zPathOut[iIn+1]=='.' && zPathOut[iIn+2]=='/'
+      ){
+        iIn++;
+        continue;
+      }
+
+      /* Replace any occurences of "<path-component>/../" with "" */
+      if( iOut>0 && iIn<=(nPathOut-4) 
+       && zPathOut[iIn]=='/' && zPathOut[iIn+1]=='.' 
+       && zPathOut[iIn+2]=='.' && zPathOut[iIn+2]=='/'
+      ){
+        iIn += 3;
+        iOut--;
+        for( ; iOut>0 && zPathOut[iOut]!='/'; iOut--);
+        continue;
+      }
+
+      zPathOut[iOut++] = zPathOut[iIn];
+    }
+    zPathOut[iOut] = '\0';
+  }
+
+  return rc;
 }
 static void *asyncDlOpen(sqlite3_vfs *pAsyncVfs, const char *zPath){
   sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
@@ -943,12 +1057,34 @@ static void *asyncWriterThread(void *NotUsed){
         rc = sqlite3OsTruncate(pBase, p->iOffset);
         break;
 
-      case ASYNC_CLOSE:
+      case ASYNC_CLOSE: {
+        AsyncLock *pLock;
+        AsyncFileData *pData = p->pFileData;
         ASYNC_TRACE(("CLOSE %s\n", p->pFileData->zName));
-        sqlite3OsClose(p->pFileData->pBaseWrite);
-        sqlite3OsClose(p->pFileData->pBaseRead);
-        sqlite3_free(p->pFileData);
+        sqlite3OsClose(pData->pBaseWrite);
+        sqlite3OsClose(pData->pBaseRead);
+
+        /* Unlink AsyncFileData.lock from the linked list of AsyncLock 
+        ** structures for this file. Obtain the async.lockMutex mutex 
+        ** before doing so.
+        */
+        pthread_mutex_lock(&async.lockMutex);
+        pLock = sqlite3HashFind(&async.aLock, pData->zName, pData->nName);
+        if( pLock==&pData->lock ){
+          sqlite3HashInsert(
+              &async.aLock, pData->zName, pData->nName, (void *)pLock->pNext 
+          );
+        }else{
+          for( ; pLock && pLock->pNext!=&pData->lock; pLock=pLock->pNext);
+          if( pLock ){
+            pLock->pNext = pData->lock.pNext;
+          }
+        }
+        pthread_mutex_unlock(&async.lockMutex);
+
+        sqlite3_free(pData);
         break;
+      }
 
       case ASYNC_DELETE:
         ASYNC_TRACE(("DELETE %s\n", p->zBuf));
index 2a723be975eb73715457babbfb7c970998ba8263..08dbb7b57f1846ced73e6858025f0674533e5c23 100644 (file)
@@ -6,7 +6,7 @@
 #***********************************************************************
 # This file runs all tests.
 #
-# $Id: async.test,v 1.7 2006/03/19 13:00:25 drh Exp $
+# $Id: async.test,v 1.8 2007/09/04 14:31:47 danielk1977 Exp $
 
 
 if {[catch {sqlite3async_enable}]} {
@@ -30,8 +30,9 @@ set INCLUDE {
   insert2.test
   insert3.test
   trans.test
+  lock.test
+  lock3.test
 }
-# set INCLUDE {select4.test}
 
 # Enable asynchronous IO.
 sqlite3async_enable 1