Make selecting the asynchronous IO file-locking mode a runtime operation. Still untested. (CVS 6544)

FossilOrigin-Name: 577277e84a05707b8c21aa08bc5fc314c1ac38ac
diff --git a/ext/async/sqlite3async.c b/ext/async/sqlite3async.c
index f1fdb8d..586a749 100644
--- a/ext/async/sqlite3async.c
+++ b/ext/async/sqlite3async.c
@@ -10,7 +10,7 @@
 **
 *************************************************************************
 **
-** $Id: sqlite3async.c,v 1.2 2009/04/24 09:27:16 danielk1977 Exp $
+** $Id: sqlite3async.c,v 1.3 2009/04/24 10:13:06 danielk1977 Exp $
 **
 ** This file contains the implementation of an asynchronous IO backend 
 ** for SQLite.
@@ -19,8 +19,10 @@
 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO)
 
 #include "sqlite3async.h"
-
-#define ENABLE_FILE_LOCKING
+#include "sqlite3.h"
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
 
 /* Useful macros used in several places */
 #define MIN(x,y) ((x)<(y)?(x):(y))
@@ -34,6 +36,8 @@
 typedef struct AsyncLock AsyncLock;
 
 /* Enable for debugging */
+#ifndef NDEBUG
+#include <stdio.h>
 static int sqlite3async_trace = 0;
 # define ASYNC_TRACE(X) if( sqlite3async_trace ) asyncTrace X
 static void asyncTrace(const char *zFormat, ...){
@@ -45,6 +49,7 @@
   fprintf(stderr, "[%d] %s", 0 /* (int)pthread_self() */, z);
   sqlite3_free(z);
 }
+#endif
 
 /*
 ** THREAD SAFETY NOTES
@@ -374,9 +379,10 @@
   AsyncLock *pLock;            /* Linked list of all AsyncLock structures */
   volatile int ioDelay;        /* Extra delay between write operations */
   volatile int eHalt;          /* One of the SQLITEASYNC_HALT_XXX values */
+  volatile int bLockFiles;     /* Current value of "lockfiles" parameter */
   int ioError;                 /* True if an IO error has occurred */
   int nFile;                   /* Number of open files (from sqlite pov) */
-} async = { 0,0,0,0,0,0,0 };
+} async = { 0,0,0,0,0,1,0,0 };
 
 /* Possible values of AsyncWrite.op */
 #define ASYNC_NOOP          0
@@ -456,11 +462,11 @@
 ** structures, one for each handle currently open on the file.
 **
 ** If the opened file is not a main-database (the SQLITE_OPEN_MAIN_DB is
-** not passed to the sqlite3OsOpen() call), or if ENABLE_FILE_LOCKING is 
-** not defined at compile time, variables AsyncLock.pFile and 
-** AsyncLock.eLock are never used. Otherwise, pFile is a file handle
-** opened on the file in question and used to obtain the file-system 
-** locks required by database connections within this process.
+** not passed to the sqlite3OsOpen() call), or if async.bLockFiles is 
+** false, variables AsyncLock.pFile and AsyncLock.eLock are never used. 
+** Otherwise, pFile is a file handle opened on the file in question and 
+** used to obtain the file-system locks required by database connections 
+** within this process.
 **
 ** See comments above the asyncLock() function for more details on 
 ** the implementation of database locking used by this backend.
@@ -1064,8 +1070,7 @@
       pLock = (AsyncLock *)sqlite3_malloc(nByte);
       if( pLock ){
         memset(pLock, 0, nByte);
-#ifdef ENABLE_FILE_LOCKING
-        if( flags&SQLITE_OPEN_MAIN_DB ){
+        if( async.bLockFiles && (flags&SQLITE_OPEN_MAIN_DB) ){
           pLock->pFile = (sqlite3_file *)&pLock[1];
           rc = pVfs->xOpen(pVfs, pData->zName, pLock->pFile, flags, 0);
           if( rc!=SQLITE_OK ){
@@ -1073,7 +1078,6 @@
             pLock = 0;
           }
         }
-#endif
         if( pLock ){
           pLock->nFile = pData->nName;
           pLock->zFile = &((char *)(&pLock[1]))[pVfs->szOsFile];
@@ -1607,7 +1611,7 @@
        && eWhen!=SQLITEASYNC_HALT_NOW
        && eWhen!=SQLITEASYNC_HALT_IDLE
       ){
-        return SQLITE_ERROR;
+        return SQLITE_MISUSE;
       }
       async.eHalt = eWhen;
       async_mutex_enter(ASYNC_MUTEX_QUEUE);
@@ -1618,9 +1622,24 @@
 
     case SQLITEASYNC_DELAY: {
       int iDelay = va_arg(ap, int);
+      if( iDelay<0 ){
+        return SQLITE_MISUSE;
+      }
       async.ioDelay = iDelay;
       break;
     }
+
+    case SQLITEASYNC_LOCKFILES: {
+      int bLock = va_arg(ap, int);
+      async_mutex_enter(ASYNC_MUTEX_QUEUE);
+      if( async.nFile || async.pQueueFirst ){
+        async_mutex_leave(ASYNC_MUTEX_QUEUE);
+        return SQLITE_MISUSE;
+      }
+      async.bLockFiles = bLock;
+      async_mutex_leave(ASYNC_MUTEX_QUEUE);
+      break;
+    }
       
     case SQLITEASYNC_GET_HALT: {
       int *peWhen = va_arg(ap, int *);
@@ -1632,6 +1651,11 @@
       *piDelay = async.ioDelay;
       break;
     }
+    case SQLITEASYNC_GET_LOCKFILES: {
+      int *piDelay = va_arg(ap, int *);
+      *piDelay = async.bLockFiles;
+      break;
+    }
 
     default:
       return SQLITE_ERROR;