]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Omit the antiquated and long-unsupport async extension since it has been omit-async
authordrh <>
Mon, 28 Oct 2024 15:38:53 +0000 (15:38 +0000)
committerdrh <>
Mon, 28 Oct 2024 15:38:53 +0000 (15:38 +0000)
superseded by WAL mode for over a decade.

FossilOrigin-Name: 10b1b86821bfc21377e7ccceb31146ab01aa6eaf418b85a204abcab5b793958e

19 files changed:
Makefile.msc
ext/async/README.txt [deleted file]
ext/async/sqlite3async.c [deleted file]
ext/async/sqlite3async.h [deleted file]
main.mk
manifest
manifest.uuid
src/test_async.c [deleted file]
src/test_tclsh.c
test/async.test [deleted file]
test/async2.test [deleted file]
test/async3.test [deleted file]
test/async4.test [deleted file]
test/async5.test [deleted file]
test/lock.test
test/main.test
test/memleak.test
test/permutations.test
test/tkt-94c04eaadb.test [deleted file]

index 863cc0242d999230fb8d49ab164cf28e00c9b788..32b8143768103d540c66086c5aba58de9327bf35 100644 (file)
@@ -1585,7 +1585,6 @@ TESTSRC = \
   $(TOP)\src\test8.c \
   $(TOP)\src\test9.c \
   $(TOP)\src\test_autoext.c \
-  $(TOP)\src\test_async.c \
   $(TOP)\src\test_backup.c \
   $(TOP)\src\test_bestindex.c \
   $(TOP)\src\test_blob.c \
@@ -1682,7 +1681,6 @@ TESTSRC2 = \
   $(SRC01) \
   $(SRC07) \
   $(SRC10) \
-  $(TOP)\ext\async\sqlite3async.c \
   fts5.c
 
 # Header files used by all library source files.
diff --git a/ext/async/README.txt b/ext/async/README.txt
deleted file mode 100644 (file)
index f62fa2f..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-NOTE (2012-11-29):
-
-The functionality implemented by this extension has been superseded
-by WAL-mode.  This module is no longer supported or maintained.  The
-code is retained for historical reference only.
-
-------------------------------------------------------------------------------
-
-Normally, when SQLite writes to a database file, it waits until the write
-operation is finished before returning control to the calling application.
-Since writing to the file-system is usually very slow compared with CPU
-bound operations, this can be a performance bottleneck. This directory
-contains an extension that causes SQLite to perform all write requests
-using a separate thread running in the background. Although this does not
-reduce the overall system resources (CPU, disk bandwidth etc.) at all, it
-allows SQLite to return control to the caller quickly even when writing to
-the database, eliminating the bottleneck.
-
-  1. Functionality
-
-    1.1 How it Works
-    1.2 Limitations
-    1.3 Locking and Concurrency
-
-  2. Compilation and Usage
-
-  3. Porting
-
-
-
-1. FUNCTIONALITY
-
-  With asynchronous I/O, write requests are handled by a separate thread
-  running in the background.  This means that the thread that initiates
-  a database write does not have to wait for (sometimes slow) disk I/O
-  to occur.  The write seems to happen very quickly, though in reality
-  it is happening at its usual slow pace in the background.
-
-  Asynchronous I/O appears to give better responsiveness, but at a price.
-  You lose the Durable property.  With the default I/O backend of SQLite,
-  once a write completes, you know that the information you wrote is
-  safely on disk.  With the asynchronous I/O, this is not the case.  If
-  your program crashes or if a power loss occurs after the database
-  write but before the asynchronous write thread has completed, then the
-  database change might never make it to disk and the next user of the
-  database might not see your change.
-
-  You lose Durability with asynchronous I/O, but you still retain the
-  other parts of ACID:  Atomic,  Consistent, and Isolated.  Many
-  appliations get along fine without the Durablity.
-
-  1.1 How it Works
-
-    Asynchronous I/O works by creating a special SQLite "vfs" structure
-    and registering it with sqlite3_vfs_register(). When files opened via 
-    this vfs are written to (using the vfs xWrite() method), the data is not 
-    written directly to disk, but is placed in the "write-queue" to be
-    handled by the background thread.
-
-    When files opened with the asynchronous vfs are read from 
-    (using the vfs xRead() method), the data is read from the file on 
-    disk and the write-queue, so that from the point of view of
-    the vfs reader the xWrite() appears to have already completed.
-
-    The special vfs is registered (and unregistered) by calls to the 
-    API functions sqlite3async_initialize() and sqlite3async_shutdown().
-    See section "Compilation and Usage" below for details.
-
-  1.2 Limitations
-
-    In order to gain experience with the main ideas surrounding asynchronous 
-    IO, this implementation is deliberately kept simple. Additional 
-    capabilities may be added in the future.
-
-    For example, as currently implemented, if writes are happening at a 
-    steady stream that exceeds the I/O capability of the background writer
-    thread, the queue of pending write operations will grow without bound.
-    If this goes on for long enough, the host system could run out of memory. 
-    A more sophisticated module could to keep track of the quantity of 
-    pending writes and stop accepting new write requests when the queue of 
-    pending writes grows too large.
-
-  1.3 Locking and Concurrency
-
-    Multiple connections from within a single process that use this
-    implementation of asynchronous IO may access a single database
-    file concurrently. From the point of view of the user, if all
-    connections are from within a single process, there is no difference
-    between the concurrency offered by "normal" SQLite and SQLite
-    using the asynchronous backend.
-
-    If file-locking is enabled (it is enabled by default), then connections
-    from multiple processes may also read and write the database file.
-    However concurrency is reduced as follows:
-
-      * When a connection using asynchronous IO begins a database
-        transaction, the database is locked immediately. However the
-        lock is not released until after all relevant operations
-        in the write-queue have been flushed to disk. This means
-        (for example) that the database may remain locked for some 
-        time after a "COMMIT" or "ROLLBACK" is issued.
-
-      * If an application using asynchronous IO executes transactions
-        in quick succession, other database users may be effectively
-        locked out of the database. This is because when a BEGIN
-        is executed, a database lock is established immediately. But
-        when the corresponding COMMIT or ROLLBACK occurs, the lock
-        is not released until the relevant part of the write-queue 
-        has been flushed through. As a result, if a COMMIT is followed
-        by a BEGIN before the write-queue is flushed through, the database 
-        is never unlocked,preventing other processes from accessing 
-        the database.
-
-    File-locking may be disabled at runtime using the sqlite3async_control()
-    API (see below). This may improve performance when an NFS or other 
-    network file-system, as the synchronous round-trips to the server be 
-    required to establish file locks are avoided. However, if multiple 
-    connections attempt to access the same database file when file-locking
-    is disabled, application crashes and database corruption is a likely
-    outcome.
-
-
-2. COMPILATION AND USAGE
-
-  The asynchronous IO extension consists of a single file of C code
-  (sqlite3async.c), and a header file (sqlite3async.h) that defines the 
-  C API used by applications to activate and control the modules 
-  functionality.
-
-  To use the asynchronous IO extension, compile sqlite3async.c as
-  part of the application that uses SQLite. Then use the API defined
-  in sqlite3async.h to initialize and configure the module.
-
-  The asynchronous IO VFS API is described in detail in comments in 
-  sqlite3async.h. Using the API usually consists of the following steps:
-
-    1. Register the asynchronous IO VFS with SQLite by calling the
-       sqlite3async_initialize() function.
-
-    2. Create a background thread to perform write operations and call
-       sqlite3async_run().
-
-    3. Use the normal SQLite API to read and write to databases via 
-       the asynchronous IO VFS.
-
-  Refer to sqlite3async.h for details.
-
-
-3. PORTING
-
-  Currently the asynchronous IO extension is compatible with win32 systems
-  and systems that support the pthreads interface, including Mac OSX, Linux, 
-  and other varieties of Unix. 
-
-  To port the asynchronous IO extension to another platform, the user must
-  implement mutex and condition variable primitives for the new platform.
-  Currently there is no externally available interface to allow this, but
-  modifying the code within sqlite3async.c to include the new platforms
-  concurrency primitives is relatively easy. Search within sqlite3async.c
-  for the comment string "PORTING FUNCTIONS" for details. Then implement
-  new versions of each of the following:
-
-    static void async_mutex_enter(int eMutex);
-    static void async_mutex_leave(int eMutex);
-    static void async_cond_wait(int eCond, int eMutex);
-    static void async_cond_signal(int eCond);
-    static void async_sched_yield(void);
-
-  The functionality required of each of the above functions is described
-  in comments in sqlite3async.c.
diff --git a/ext/async/sqlite3async.c b/ext/async/sqlite3async.c
deleted file mode 100644 (file)
index eed7c8d..0000000
+++ /dev/null
@@ -1,1706 +0,0 @@
-/*
-** 2005 December 14
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** $Id: sqlite3async.c,v 1.7 2009/07/18 11:52:04 danielk1977 Exp $
-**
-** This file contains the implementation of an asynchronous IO backend 
-** for SQLite.
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO)
-
-#include "sqlite3async.h"
-#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))
-#define MAX(x,y) ((x)>(y)?(x):(y))
-
-#ifndef SQLITE_AMALGAMATION
-/* Macro to mark parameters as unused and silence compiler warnings. */
-#define UNUSED_PARAMETER(x) (void)(x)
-#endif
-
-/* Forward references */
-typedef struct AsyncWrite AsyncWrite;
-typedef struct AsyncFile AsyncFile;
-typedef struct AsyncFileData AsyncFileData;
-typedef struct AsyncFileLock AsyncFileLock;
-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, ...){
-  char *z;
-  va_list ap;
-  va_start(ap, zFormat);
-  z = sqlite3_vmprintf(zFormat, ap);
-  va_end(ap);
-  fprintf(stderr, "[%d] %s", 0 /* (int)pthread_self() */, z);
-  sqlite3_free(z);
-}
-#else
-# define ASYNC_TRACE(X)
-#endif
-
-/*
-** THREAD SAFETY NOTES
-**
-** Basic rules:
-**
-**     * Both read and write access to the global write-op queue must be 
-**       protected by the async.queueMutex. As are the async.ioError and
-**       async.nFile variables.
-**
-**     * The async.pLock list and all AsyncLock and AsyncFileLock
-**       structures must be protected by the async.lockMutex mutex.
-**
-**     * The file handles from the underlying system are not assumed to 
-**       be thread safe.
-**
-**     * See the last two paragraphs under "The Writer Thread" for
-**       an assumption to do with file-handle synchronization by the Os.
-**
-** Deadlock prevention:
-**
-**     There are three mutex used by the system: the "writer" mutex, 
-**     the "queue" mutex and the "lock" mutex. Rules are:
-**
-**     * It is illegal to block on the writer mutex when any other mutex
-**       are held, and 
-**
-**     * It is illegal to block on the queue mutex when the lock mutex
-**       is held.
-**
-**     i.e. mutex's must be grabbed in the order "writer", "queue", "lock".
-**
-** File system operations (invoked by SQLite thread):
-**
-**     xOpen
-**     xDelete
-**     xFileExists
-**
-** File handle operations (invoked by SQLite thread):
-**
-**         asyncWrite, asyncClose, asyncTruncate, asyncSync 
-**    
-**     The operations above add an entry to the global write-op list. They
-**     prepare the entry, acquire the async.queueMutex momentarily while
-**     list pointers are  manipulated to insert the new entry, then release
-**     the mutex and signal the writer thread to wake up in case it happens
-**     to be asleep.
-**
-**    
-**         asyncRead, asyncFileSize.
-**
-**     Read operations. Both of these read from both the underlying file
-**     first then adjust their result based on pending writes in the 
-**     write-op queue.   So async.queueMutex is held for the duration
-**     of these operations to prevent other threads from changing the
-**     queue in mid operation.
-**    
-**
-**         asyncLock, asyncUnlock, asyncCheckReservedLock
-**    
-**     These primitives implement in-process locking using a hash table
-**     on the file name.  Files are locked correctly for connections coming
-**     from the same process.  But other processes cannot see these locks
-**     and will therefore not honor them.
-**
-**
-** The writer thread:
-**
-**     The async.writerMutex is used to make sure only there is only
-**     a single writer thread running at a time.
-**
-**     Inside the writer thread is a loop that works like this:
-**
-**         WHILE (write-op list is not empty)
-**             Do IO operation at head of write-op list
-**             Remove entry from head of write-op list
-**         END WHILE
-**
-**     The async.queueMutex is always held during the <write-op list is 
-**     not empty> test, and when the entry is removed from the head
-**     of the write-op list. Sometimes it is held for the interim
-**     period (while the IO is performed), and sometimes it is
-**     relinquished. It is relinquished if (a) the IO op is an
-**     ASYNC_CLOSE or (b) when the file handle was opened, two of
-**     the underlying systems handles were opened on the same
-**     file-system entry.
-**
-**     If condition (b) above is true, then one file-handle 
-**     (AsyncFile.pBaseRead) is used exclusively by sqlite threads to read the
-**     file, the other (AsyncFile.pBaseWrite) by sqlite3_async_flush() 
-**     threads to perform write() operations. This means that read 
-**     operations are not blocked by asynchronous writes (although 
-**     asynchronous writes may still be blocked by reads).
-**
-**     This assumes that the OS keeps two handles open on the same file
-**     properly in sync. That is, any read operation that starts after a
-**     write operation on the same file system entry has completed returns
-**     data consistent with the write. We also assume that if one thread 
-**     reads a file while another is writing it all bytes other than the
-**     ones actually being written contain valid data.
-**
-**     If the above assumptions are not true, set the preprocessor symbol
-**     SQLITE_ASYNC_TWO_FILEHANDLES to 0.
-*/
-
-
-#ifndef NDEBUG
-# define TESTONLY( X ) X
-#else
-# define TESTONLY( X )
-#endif
-
-/*
-** PORTING FUNCTIONS
-**
-** There are two definitions of the following functions. One for pthreads
-** compatible systems and one for Win32. These functions isolate the OS
-** specific code required by each platform.
-**
-** The system uses three mutexes and a single condition variable. To
-** block on a mutex, async_mutex_enter() is called. The parameter passed
-** to async_mutex_enter(), which must be one of ASYNC_MUTEX_LOCK,
-** ASYNC_MUTEX_QUEUE or ASYNC_MUTEX_WRITER, identifies which of the three
-** mutexes to lock. Similarly, to unlock a mutex, async_mutex_leave() is
-** called with a parameter identifying the mutex being unlocked. Mutexes
-** are not recursive - it is an error to call async_mutex_enter() to
-** lock a mutex that is already locked, or to call async_mutex_leave()
-** to unlock a mutex that is not currently locked.
-**
-** The async_cond_wait() and async_cond_signal() functions are modelled
-** on the pthreads functions with similar names. The first parameter to
-** both functions is always ASYNC_COND_QUEUE. When async_cond_wait()
-** is called the mutex identified by the second parameter must be held.
-** The mutex is unlocked, and the calling thread simultaneously begins 
-** waiting for the condition variable to be signalled by another thread.
-** After another thread signals the condition variable, the calling
-** thread stops waiting, locks mutex eMutex and returns. The 
-** async_cond_signal() function is used to signal the condition variable. 
-** It is assumed that the mutex used by the thread calling async_cond_wait() 
-** is held by the caller of async_cond_signal() (otherwise there would be 
-** a race condition).
-**
-** It is guaranteed that no other thread will call async_cond_wait() when
-** there is already a thread waiting on the condition variable.
-**
-** The async_sched_yield() function is called to suggest to the operating
-** system that it would be a good time to shift the current thread off the
-** CPU. The system will still work if this function is not implemented
-** (it is not currently implemented for win32), but it might be marginally
-** more efficient if it is.
-*/
-static void async_mutex_enter(int eMutex);
-static void async_mutex_leave(int eMutex);
-static void async_cond_wait(int eCond, int eMutex);
-static void async_cond_signal(int eCond);
-static void async_sched_yield(void);
-
-/*
-** There are also two definitions of the following. async_os_initialize()
-** is called when the asynchronous VFS is first installed, and os_shutdown()
-** is called when it is uninstalled (from within sqlite3async_shutdown()).
-**
-** For pthreads builds, both of these functions are no-ops. For win32,
-** they provide an opportunity to initialize and finalize the required
-** mutex and condition variables.
-**
-** If async_os_initialize() returns other than zero, then the initialization
-** fails and SQLITE_ERROR is returned to the user.
-*/
-static int async_os_initialize(void);
-static void async_os_shutdown(void);
-
-/* Values for use as the 'eMutex' argument of the above functions. The
-** integer values assigned to these constants are important for assert()
-** statements that verify that mutexes are locked in the correct order.
-** Specifically, it is unsafe to try to lock mutex N while holding a lock 
-** on mutex M if (M<=N).
-*/
-#define ASYNC_MUTEX_LOCK    0
-#define ASYNC_MUTEX_QUEUE   1
-#define ASYNC_MUTEX_WRITER  2
-
-/* Values for use as the 'eCond' argument of the above functions. */
-#define ASYNC_COND_QUEUE    0
-
-/*************************************************************************
-** Start of OS specific code.
-*/
-#if SQLITE_OS_WIN || defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
-
-#include <windows.h>
-
-/* The following block contains the win32 specific code. */
-
-#define mutex_held(X) (GetCurrentThreadId()==primitives.aHolder[X])
-
-static struct AsyncPrimitives {
-  int isInit;
-  DWORD aHolder[3];
-  CRITICAL_SECTION aMutex[3];
-  HANDLE aCond[1];
-} primitives = { 0 };
-
-static int async_os_initialize(void){
-  if( !primitives.isInit ){
-    primitives.aCond[0] = CreateEvent(NULL, TRUE, FALSE, 0);
-    if( primitives.aCond[0]==NULL ){
-      return 1;
-    }
-    InitializeCriticalSection(&primitives.aMutex[0]);
-    InitializeCriticalSection(&primitives.aMutex[1]);
-    InitializeCriticalSection(&primitives.aMutex[2]);
-    primitives.isInit = 1;
-  }
-  return 0;
-}
-static void async_os_shutdown(void){
-  if( primitives.isInit ){
-    DeleteCriticalSection(&primitives.aMutex[0]);
-    DeleteCriticalSection(&primitives.aMutex[1]);
-    DeleteCriticalSection(&primitives.aMutex[2]);
-    CloseHandle(primitives.aCond[0]);
-    primitives.isInit = 0;
-  }
-}
-
-/* The following block contains the Win32 specific code. */
-static void async_mutex_enter(int eMutex){
-  assert( eMutex==0 || eMutex==1 || eMutex==2 );
-  assert( eMutex!=2 || (!mutex_held(0) && !mutex_held(1) && !mutex_held(2)) );
-  assert( eMutex!=1 || (!mutex_held(0) && !mutex_held(1)) );
-  assert( eMutex!=0 || (!mutex_held(0)) );
-  EnterCriticalSection(&primitives.aMutex[eMutex]);
-  TESTONLY( primitives.aHolder[eMutex] = GetCurrentThreadId(); )
-}
-static void async_mutex_leave(int eMutex){
-  assert( eMutex==0 || eMutex==1 || eMutex==2 );
-  assert( mutex_held(eMutex) );
-  TESTONLY( primitives.aHolder[eMutex] = 0; )
-  LeaveCriticalSection(&primitives.aMutex[eMutex]);
-}
-static void async_cond_wait(int eCond, int eMutex){
-  ResetEvent(primitives.aCond[eCond]);
-  async_mutex_leave(eMutex);
-  WaitForSingleObject(primitives.aCond[eCond], INFINITE);
-  async_mutex_enter(eMutex);
-}
-static void async_cond_signal(int eCond){
-  assert( mutex_held(ASYNC_MUTEX_QUEUE) );
-  SetEvent(primitives.aCond[eCond]);
-}
-static void async_sched_yield(void){
-  Sleep(0);
-}
-#else
-
-/* The following block contains the pthreads specific code. */
-#include <pthread.h>
-#include <sched.h>
-
-#define mutex_held(X) pthread_equal(primitives.aHolder[X], pthread_self())
-
-static int  async_os_initialize(void) {return 0;}
-static void async_os_shutdown(void) {}
-
-static struct AsyncPrimitives {
-  pthread_mutex_t aMutex[3];
-  pthread_cond_t aCond[1];
-  pthread_t aHolder[3];
-} primitives = {
-  { PTHREAD_MUTEX_INITIALIZER, 
-    PTHREAD_MUTEX_INITIALIZER, 
-    PTHREAD_MUTEX_INITIALIZER
-  } , {
-    PTHREAD_COND_INITIALIZER
-  } , { 0, 0, 0 }
-};
-
-static void async_mutex_enter(int eMutex){
-  assert( eMutex==0 || eMutex==1 || eMutex==2 );
-  assert( eMutex!=2 || (!mutex_held(0) && !mutex_held(1) && !mutex_held(2)) );
-  assert( eMutex!=1 || (!mutex_held(0) && !mutex_held(1)) );
-  assert( eMutex!=0 || (!mutex_held(0)) );
-  pthread_mutex_lock(&primitives.aMutex[eMutex]);
-  TESTONLY( primitives.aHolder[eMutex] = pthread_self(); )
-}
-static void async_mutex_leave(int eMutex){
-  assert( eMutex==0 || eMutex==1 || eMutex==2 );
-  assert( mutex_held(eMutex) );
-  TESTONLY( primitives.aHolder[eMutex] = 0; )
-  pthread_mutex_unlock(&primitives.aMutex[eMutex]);
-}
-static void async_cond_wait(int eCond, int eMutex){
-  assert( eMutex==0 || eMutex==1 || eMutex==2 );
-  assert( mutex_held(eMutex) );
-  TESTONLY( primitives.aHolder[eMutex] = 0; )
-  pthread_cond_wait(&primitives.aCond[eCond], &primitives.aMutex[eMutex]);
-  TESTONLY( primitives.aHolder[eMutex] = pthread_self(); )
-}
-static void async_cond_signal(int eCond){
-  assert( mutex_held(ASYNC_MUTEX_QUEUE) );
-  pthread_cond_signal(&primitives.aCond[eCond]);
-}
-static void async_sched_yield(void){
-  sched_yield();
-}
-#endif
-/*
-** End of OS specific code.
-*************************************************************************/
-
-#define assert_mutex_is_held(X) assert( mutex_held(X) )
-
-
-#ifndef SQLITE_ASYNC_TWO_FILEHANDLES
-/* #define SQLITE_ASYNC_TWO_FILEHANDLES 0 */
-#define SQLITE_ASYNC_TWO_FILEHANDLES 1
-#endif
-
-/*
-** State information is held in the static variable "async" defined
-** as the following structure.
-**
-** Both async.ioError and async.nFile are protected by async.queueMutex.
-*/
-static struct TestAsyncStaticData {
-  AsyncWrite *pQueueFirst;     /* Next write operation to be processed */
-  AsyncWrite *pQueueLast;      /* Last write operation on the list */
-  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,1,0,0 };
-
-/* Possible values of AsyncWrite.op */
-#define ASYNC_NOOP          0
-#define ASYNC_WRITE         1
-#define ASYNC_SYNC          2
-#define ASYNC_TRUNCATE      3
-#define ASYNC_CLOSE         4
-#define ASYNC_DELETE        5
-#define ASYNC_OPENEXCLUSIVE 6
-#define ASYNC_UNLOCK        7
-
-/* 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", "DELETE", "OPENEX", "UNLOCK"
-};
-
-/*
-** Entries on the write-op queue are instances of the AsyncWrite
-** structure, defined here.
-**
-** 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).
-**
-** ASYNC_SYNC:
-**     nByte   -> flags to pass to sqlite3OsSync().
-**
-** ASYNC_TRUNCATE:
-**     iOffset -> Size to truncate file to.
-**     nByte   -> Unused.
-**
-** ASYNC_CLOSE:
-**     iOffset -> Unused.
-**     nByte   -> Unused.
-**
-** ASYNC_DELETE:
-**     iOffset -> Contains the "syncDir" flag.
-**     nByte   -> Number of bytes of zBuf points to (file name).
-**
-** ASYNC_OPENEXCLUSIVE:
-**     iOffset -> Value of "delflag".
-**     nByte   -> Number of bytes of zBuf points to (file name).
-**
-** ASYNC_UNLOCK:
-**     nByte   -> Argument to sqlite3OsUnlock().
-**
-**
-** For an ASYNC_WRITE operation, zBuf points to the data to write to the file. 
-** This space is sqlite3_malloc()d along with the AsyncWrite structure in a
-** single blob, so is deleted when sqlite3_free() is called on the parent 
-** structure.
-*/
-struct AsyncWrite {
-  AsyncFileData *pFileData;    /* File to write data to or sync */
-  int op;                      /* One of ASYNC_xxx etc. */
-  sqlite_int64 iOffset;        /* See above */
-  int nByte;          /* See above */
-  char *zBuf;         /* Data to write to file (or NULL if op!=ASYNC_WRITE) */
-  AsyncWrite *pNext;  /* Next write operation (to any file) */
-};
-
-/*
-** An instance of this structure is created for each distinct open file 
-** (i.e. if two handles are opened on the one file, only one of these
-** structures is allocated) and stored in the async.aLock hash table. The
-** keys for async.aLock are the full pathnames of the opened files.
-**
-** AsyncLock.pList points to the head of a linked list of AsyncFileLock
-** 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 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.
-*/
-struct AsyncLock {
-  char *zFile;
-  int nFile;
-  sqlite3_file *pFile;
-  int eLock;
-  AsyncFileLock *pList;
-  AsyncLock *pNext;           /* Next in linked list headed by async.pLock */
-};
-
-/*
-** 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.
-*/
-struct AsyncFileLock {
-  int eLock;                /* Internally visible lock state (sqlite pov) */
-  int eAsyncLock;           /* Lock-state with write-queue unlock */
-  AsyncFileLock *pNext;
-};
-
-/* 
-** The AsyncFile structure is a subclass of sqlite3_file used for 
-** asynchronous IO. 
-**
-** All of the actual data for the structure is stored in the structure
-** pointed to by AsyncFile.pData, which is allocated as part of the
-** sqlite3OsOpen() using sqlite3_malloc(). The reason for this is that the
-** lifetime of the AsyncFile structure is ended by the caller after OsClose()
-** is called, but the data in AsyncFileData may be required by the
-** writer thread after that point.
-*/
-struct AsyncFile {
-  sqlite3_io_methods *pMethod;
-  AsyncFileData *pData;
-};
-struct AsyncFileData {
-  char *zName;               /* Underlying OS filename - used for debugging */
-  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 */
-  AsyncFileLock lock;        /* Lock state for this handle */
-  AsyncLock *pLock;          /* AsyncLock object for this file system entry */
-  AsyncWrite closeOp;        /* Preallocated close operation */
-};
-
-/*
-** Add an entry to the end of the global write-op list. pWrite should point 
-** to an AsyncWrite structure allocated using sqlite3_malloc().  The writer
-** thread will call sqlite3_free() to free the structure after the specified
-** operation has been completed.
-**
-** Once an AsyncWrite structure has been added to the list, it becomes the
-** property of the writer thread and must not be read or modified by the
-** caller.  
-*/
-static void addAsyncWrite(AsyncWrite *pWrite){
-  /* We must hold the queue mutex in order to modify the queue pointers */
-  if( pWrite->op!=ASYNC_UNLOCK ){
-    async_mutex_enter(ASYNC_MUTEX_QUEUE);
-  }
-
-  /* Add the record to the end of the write-op queue */
-  assert( !pWrite->pNext );
-  if( async.pQueueLast ){
-    assert( async.pQueueFirst );
-    async.pQueueLast->pNext = pWrite;
-  }else{
-    async.pQueueFirst = pWrite;
-  }
-  async.pQueueLast = pWrite;
-  ASYNC_TRACE(("PUSH %p (%s %s %d)\n", pWrite, azOpcodeName[pWrite->op],
-         pWrite->pFileData ? pWrite->pFileData->zName : "-", pWrite->iOffset));
-
-  if( pWrite->op==ASYNC_CLOSE ){
-    async.nFile--;
-  }
-
-  /* The writer thread might have been idle because there was nothing
-  ** on the write-op queue for it to do.  So wake it up. */
-  async_cond_signal(ASYNC_COND_QUEUE);
-
-  /* Drop the queue mutex */
-  if( pWrite->op!=ASYNC_UNLOCK ){
-    async_mutex_leave(ASYNC_MUTEX_QUEUE);
-  }
-}
-
-/*
-** Increment async.nFile in a thread-safe manner.
-*/
-static void incrOpenFileCount(void){
-  /* We must hold the queue mutex in order to modify async.nFile */
-  async_mutex_enter(ASYNC_MUTEX_QUEUE);
-  if( async.nFile==0 ){
-    async.ioError = SQLITE_OK;
-  }
-  async.nFile++;
-  async_mutex_leave(ASYNC_MUTEX_QUEUE);
-}
-
-/*
-** This is a utility function to allocate and populate a new AsyncWrite
-** structure and insert it (via addAsyncWrite() ) into the global list.
-*/
-static int addNewAsyncWrite(
-  AsyncFileData *pFileData, 
-  int op, 
-  sqlite3_int64 iOffset, 
-  int nByte,
-  const char *zByte
-){
-  AsyncWrite *p;
-  if( op!=ASYNC_CLOSE && async.ioError ){
-    return async.ioError;
-  }
-  p = sqlite3_malloc(sizeof(AsyncWrite) + (zByte?nByte:0));
-  if( !p ){
-    /* The upper layer does not expect operations like OsWrite() to
-    ** return SQLITE_NOMEM. This is partly because under normal conditions
-    ** SQLite is required to do rollback without calling malloc(). So
-    ** if malloc() fails here, treat it as an I/O error. The above
-    ** layer knows how to handle that.
-    */
-    return SQLITE_IOERR;
-  }
-  p->op = op;
-  p->iOffset = iOffset;
-  p->nByte = nByte;
-  p->pFileData = pFileData;
-  p->pNext = 0;
-  if( zByte ){
-    p->zBuf = (char *)&p[1];
-    memcpy(p->zBuf, zByte, nByte);
-  }else{
-    p->zBuf = 0;
-  }
-  addAsyncWrite(p);
-  return SQLITE_OK;
-}
-
-/*
-** Close the file. This just adds an entry to the write-op list, the file is
-** not actually closed.
-*/
-static int asyncClose(sqlite3_file *pFile){
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-
-  /* Unlock the file, if it is locked */
-  async_mutex_enter(ASYNC_MUTEX_LOCK);
-  p->lock.eLock = 0;
-  async_mutex_leave(ASYNC_MUTEX_LOCK);
-
-  addAsyncWrite(&p->closeOp);
-  return SQLITE_OK;
-}
-
-/*
-** Implementation of sqlite3OsWrite() for asynchronous files. Instead of 
-** writing to the underlying file, this function adds an entry to the end of
-** the global AsyncWrite list. Either SQLITE_OK or SQLITE_NOMEM may be
-** returned.
-*/
-static int asyncWrite(
-  sqlite3_file *pFile, 
-  const void *pBuf, 
-  int amt, 
-  sqlite3_int64 iOff
-){
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  return addNewAsyncWrite(p, ASYNC_WRITE, iOff, amt, pBuf);
-}
-
-/*
-** Read data from the file. First we read from the filesystem, then adjust 
-** the contents of the buffer based on ASYNC_WRITE operations in the 
-** write-op queue.
-**
-** This method holds the mutex from start to finish.
-*/
-static int asyncRead(
-  sqlite3_file *pFile, 
-  void *zOut, 
-  int iAmt, 
-  sqlite3_int64 iOffset
-){
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  int rc = SQLITE_OK;
-  sqlite3_int64 filesize = 0;
-  sqlite3_file *pBase = p->pBaseRead;
-  sqlite3_int64 iAmt64 = (sqlite3_int64)iAmt;
-
-  /* Grab the write queue mutex for the duration of the call */
-  async_mutex_enter(ASYNC_MUTEX_QUEUE);
-
-  /* If an I/O error has previously occurred in this virtual file 
-  ** system, then all subsequent operations fail.
-  */
-  if( async.ioError!=SQLITE_OK ){
-    rc = async.ioError;
-    goto asyncread_out;
-  }
-
-  if( pBase->pMethods ){
-    sqlite3_int64 nRead;
-    rc = pBase->pMethods->xFileSize(pBase, &filesize);
-    if( rc!=SQLITE_OK ){
-      goto asyncread_out;
-    }
-    nRead = MIN(filesize - iOffset, iAmt64);
-    if( nRead>0 ){
-      rc = pBase->pMethods->xRead(pBase, zOut, (int)nRead, iOffset);
-      ASYNC_TRACE(("READ %s %d bytes at %d\n", p->zName, nRead, iOffset));
-    }
-  }
-
-  if( rc==SQLITE_OK ){
-    AsyncWrite *pWrite;
-    char *zName = p->zName;
-
-    for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){
-      if( pWrite->op==ASYNC_WRITE && (
-        (pWrite->pFileData==p) ||
-        (zName && pWrite->pFileData->zName==zName)
-      )){
-        sqlite3_int64 nCopy;
-        sqlite3_int64 nByte64 = (sqlite3_int64)pWrite->nByte;
-
-        /* Set variable iBeginIn to the offset in buffer pWrite->zBuf[] from
-        ** which data should be copied. Set iBeginOut to the offset within
-        ** the output buffer to which data should be copied. If either of
-        ** these offsets is a negative number, set them to 0.
-        */
-        sqlite3_int64 iBeginOut = (pWrite->iOffset-iOffset);
-        sqlite3_int64 iBeginIn = -iBeginOut;
-        if( iBeginIn<0 ) iBeginIn = 0;
-        if( iBeginOut<0 ) iBeginOut = 0;
-
-        filesize = MAX(filesize, pWrite->iOffset+nByte64);
-
-        nCopy = MIN(nByte64-iBeginIn, iAmt64-iBeginOut);
-        if( nCopy>0 ){
-          memcpy(&((char *)zOut)[iBeginOut], &pWrite->zBuf[iBeginIn], (size_t)nCopy);
-          ASYNC_TRACE(("OVERREAD %d bytes at %d\n", nCopy, iBeginOut+iOffset));
-        }
-      }
-    }
-  }
-
-asyncread_out:
-  async_mutex_leave(ASYNC_MUTEX_QUEUE);
-  if( rc==SQLITE_OK && filesize<(iOffset+iAmt) ){
-    rc = SQLITE_IOERR_SHORT_READ;
-  }
-  return rc;
-}
-
-/*
-** Truncate the file to nByte bytes in length. This just adds an entry to 
-** the write-op list, no IO actually takes place.
-*/
-static int asyncTruncate(sqlite3_file *pFile, sqlite3_int64 nByte){
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  return addNewAsyncWrite(p, ASYNC_TRUNCATE, nByte, 0, 0);
-}
-
-/*
-** Sync the file. This just adds an entry to the write-op list, the 
-** sync() is done later by sqlite3_async_flush().
-*/
-static int asyncSync(sqlite3_file *pFile, int flags){
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  return addNewAsyncWrite(p, ASYNC_SYNC, 0, flags, 0);
-}
-
-/*
-** Read the size of the file. First we read the size of the file system 
-** entry, then adjust for any ASYNC_WRITE or ASYNC_TRUNCATE operations 
-** currently in the write-op list. 
-**
-** This method holds the mutex from start to finish.
-*/
-int asyncFileSize(sqlite3_file *pFile, sqlite3_int64 *piSize){
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  int rc = SQLITE_OK;
-  sqlite3_int64 s = 0;
-  sqlite3_file *pBase;
-
-  async_mutex_enter(ASYNC_MUTEX_QUEUE);
-
-  /* Read the filesystem size from the base file. If pMethods is NULL, this
-  ** means the file hasn't been opened yet. In this case all relevant data 
-  ** must be in the write-op queue anyway, so we can omit reading from the
-  ** file-system.
-  */
-  pBase = p->pBaseRead;
-  if( pBase->pMethods ){
-    rc = pBase->pMethods->xFileSize(pBase, &s);
-  }
-
-  if( rc==SQLITE_OK ){
-    AsyncWrite *pWrite;
-    for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){
-      if( pWrite->op==ASYNC_DELETE 
-       && p->zName 
-       && strcmp(p->zName, pWrite->zBuf)==0 
-      ){
-        s = 0;
-      }else if( pWrite->pFileData && (
-          (pWrite->pFileData==p) 
-       || (p->zName && pWrite->pFileData->zName==p->zName) 
-      )){
-        switch( pWrite->op ){
-          case ASYNC_WRITE:
-            s = MAX(pWrite->iOffset + (sqlite3_int64)(pWrite->nByte), s);
-            break;
-          case ASYNC_TRUNCATE:
-            s = MIN(s, pWrite->iOffset);
-            break;
-        }
-      }
-    }
-    *piSize = s;
-  }
-  async_mutex_leave(ASYNC_MUTEX_QUEUE);
-  return rc;
-}
-
-/*
-** Lock or unlock the actual file-system entry.
-*/
-static int getFileLock(AsyncLock *pLock){
-  int rc = SQLITE_OK;
-  AsyncFileLock *pIter;
-  int eRequired = 0;
-
-  if( pLock->pFile ){
-    for(pIter=pLock->pList; pIter; pIter=pIter->pNext){
-      assert(pIter->eAsyncLock>=pIter->eLock);
-      if( pIter->eAsyncLock>eRequired ){
-        eRequired = pIter->eAsyncLock;
-        assert(eRequired>=0 && eRequired<=SQLITE_LOCK_EXCLUSIVE);
-      }
-    }
-
-    if( eRequired>pLock->eLock ){
-      rc = pLock->pFile->pMethods->xLock(pLock->pFile, eRequired);
-      if( rc==SQLITE_OK ){
-        pLock->eLock = eRequired;
-      }
-    }
-    else if( eRequired<pLock->eLock && eRequired<=SQLITE_LOCK_SHARED ){
-      rc = pLock->pFile->pMethods->xUnlock(pLock->pFile, eRequired);
-      if( rc==SQLITE_OK ){
-        pLock->eLock = eRequired;
-      }
-    }
-  }
-
-  return rc;
-}
-
-/*
-** Return the AsyncLock structure from the global async.pLock list 
-** associated with the file-system entry identified by path zName 
-** (a string of nName bytes). If no such structure exists, return 0.
-*/
-static AsyncLock *findLock(const char *zName, int nName){
-  AsyncLock *p = async.pLock;
-  while( p && (p->nFile!=nName || memcmp(p->zFile, zName, nName)) ){
-    p = p->pNext;
-  }
-  return p;
-}
-
-/*
-** The following two methods - asyncLock() and asyncUnlock() - are used
-** to obtain and release locks on database files opened with the
-** asynchronous backend.
-*/
-static int asyncLock(sqlite3_file *pFile, int eLock){
-  int rc = SQLITE_OK;
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-
-  if( p->zName ){
-    async_mutex_enter(ASYNC_MUTEX_LOCK);
-    if( p->lock.eLock<eLock ){
-      AsyncLock *pLock = p->pLock;
-      AsyncFileLock *pIter;
-      assert(pLock && pLock->pList);
-      for(pIter=pLock->pList; pIter; pIter=pIter->pNext){
-        if( pIter!=&p->lock && (
-          (eLock==SQLITE_LOCK_EXCLUSIVE && pIter->eLock>=SQLITE_LOCK_SHARED) ||
-          (eLock==SQLITE_LOCK_PENDING && pIter->eLock>=SQLITE_LOCK_RESERVED) ||
-          (eLock==SQLITE_LOCK_RESERVED && pIter->eLock>=SQLITE_LOCK_RESERVED) ||
-          (eLock==SQLITE_LOCK_SHARED && pIter->eLock>=SQLITE_LOCK_PENDING)
-        )){
-          rc = SQLITE_BUSY;
-        }
-      }
-      if( rc==SQLITE_OK ){
-        p->lock.eLock = eLock;
-        p->lock.eAsyncLock = MAX(p->lock.eAsyncLock, eLock);
-      }
-      assert(p->lock.eAsyncLock>=p->lock.eLock);
-      if( rc==SQLITE_OK ){
-        rc = getFileLock(pLock);
-      }
-    }
-    async_mutex_leave(ASYNC_MUTEX_LOCK);
-  }
-
-  ASYNC_TRACE(("LOCK %d (%s) rc=%d\n", eLock, p->zName, rc));
-  return rc;
-}
-static int asyncUnlock(sqlite3_file *pFile, int eLock){
-  int rc = SQLITE_OK;
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-  if( p->zName ){
-    AsyncFileLock *pLock = &p->lock;
-    async_mutex_enter(ASYNC_MUTEX_QUEUE);
-    async_mutex_enter(ASYNC_MUTEX_LOCK);
-    pLock->eLock = MIN(pLock->eLock, eLock);
-    rc = addNewAsyncWrite(p, ASYNC_UNLOCK, 0, eLock, 0);
-    async_mutex_leave(ASYNC_MUTEX_LOCK);
-    async_mutex_leave(ASYNC_MUTEX_QUEUE);
-  }
-  return rc;
-}
-
-/*
-** 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 *pResOut){
-  int ret = 0;
-  AsyncFileLock *pIter;
-  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
-
-  async_mutex_enter(ASYNC_MUTEX_LOCK);
-  for(pIter=p->pLock->pList; pIter; pIter=pIter->pNext){
-    if( pIter->eLock>=SQLITE_LOCK_RESERVED ){
-      ret = 1;
-      break;
-    }
-  }
-  async_mutex_leave(ASYNC_MUTEX_LOCK);
-
-  ASYNC_TRACE(("CHECK-LOCK %d (%s)\n", ret, p->zName));
-  *pResOut = ret;
-  return SQLITE_OK;
-}
-
-/* 
-** sqlite3_file_control() implementation.
-*/
-static int asyncFileControl(sqlite3_file *id, int op, void *pArg){
-  switch( op ){
-    case SQLITE_FCNTL_LOCKSTATE: {
-      async_mutex_enter(ASYNC_MUTEX_LOCK);
-      *(int*)pArg = ((AsyncFile*)id)->pData->lock.eLock;
-      async_mutex_leave(ASYNC_MUTEX_LOCK);
-      return SQLITE_OK;
-    }
-  }
-  return SQLITE_NOTFOUND;
-}
-
-/* 
-** Return the device characteristics and sector-size of the device. It
-** is tricky to implement these correctly, as this backend might 
-** not have an open file handle at this point.
-*/
-static int asyncSectorSize(sqlite3_file *pFile){
-  UNUSED_PARAMETER(pFile);
-  return 512;
-}
-static int asyncDeviceCharacteristics(sqlite3_file *pFile){
-  UNUSED_PARAMETER(pFile);
-  return 0;
-}
-
-static int unlinkAsyncFile(AsyncFileData *pData){
-  AsyncFileLock **ppIter;
-  int rc = SQLITE_OK;
-
-  if( pData->zName ){
-    AsyncLock *pLock = pData->pLock;
-    for(ppIter=&pLock->pList; *ppIter; ppIter=&((*ppIter)->pNext)){
-      if( (*ppIter)==&pData->lock ){
-        *ppIter = pData->lock.pNext;
-        break;
-      }
-    }
-    if( !pLock->pList ){
-      AsyncLock **pp;
-      if( pLock->pFile ){
-        pLock->pFile->pMethods->xClose(pLock->pFile);
-      }
-      for(pp=&async.pLock; *pp!=pLock; pp=&((*pp)->pNext));
-      *pp = pLock->pNext;
-      sqlite3_free(pLock);
-    }else{
-      rc = getFileLock(pLock);
-    }
-  }
-
-  return rc;
-}
-
-/*
-** The parameter passed to this function is a copy of a 'flags' parameter
-** passed to this modules xOpen() method. This function returns true
-** if the file should be opened asynchronously, or false if it should
-** be opened immediately.
-**
-** If the file is to be opened asynchronously, then asyncOpen() will add
-** an entry to the event queue and the file will not actually be opened
-** until the event is processed. Otherwise, the file is opened directly
-** by the caller.
-*/
-static int doAsynchronousOpen(int flags){
-  return (flags&SQLITE_OPEN_CREATE) && (
-      (flags&SQLITE_OPEN_MAIN_JOURNAL) ||
-      (flags&SQLITE_OPEN_TEMP_JOURNAL) ||
-      (flags&SQLITE_OPEN_DELETEONCLOSE)
-  );
-}
-
-/*
-** Open a file.
-*/
-static int asyncOpen(
-  sqlite3_vfs *pAsyncVfs,
-  const char *zName,
-  sqlite3_file *pFile,
-  int flags,
-  int *pOutFlags
-){
-  static sqlite3_io_methods async_methods = {
-    1,                               /* iVersion */
-    asyncClose,                      /* xClose */
-    asyncRead,                       /* xRead */
-    asyncWrite,                      /* xWrite */
-    asyncTruncate,                   /* xTruncate */
-    asyncSync,                       /* xSync */
-    asyncFileSize,                   /* xFileSize */
-    asyncLock,                       /* xLock */
-    asyncUnlock,                     /* xUnlock */
-    asyncCheckReservedLock,          /* xCheckReservedLock */
-    asyncFileControl,                /* xFileControl */
-    asyncSectorSize,                 /* xSectorSize */
-    asyncDeviceCharacteristics       /* xDeviceCharacteristics */
-  };
-
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  AsyncFile *p = (AsyncFile *)pFile;
-  int nName = 0;
-  int rc = SQLITE_OK;
-  int nByte;
-  AsyncFileData *pData;
-  AsyncLock *pLock = 0;
-  char *z;
-  int isAsyncOpen = doAsynchronousOpen(flags);
-
-  /* If zName is NULL, then the upper layer is requesting an anonymous file.
-  ** Otherwise, allocate enough space to make a copy of the file name (along
-  ** with the second nul-terminator byte required by xOpen).
-  */
-  if( zName ){
-    nName = (int)strlen(zName);
-  }
-
-  nByte = (
-    sizeof(AsyncFileData) +        /* AsyncFileData structure */
-    2 * pVfs->szOsFile +           /* AsyncFileData.pBaseRead and pBaseWrite */
-    nName + 2                      /* AsyncFileData.zName */
-  ); 
-  z = sqlite3_malloc(nByte);
-  if( !z ){
-    return SQLITE_NOMEM;
-  }
-  memset(z, 0, nByte);
-  pData = (AsyncFileData*)z;
-  z += sizeof(pData[0]);
-  pData->pBaseRead = (sqlite3_file*)z;
-  z += pVfs->szOsFile;
-  pData->pBaseWrite = (sqlite3_file*)z;
-  pData->closeOp.pFileData = pData;
-  pData->closeOp.op = ASYNC_CLOSE;
-
-  if( zName ){
-    z += pVfs->szOsFile;
-    pData->zName = z;
-    pData->nName = nName;
-    memcpy(pData->zName, zName, nName);
-  }
-
-  if( !isAsyncOpen ){
-    int flagsout;
-    rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseRead, flags, &flagsout);
-    if( rc==SQLITE_OK 
-     && (flagsout&SQLITE_OPEN_READWRITE) 
-     && (flags&SQLITE_OPEN_EXCLUSIVE)==0
-    ){
-      rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseWrite, flags, 0);
-    }
-    if( pOutFlags ){
-      *pOutFlags = flagsout;
-    }
-  }
-
-  async_mutex_enter(ASYNC_MUTEX_LOCK);
-
-  if( zName && rc==SQLITE_OK ){
-    pLock = findLock(pData->zName, pData->nName);
-    if( !pLock ){
-      int nByte = pVfs->szOsFile + sizeof(AsyncLock) + pData->nName + 1; 
-      pLock = (AsyncLock *)sqlite3_malloc(nByte);
-      if( pLock ){
-        memset(pLock, 0, nByte);
-        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 ){
-            sqlite3_free(pLock);
-            pLock = 0;
-          }
-        }
-        if( pLock ){
-          pLock->nFile = pData->nName;
-          pLock->zFile = &((char *)(&pLock[1]))[pVfs->szOsFile];
-          memcpy(pLock->zFile, pData->zName, pLock->nFile);
-          pLock->pNext = async.pLock;
-          async.pLock = pLock;
-        }
-      }else{
-        rc = SQLITE_NOMEM;
-      }
-    }
-  }
-
-  if( rc==SQLITE_OK ){
-    p->pMethod = &async_methods;
-    p->pData = pData;
-
-    /* Link AsyncFileData.lock into the linked list of 
-    ** AsyncFileLock structures for this file.
-    */
-    if( zName ){
-      pData->lock.pNext = pLock->pList;
-      pLock->pList = &pData->lock;
-      pData->zName = pLock->zFile;
-    }
-  }else{
-    if( pData->pBaseRead->pMethods ){
-      pData->pBaseRead->pMethods->xClose(pData->pBaseRead);
-    }
-    if( pData->pBaseWrite->pMethods ){
-      pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite);
-    }
-    sqlite3_free(pData);
-  }
-
-  async_mutex_leave(ASYNC_MUTEX_LOCK);
-
-  if( rc==SQLITE_OK ){
-    pData->pLock = pLock;
-  }
-
-  if( rc==SQLITE_OK && isAsyncOpen ){
-    rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (sqlite3_int64)flags,0,0);
-    if( rc==SQLITE_OK ){
-      if( pOutFlags ) *pOutFlags = flags;
-    }else{
-      async_mutex_enter(ASYNC_MUTEX_LOCK);
-      unlinkAsyncFile(pData);
-      async_mutex_leave(ASYNC_MUTEX_LOCK);
-      sqlite3_free(pData);
-    }
-  }
-  if( rc!=SQLITE_OK ){
-    p->pMethod = 0;
-  }else{
-    incrOpenFileCount();
-  }
-
-  return rc;
-}
-
-/*
-** Implementation of sqlite3OsDelete. Add an entry to the end of the 
-** write-op queue to perform the delete.
-*/
-static int asyncDelete(sqlite3_vfs *pAsyncVfs, const char *z, int syncDir){
-  UNUSED_PARAMETER(pAsyncVfs);
-  return addNewAsyncWrite(0, ASYNC_DELETE, syncDir, (int)strlen(z)+1, z);
-}
-
-/*
-** Implementation of sqlite3OsAccess. This method holds the mutex from
-** start to finish.
-*/
-static int asyncAccess(
-  sqlite3_vfs *pAsyncVfs, 
-  const char *zName, 
-  int flags,
-  int *pResOut
-){
-  int rc;
-  int ret;
-  AsyncWrite *p;
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-
-  assert(flags==SQLITE_ACCESS_READWRITE 
-      || flags==SQLITE_ACCESS_READ 
-      || flags==SQLITE_ACCESS_EXISTS 
-  );
-
-  async_mutex_enter(ASYNC_MUTEX_QUEUE);
-  rc = pVfs->xAccess(pVfs, zName, flags, &ret);
-  if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
-    for(p=async.pQueueFirst; p; p = p->pNext){
-      if( p->op==ASYNC_DELETE && 0==strcmp(p->zBuf, zName) ){
-        ret = 0;
-      }else if( p->op==ASYNC_OPENEXCLUSIVE 
-             && p->pFileData->zName
-             && 0==strcmp(p->pFileData->zName, zName) 
-      ){
-        ret = 1;
-      }
-    }
-  }
-  ASYNC_TRACE(("ACCESS(%s): %s = %d\n", 
-    flags==SQLITE_ACCESS_READWRITE?"read-write":
-    flags==SQLITE_ACCESS_READ?"read":"exists"
-    , zName, ret)
-  );
-  async_mutex_leave(ASYNC_MUTEX_QUEUE);
-  *pResOut = ret;
-  return rc;
-}
-
-/*
-** Fill in zPathOut with the full path to the file identified by zPath.
-*/
-static int asyncFullPathname(
-  sqlite3_vfs *pAsyncVfs, 
-  const char *zPath, 
-  int nPathOut,
-  char *zPathOut
-){
-  int rc;
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  rc = pVfs->xFullPathname(pVfs, zPath, nPathOut, 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 i, j;
-    char *z = zPathOut;
-    int n = (int)strlen(z);
-    while( n>1 && z[n-1]=='/' ){ n--; }
-    for(i=j=0; i<n; i++){
-      if( z[i]=='/' ){
-        if( z[i+1]=='/' ) continue;
-        if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
-          i += 1;
-          continue;
-        }
-        if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){
-          while( j>0 && z[j-1]!='/' ){ j--; }
-          if( j>0 ){ j--; }
-          i += 2;
-          continue;
-        }
-      }
-      z[j++] = z[i];
-    }
-    z[j] = 0;
-  }
-
-  return rc;
-}
-static void *asyncDlOpen(sqlite3_vfs *pAsyncVfs, const char *zPath){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  return pVfs->xDlOpen(pVfs, zPath);
-}
-static void asyncDlError(sqlite3_vfs *pAsyncVfs, int nByte, char *zErrMsg){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  pVfs->xDlError(pVfs, nByte, zErrMsg);
-}
-static void (*asyncDlSym(
-  sqlite3_vfs *pAsyncVfs, 
-  void *pHandle, 
-  const char *zSymbol
-))(void){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  return pVfs->xDlSym(pVfs, pHandle, zSymbol);
-}
-static void asyncDlClose(sqlite3_vfs *pAsyncVfs, void *pHandle){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  pVfs->xDlClose(pVfs, pHandle);
-}
-static int asyncRandomness(sqlite3_vfs *pAsyncVfs, int nByte, char *zBufOut){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  return pVfs->xRandomness(pVfs, nByte, zBufOut);
-}
-static int asyncSleep(sqlite3_vfs *pAsyncVfs, int nMicro){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  return pVfs->xSleep(pVfs, nMicro);
-}
-static int asyncCurrentTime(sqlite3_vfs *pAsyncVfs, double *pTimeOut){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;
-  return pVfs->xCurrentTime(pVfs, pTimeOut);
-}
-
-static sqlite3_vfs async_vfs = {
-  1,                    /* iVersion */
-  sizeof(AsyncFile),    /* szOsFile */
-  0,                    /* mxPathname */
-  0,                    /* pNext */
-  SQLITEASYNC_VFSNAME,  /* zName */
-  0,                    /* pAppData */
-  asyncOpen,            /* xOpen */
-  asyncDelete,          /* xDelete */
-  asyncAccess,          /* xAccess */
-  asyncFullPathname,    /* xFullPathname */
-  asyncDlOpen,          /* xDlOpen */
-  asyncDlError,         /* xDlError */
-  asyncDlSym,           /* xDlSym */
-  asyncDlClose,         /* xDlClose */
-  asyncRandomness,      /* xDlError */
-  asyncSleep,           /* xDlSym */
-  asyncCurrentTime      /* xDlClose */
-};
-
-/* 
-** This procedure runs in a separate thread, reading messages off of the
-** write queue and processing them one by one.  
-**
-** If async.writerHaltNow is true, then this procedure exits
-** after processing a single message.
-**
-** If async.writerHaltWhenIdle is true, then this procedure exits when
-** the write queue is empty.
-**
-** If both of the above variables are false, this procedure runs
-** indefinately, waiting for operations to be added to the write queue
-** and processing them in the order in which they arrive.
-**
-** An artifical delay of async.ioDelay milliseconds is inserted before
-** each write operation in order to simulate the effect of a slow disk.
-**
-** Only one instance of this procedure may be running at a time.
-*/
-static void asyncWriterThread(void){
-  sqlite3_vfs *pVfs = (sqlite3_vfs *)(async_vfs.pAppData);
-  AsyncWrite *p = 0;
-  int rc = SQLITE_OK;
-  int holdingMutex = 0;
-
-  async_mutex_enter(ASYNC_MUTEX_WRITER);
-
-  while( async.eHalt!=SQLITEASYNC_HALT_NOW ){
-    int doNotFree = 0;
-    sqlite3_file *pBase = 0;
-
-    if( !holdingMutex ){
-      async_mutex_enter(ASYNC_MUTEX_QUEUE);
-    }
-    while( (p = async.pQueueFirst)==0 ){
-      if( async.eHalt!=SQLITEASYNC_HALT_NEVER ){
-        async_mutex_leave(ASYNC_MUTEX_QUEUE);
-        break;
-      }else{
-        ASYNC_TRACE(("IDLE\n"));
-        async_cond_wait(ASYNC_COND_QUEUE, ASYNC_MUTEX_QUEUE);
-        ASYNC_TRACE(("WAKEUP\n"));
-      }
-    }
-    if( p==0 ) break;
-    holdingMutex = 1;
-
-    /* Right now this thread is holding the mutex on the write-op queue.
-    ** Variable 'p' points to the first entry in the write-op queue. In
-    ** the general case, we hold on to the mutex for the entire body of
-    ** the loop. 
-    **
-    ** However in the cases enumerated below, we relinquish the mutex,
-    ** perform the IO, and then re-request the mutex before removing 'p' from
-    ** the head of the write-op queue. The idea is to increase concurrency with
-    ** sqlite threads.
-    **
-    **     * An ASYNC_CLOSE operation.
-    **     * An ASYNC_OPENEXCLUSIVE operation. For this one, we relinquish 
-    **       the mutex, call the underlying xOpenExclusive() function, then
-    **       re-aquire the mutex before seting the AsyncFile.pBaseRead 
-    **       variable.
-    **     * ASYNC_SYNC and ASYNC_WRITE operations, if 
-    **       SQLITE_ASYNC_TWO_FILEHANDLES was set at compile time and two
-    **       file-handles are open for the particular file being "synced".
-    */
-    if( async.ioError!=SQLITE_OK && p->op!=ASYNC_CLOSE ){
-      p->op = ASYNC_NOOP;
-    }
-    if( p->pFileData ){
-      pBase = p->pFileData->pBaseWrite;
-      if( 
-        p->op==ASYNC_CLOSE || 
-        p->op==ASYNC_OPENEXCLUSIVE ||
-        (pBase->pMethods && (p->op==ASYNC_SYNC || p->op==ASYNC_WRITE) ) 
-      ){
-        async_mutex_leave(ASYNC_MUTEX_QUEUE);
-        holdingMutex = 0;
-      }
-      if( !pBase->pMethods ){
-        pBase = p->pFileData->pBaseRead;
-      }
-    }
-
-    switch( p->op ){
-      case ASYNC_NOOP:
-        break;
-
-      case ASYNC_WRITE:
-        assert( pBase );
-        ASYNC_TRACE(("WRITE %s %d bytes at %d\n",
-                p->pFileData->zName, p->nByte, p->iOffset));
-        rc = pBase->pMethods->xWrite(pBase, (void *)(p->zBuf), p->nByte, p->iOffset);
-        break;
-
-      case ASYNC_SYNC:
-        assert( pBase );
-        ASYNC_TRACE(("SYNC %s\n", p->pFileData->zName));
-        rc = pBase->pMethods->xSync(pBase, p->nByte);
-        break;
-
-      case ASYNC_TRUNCATE:
-        assert( pBase );
-        ASYNC_TRACE(("TRUNCATE %s to %d bytes\n", 
-                p->pFileData->zName, p->iOffset));
-        rc = pBase->pMethods->xTruncate(pBase, p->iOffset);
-        break;
-
-      case ASYNC_CLOSE: {
-        AsyncFileData *pData = p->pFileData;
-        ASYNC_TRACE(("CLOSE %s\n", p->pFileData->zName));
-        if( pData->pBaseWrite->pMethods ){
-          pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite);
-        }
-        if( pData->pBaseRead->pMethods ){
-          pData->pBaseRead->pMethods->xClose(pData->pBaseRead);
-        }
-
-        /* Unlink AsyncFileData.lock from the linked list of AsyncFileLock 
-        ** structures for this file. Obtain the async.lockMutex mutex 
-        ** before doing so.
-        */
-        async_mutex_enter(ASYNC_MUTEX_LOCK);
-        rc = unlinkAsyncFile(pData);
-        async_mutex_leave(ASYNC_MUTEX_LOCK);
-
-        if( !holdingMutex ){
-          async_mutex_enter(ASYNC_MUTEX_QUEUE);
-          holdingMutex = 1;
-        }
-        assert_mutex_is_held(ASYNC_MUTEX_QUEUE);
-        async.pQueueFirst = p->pNext;
-        sqlite3_free(pData);
-        doNotFree = 1;
-        break;
-      }
-
-      case ASYNC_UNLOCK: {
-        AsyncWrite *pIter;
-        AsyncFileData *pData = p->pFileData;
-        int eLock = p->nByte;
-
-        /* When a file is locked by SQLite using the async backend, it is 
-        ** locked within the 'real' file-system synchronously. When it is
-        ** unlocked, an ASYNC_UNLOCK event is added to the write-queue to
-        ** unlock the file asynchronously. The design of the async backend
-        ** requires that the 'real' file-system file be locked from the
-        ** time that SQLite first locks it (and probably reads from it)
-        ** until all asynchronous write events that were scheduled before
-        ** SQLite unlocked the file have been processed.
-        **
-        ** This is more complex if SQLite locks and unlocks the file multiple
-        ** times in quick succession. For example, if SQLite does: 
-        ** 
-        **   lock, write, unlock, lock, write, unlock
-        **
-        ** Each "lock" operation locks the file immediately. Each "write" 
-        ** and "unlock" operation adds an event to the event queue. If the
-        ** second "lock" operation is performed before the first "unlock"
-        ** operation has been processed asynchronously, then the first
-        ** "unlock" cannot be safely processed as is, since this would mean
-        ** the file was unlocked when the second "write" operation is
-        ** processed. To work around this, when processing an ASYNC_UNLOCK
-        ** operation, SQLite:
-        **
-        **   1) Unlocks the file to the minimum of the argument passed to
-        **      the xUnlock() call and the current lock from SQLite's point
-        **      of view, and
-        **
-        **   2) Only unlocks the file at all if this event is the last
-        **      ASYNC_UNLOCK event on this file in the write-queue.
-        */ 
-        assert( holdingMutex==1 );
-        assert( async.pQueueFirst==p );
-        for(pIter=async.pQueueFirst->pNext; pIter; pIter=pIter->pNext){
-          if( pIter->pFileData==pData && pIter->op==ASYNC_UNLOCK ) break;
-        }
-        if( !pIter ){
-          async_mutex_enter(ASYNC_MUTEX_LOCK);
-          pData->lock.eAsyncLock = MIN(
-              pData->lock.eAsyncLock, MAX(pData->lock.eLock, eLock)
-          );
-          assert(pData->lock.eAsyncLock>=pData->lock.eLock);
-          rc = getFileLock(pData->pLock);
-          async_mutex_leave(ASYNC_MUTEX_LOCK);
-        }
-        break;
-      }
-
-      case ASYNC_DELETE:
-        ASYNC_TRACE(("DELETE %s\n", p->zBuf));
-        rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset);
-        if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
-        break;
-
-      case ASYNC_OPENEXCLUSIVE: {
-        int flags = (int)p->iOffset;
-        AsyncFileData *pData = p->pFileData;
-        ASYNC_TRACE(("OPEN %s flags=%d\n", p->zBuf, (int)p->iOffset));
-        assert(pData->pBaseRead->pMethods==0 && pData->pBaseWrite->pMethods==0);
-        rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseRead, flags, 0);
-        assert( holdingMutex==0 );
-        async_mutex_enter(ASYNC_MUTEX_QUEUE);
-        holdingMutex = 1;
-        break;
-      }
-
-      default: assert(!"Illegal value for AsyncWrite.op");
-    }
-
-    /* If we didn't hang on to the mutex during the IO op, obtain it now
-    ** so that the AsyncWrite structure can be safely removed from the 
-    ** global write-op queue.
-    */
-    if( !holdingMutex ){
-      async_mutex_enter(ASYNC_MUTEX_QUEUE);
-      holdingMutex = 1;
-    }
-    /* ASYNC_TRACE(("UNLINK %p\n", p)); */
-    if( p==async.pQueueLast ){
-      async.pQueueLast = 0;
-    }
-    if( !doNotFree ){
-      assert_mutex_is_held(ASYNC_MUTEX_QUEUE);
-      async.pQueueFirst = p->pNext;
-      sqlite3_free(p);
-    }
-    assert( holdingMutex );
-
-    /* An IO error has occurred. We cannot report the error back to the
-    ** connection that requested the I/O since the error happened 
-    ** asynchronously.  The connection has already moved on.  There 
-    ** really is nobody to report the error to.
-    **
-    ** The file for which the error occurred may have been a database or
-    ** journal file. Regardless, none of the currently queued operations
-    ** associated with the same database should now be performed. Nor should
-    ** any subsequently requested IO on either a database or journal file 
-    ** handle for the same database be accepted until the main database
-    ** file handle has been closed and reopened.
-    **
-    ** Furthermore, no further IO should be queued or performed on any file
-    ** handle associated with a database that may have been part of a 
-    ** multi-file transaction that included the database associated with 
-    ** the IO error (i.e. a database ATTACHed to the same handle at some 
-    ** point in time).
-    */
-    if( rc!=SQLITE_OK ){
-      async.ioError = rc;
-    }
-
-    if( async.ioError && !async.pQueueFirst ){
-      async_mutex_enter(ASYNC_MUTEX_LOCK);
-      if( 0==async.pLock ){
-        async.ioError = SQLITE_OK;
-      }
-      async_mutex_leave(ASYNC_MUTEX_LOCK);
-    }
-
-    /* Drop the queue mutex before continuing to the next write operation
-    ** in order to give other threads a chance to work with the write queue.
-    */
-    if( !async.pQueueFirst || !async.ioError ){
-      async_mutex_leave(ASYNC_MUTEX_QUEUE);
-      holdingMutex = 0;
-      if( async.ioDelay>0 ){
-        pVfs->xSleep(pVfs, async.ioDelay*1000);
-      }else{
-        async_sched_yield();
-      }
-    }
-  }
-  
-  async_mutex_leave(ASYNC_MUTEX_WRITER);
-  return;
-}
-
-/*
-** Install the asynchronous VFS.
-*/ 
-int sqlite3async_initialize(const char *zParent, int isDefault){
-  int rc = SQLITE_OK;
-  if( async_vfs.pAppData==0 ){
-    sqlite3_vfs *pParent = sqlite3_vfs_find(zParent);
-    if( !pParent || async_os_initialize() ){
-      rc = SQLITE_ERROR;
-    }else if( SQLITE_OK!=(rc = sqlite3_vfs_register(&async_vfs, isDefault)) ){
-      async_os_shutdown();
-    }else{
-      async_vfs.pAppData = (void *)pParent;
-      async_vfs.mxPathname = ((sqlite3_vfs *)async_vfs.pAppData)->mxPathname;
-    }
-  }
-  return rc;
-}
-
-/*
-** Uninstall the asynchronous VFS.
-*/
-void sqlite3async_shutdown(void){
-  if( async_vfs.pAppData ){
-    async_os_shutdown();
-    sqlite3_vfs_unregister((sqlite3_vfs *)&async_vfs);
-    async_vfs.pAppData = 0;
-  }
-}
-
-/*
-** Process events on the write-queue.
-*/
-void sqlite3async_run(void){
-  asyncWriterThread();
-}
-
-/*
-** Control/configure the asynchronous IO system.
-*/
-int sqlite3async_control(int op, ...){
-  int rc = SQLITE_OK;
-  va_list ap;
-  va_start(ap, op);
-  switch( op ){
-    case SQLITEASYNC_HALT: {
-      int eWhen = va_arg(ap, int);
-      if( eWhen!=SQLITEASYNC_HALT_NEVER
-       && eWhen!=SQLITEASYNC_HALT_NOW
-       && eWhen!=SQLITEASYNC_HALT_IDLE
-      ){
-        rc = SQLITE_MISUSE;
-        break;
-      }
-      async.eHalt = eWhen;
-      async_mutex_enter(ASYNC_MUTEX_QUEUE);
-      async_cond_signal(ASYNC_COND_QUEUE);
-      async_mutex_leave(ASYNC_MUTEX_QUEUE);
-      break;
-    }
-
-    case SQLITEASYNC_DELAY: {
-      int iDelay = va_arg(ap, int);
-      if( iDelay<0 ){
-        rc = SQLITE_MISUSE;
-        break;
-      }
-      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);
-        rc = SQLITE_MISUSE;
-        break;
-      }
-      async.bLockFiles = bLock;
-      async_mutex_leave(ASYNC_MUTEX_QUEUE);
-      break;
-    }
-      
-    case SQLITEASYNC_GET_HALT: {
-      int *peWhen = va_arg(ap, int *);
-      *peWhen = async.eHalt;
-      break;
-    }
-    case SQLITEASYNC_GET_DELAY: {
-      int *piDelay = va_arg(ap, int *);
-      *piDelay = async.ioDelay;
-      break;
-    }
-    case SQLITEASYNC_GET_LOCKFILES: {
-      int *piDelay = va_arg(ap, int *);
-      *piDelay = async.bLockFiles;
-      break;
-    }
-
-    default:
-      rc = SQLITE_ERROR;
-      break;
-  }
-  va_end(ap);
-  return rc;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO) */
diff --git a/ext/async/sqlite3async.h b/ext/async/sqlite3async.h
deleted file mode 100644 (file)
index 13b23bc..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-
-#ifndef __SQLITEASYNC_H_
-#define __SQLITEASYNC_H_ 1
-
-/*
-** Make sure we can call this stuff from C++.
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SQLITEASYNC_VFSNAME "sqlite3async"
-
-/*
-** THREAD SAFETY NOTES:
-**
-** Of the four API functions in this file, the following are not threadsafe:
-**
-**   sqlite3async_initialize()
-**   sqlite3async_shutdown()
-**
-** Care must be taken that neither of these functions is called while 
-** another thread may be calling either any sqlite3async_XXX() function
-** or an sqlite3_XXX() API function related to a database handle that
-** is using the asynchronous IO VFS.
-**
-** These functions:
-**
-**   sqlite3async_run()
-**   sqlite3async_control()
-**
-** are threadsafe. It is quite safe to call either of these functions even
-** if another thread may also be calling one of them or an sqlite3_XXX()
-** function related to a database handle that uses the asynchronous IO VFS.
-*/
-
-/*
-** Initialize the asynchronous IO VFS and register it with SQLite using
-** sqlite3_vfs_register(). If the asynchronous VFS is already initialized
-** and registered, this function is a no-op. The asynchronous IO VFS
-** is registered as "sqlite3async".
-**
-** The asynchronous IO VFS does not make operating system IO requests 
-** directly. Instead, it uses an existing VFS implementation for all
-** required file-system operations. If the first parameter to this function
-** is NULL, then the current default VFS is used for IO. If it is not
-** NULL, then it must be the name of an existing VFS. In other words, the
-** first argument to this function is passed to sqlite3_vfs_find() to
-** locate the VFS to use for all real IO operations. This VFS is known
-** as the "parent VFS".
-**
-** If the second parameter to this function is non-zero, then the 
-** asynchronous IO VFS is registered as the default VFS for all SQLite 
-** database connections within the process. Otherwise, the asynchronous IO
-** VFS is only used by connections opened using sqlite3_open_v2() that
-** specifically request VFS "sqlite3async".
-**
-** If a parent VFS cannot be located, then SQLITE_ERROR is returned.
-** In the unlikely event that operating system specific initialization
-** fails (win32 systems create the required critical section and event 
-** objects within this function), then SQLITE_ERROR is also returned.
-** Finally, if the call to sqlite3_vfs_register() returns an error, then 
-** the error code is returned to the user by this function. In all three
-** of these cases, intialization has failed and the asynchronous IO VFS
-** is not registered with SQLite.
-**
-** Otherwise, if no error occurs, SQLITE_OK is returned.
-*/ 
-int sqlite3async_initialize(const char *zParent, int isDefault);
-
-/*
-** This function unregisters the asynchronous IO VFS using 
-** sqlite3_vfs_unregister().
-**
-** On win32 platforms, this function also releases the small number of 
-** critical section and event objects created by sqlite3async_initialize().
-*/ 
-void sqlite3async_shutdown(void);
-
-/*
-** This function may only be called when the asynchronous IO VFS is 
-** installed (after a call to sqlite3async_initialize()). It processes
-** zero or more queued write operations before returning. It is expected
-** (but not required) that this function will be called by a different 
-** thread than those threads that use SQLite. The "background thread"
-** that performs IO.
-**
-** How many queued write operations are performed before returning 
-** depends on the global setting configured by passing the SQLITEASYNC_HALT
-** verb to sqlite3async_control() (see below for details). By default
-** this function never returns - it processes all pending operations and 
-** then blocks waiting for new ones.
-**
-** If multiple simultaneous calls are made to sqlite3async_run() from two
-** or more threads, then the calls are serialized internally.
-*/
-void sqlite3async_run(void);
-
-/*
-** This function may only be called when the asynchronous IO VFS is 
-** installed (after a call to sqlite3async_initialize()). It is used 
-** to query or configure various parameters that affect the operation 
-** of the asynchronous IO VFS. At present there are three parameters 
-** supported:
-**
-**   * The "halt" parameter, which configures the circumstances under
-**     which the sqlite3async_run() parameter is configured.
-**
-**   * The "delay" parameter. Setting the delay parameter to a non-zero
-**     value causes the sqlite3async_run() function to sleep for the
-**     configured number of milliseconds between each queued write 
-**     operation.
-**
-**   * The "lockfiles" parameter. This parameter determines whether or 
-**     not the asynchronous IO VFS locks the database files it operates
-**     on. Disabling file locking can improve throughput.
-**
-** This function is always passed two arguments. When setting the value
-** of a parameter, the first argument must be one of SQLITEASYNC_HALT,
-** SQLITEASYNC_DELAY or SQLITEASYNC_LOCKFILES. The second argument must
-** be passed the new value for the parameter as type "int".
-**
-** When querying the current value of a paramter, the first argument must
-** be one of SQLITEASYNC_GET_HALT, GET_DELAY or GET_LOCKFILES. The second 
-** argument to this function must be of type (int *). The current value
-** of the queried parameter is copied to the memory pointed to by the
-** second argument. For example:
-**
-**   int eCurrentHalt;
-**   int eNewHalt = SQLITEASYNC_HALT_IDLE;
-**
-**   sqlite3async_control(SQLITEASYNC_HALT, eNewHalt);
-**   sqlite3async_control(SQLITEASYNC_GET_HALT, &eCurrentHalt);
-**   assert( eNewHalt==eCurrentHalt );
-**
-** See below for more detail on each configuration parameter.
-**
-** SQLITEASYNC_HALT:
-**
-**   This is used to set the value of the "halt" parameter. The second
-**   argument must be one of the SQLITEASYNC_HALT_XXX symbols defined
-**   below (either NEVER, IDLE and NOW).
-**
-**   If the parameter is set to NEVER, then calls to sqlite3async_run()
-**   never return. This is the default setting. If the parameter is set
-**   to IDLE, then calls to sqlite3async_run() return as soon as the
-**   queue of pending write operations is empty. If the parameter is set
-**   to NOW, then calls to sqlite3async_run() return as quickly as 
-**   possible, without processing any pending write requests.
-**
-**   If an attempt is made to set this parameter to an integer value other
-**   than SQLITEASYNC_HALT_NEVER, IDLE or NOW, then sqlite3async_control() 
-**   returns SQLITE_MISUSE and the current value of the parameter is not 
-**   modified.
-**
-**   Modifying the "halt" parameter affects calls to sqlite3async_run() 
-**   made by other threads that are currently in progress.
-**
-** SQLITEASYNC_DELAY:
-**
-**   This is used to set the value of the "delay" parameter. If set to
-**   a non-zero value, then after completing a pending write request, the
-**   sqlite3async_run() function sleeps for the configured number of 
-**   milliseconds.
-**
-**   If an attempt is made to set this parameter to a negative value,
-**   sqlite3async_control() returns SQLITE_MISUSE and the current value
-**   of the parameter is not modified.
-**
-**   Modifying the "delay" parameter affects calls to sqlite3async_run() 
-**   made by other threads that are currently in progress.
-**
-** SQLITEASYNC_LOCKFILES:
-**
-**   This is used to set the value of the "lockfiles" parameter. This
-**   parameter must be set to either 0 or 1. If set to 1, then the
-**   asynchronous IO VFS uses the xLock() and xUnlock() methods of the
-**   parent VFS to lock database files being read and/or written. If
-**   the parameter is set to 0, then these locks are omitted.
-**
-**   This parameter may only be set when there are no open database
-**   connections using the VFS and the queue of pending write requests
-**   is empty. Attempting to set it when this is not true, or to set it 
-**   to a value other than 0 or 1 causes sqlite3async_control() to return
-**   SQLITE_MISUSE and the value of the parameter to remain unchanged.
-**
-**   If this parameter is set to zero, then it is only safe to access the
-**   database via the asynchronous IO VFS from within a single process. If
-**   while writing to the database via the asynchronous IO VFS the database
-**   is also read or written from within another process, or via another
-**   connection that does not use the asynchronous IO VFS within the same
-**   process, the results are undefined (and may include crashes or database
-**   corruption).
-**
-**   Alternatively, if this parameter is set to 1, then it is safe to access
-**   the database from multiple connections within multiple processes using
-**   either the asynchronous IO VFS or the parent VFS directly.
-*/
-int sqlite3async_control(int op, ...);
-
-/*
-** Values that can be used as the first argument to sqlite3async_control().
-*/
-#define SQLITEASYNC_HALT          1
-#define SQLITEASYNC_GET_HALT      2
-#define SQLITEASYNC_DELAY         3
-#define SQLITEASYNC_GET_DELAY     4
-#define SQLITEASYNC_LOCKFILES     5
-#define SQLITEASYNC_GET_LOCKFILES 6
-
-/*
-** If the first argument to sqlite3async_control() is SQLITEASYNC_HALT,
-** the second argument should be one of the following.
-*/
-#define SQLITEASYNC_HALT_NEVER 0       /* Never halt (default value) */
-#define SQLITEASYNC_HALT_NOW   1       /* Halt as soon as possible */
-#define SQLITEASYNC_HALT_IDLE  2       /* Halt when write-queue is empty */
-
-#ifdef __cplusplus
-}  /* End of the 'extern "C"' block */
-#endif
-#endif        /* ifndef __SQLITEASYNC_H_ */
diff --git a/main.mk b/main.mk
index 1502b05c7e33ee4c104d88b346653e42bd6a8db0..3469381bd65b56d6cc0e6b01480f7667ded1c247 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -307,7 +307,7 @@ T.cc.sqlite ?= $(T.cc)
 #
 CFLAGS.intree_includes = \
     -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \
-    -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \
+    -I$(TOP)/ext/fts3 -I$(TOP)/ext/session \
     -I$(TOP)/ext/misc -I$(TOP)/ext/userauth
 T.cc.sqlite += $(CFLAGS.intree_includes)
 
@@ -627,7 +627,6 @@ TESTSRC = \
   $(TOP)/src/test8.c \
   $(TOP)/src/test9.c \
   $(TOP)/src/test_autoext.c \
-  $(TOP)/src/test_async.c \
   $(TOP)/src/test_backup.c \
   $(TOP)/src/test_bestindex.c \
   $(TOP)/src/test_blob.c \
@@ -764,7 +763,6 @@ TESTSRC2 = \
   $(TOP)/ext/fts3/fts3_term.c \
   $(TOP)/ext/fts3/fts3_tokenizer.c \
   $(TOP)/ext/fts3/fts3_write.c \
-  $(TOP)/ext/async/sqlite3async.c \
   $(TOP)/ext/session/sqlite3session.c \
   $(TOP)/ext/misc/stmt.c \
   fts5.c
index 383228d3e0737756c564b070e8479b32f701a7ce..2a8ee27a4757be0c45870ed6fe8131f85a39df0c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,11 +1,11 @@
-C Omit\sext/consio\sfrom\sthe\stree.\s\sNo\slonger\sneeded\sor\ssupported.
-D 2024-10-28T14:53:45.379
+C Omit\sthe\santiquated\sand\slong-unsupport\sasync\sextension\ssince\sit\shas\sbeen\nsuperseded\sby\sWAL\smode\sfor\sover\sa\sdecade.
+D 2024-10-28T15:38:53.409
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2
 F Makefile.in 02ea00ff433902dba369d4a55b3aeb6bb1ffe2d82f777194984b8cdd7ed7c3ad
 F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1
-F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f
+F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312
 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889
 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
@@ -68,9 +68,6 @@ F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc1404
 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
 F doc/wal-lock.md 781726aaba20bafeceb7ba9f91d5c98c6731691b30c954e37cf0b49a053d461d
 F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
-F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
-F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
-F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
 F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
 F ext/expert/expert1.test 1d2da6606623b57bb47064e02140823ce1daecd4cacbf402c73ad3473d7f000c
@@ -705,7 +702,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
-F main.mk ed437c3fb9ef480a534aa3205fff1f380ce776c1aa1069e3623b692770f86404
+F main.mk c5e17513c0f68b514d0f1b5afabcc0aabfedf8ebba0e6314435df1edcb7e8fd4
 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -804,7 +801,6 @@ F src/test5.c bb87279ed12e199486894e6c83e58dc8cd1de9524ace171d59219d3ab696a0c1
 F src/test6.c 763b92489f11f4a77b773f0d3b8369ab0edd5292ac794043062c337019f12d8a
 F src/test8.c 206d8f3cc73950d252906656e2646b5de0d580b07187b635fcb3edd8c2c5fbc0
 F src/test9.c 7a708ad27f8fda79113e5e15de66632710958c401e64c2f22bc04e2f5a7a1b62
-F src/test_async.c 0101173cf8137ba5473a84a695281fa9dedc2a1d155998c68623f2978017ad98
 F src/test_autoext.c 14d4bbd3d0bd1eec0f6d16b29e28cf1e2d0b020d454835f0721a5f68121ac10f
 F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d9719a7
 F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
@@ -837,7 +833,7 @@ F src/test_schema.c b06d3ddc3edc173c143878f3edb869dd200d57d918ae2f38820534f9a5e3
 F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a
 F src/test_superlock.c 18355ca274746aa6909e3744163e5deb1196a85d5bc64b9cd377273cef626da7
 F src/test_syscall.c 9ad7ab39910c16d29411678d91b0d27a7a996a718df5ee93dcd635e846d0275c
-F src/test_tclsh.c 6077f2bdc6b4ea2bace2a0cd6ea48e0a4651007ae7382c13efc0c495eb0c6956
+F src/test_tclsh.c c01706ac60bd3176754d3ccd37da74c6ad97c2e14489f8ed71b497c1c0ac0dd4
 F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e048424
 F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb
 F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3
@@ -919,11 +915,6 @@ F test/analyzeE.test d2ec7921c162cdc33ac8e7eb01f9ebf78100610af7c94c8552bbf551de1
 F test/analyzeF.test 40b5cc3ad7b10e81020d7ca86f1417647ecfae7477cfd88acc5aa7ae1068f949
 F test/analyzeG.test 623be33038c49648872746c8dd8b23b5792c08fef173c55e82f1b12fca259852
 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49
-F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
-F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
-F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
-F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
-F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
 F test/atof1.test 7ec56debc04b32e8f9dc87239f4bbb07d84550fb83dd7475b0ead9e83beb35da
 F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
 F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
@@ -1417,7 +1408,7 @@ F test/literal2.tcl 1499037beaf661aeecdbe48801220a181d805372a64c6128d5f26bb6a4a8
 F test/literal2.test b149e16b5fc9ee6249069a8858ed41052f222014fe0ba7ad43c2fb989c2dada2
 F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04
 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
-F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db
+F test/lock.test 05f346b65040b9a27c032c984e1e509dfef1661135b4f26a3ab6d21358277803
 F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
 F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
 F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37b8
@@ -1426,7 +1417,7 @@ F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
 F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413
 F test/lookaside.test 5a828e7256f1ee4da8e1bdaa03373a3ccdb0f1ff98dfa82e9b76cb41a45b1083
-F test/main.test 1b07447e484d3a3ca8c620c6551258fa51f9cc9fdd56648e8949ea8c836be961
+F test/main.test e8752d76233b1c8906cd2c98ad920dba868bd63c87d51d8a2ea5e9cba55dd496
 F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
 F test/malloc.test 18dd1c4188c81ca79cf123527c71b19ee0c31feb9947fdffb0dc6ceb1436816a
 F test/malloc3.test 6e88bae6312854a4adb4ecc2a6a5ea8c59b4db778b724ba718e1c43fc8c3c136
@@ -1459,7 +1450,7 @@ F test/memdb1.test c737ac9aa5895092332b1dde24fae7ae494b7fcbcd346d22d600891096a38
 F test/memdb2.test 4ba1fc09e2f51df80d148a540e4a3fa66d0462e91167b27497084de4d1f6b5b4
 F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c
 F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164d288da1e
-F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
+F test/memleak.test c7478f1195d64887dd1c677edc39fa03b5bf29024e6dcc5b5cc554d7ed00b01f
 F test/memsubsys1.test 86b8158752af9188ed5b32a30674a1ef71183e6bc4e6808e815cd658ca9058a6
 F test/memsubsys2.test 774b93cb09ca50d1b759bb7c645baa2a9ce172edc3a3da67d5150a26a9fc2a08
 F test/merge1.test 7dd9dc6838bcd0623a069485fe3a8dd498a051c16e1877cf84f506c0d6a29b43
@@ -1538,7 +1529,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
 F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
 F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463
 F test/percentile.test 52ba89d6ee6b65f770972b67dace358bab7cdbd532803d3db157845268e789cd
-F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80
+F test/permutations.test 37650c5286f7d6f322af95cad876b69c6c2c79c28dc649f09de07d3312b1213c
 F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
 F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882
 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
@@ -1784,7 +1775,6 @@ F test/tkt-8454a207b9.test ead80b7a01438ca1436cee029694a96c821346cf1e24f06de12f8
 F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
 F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed
 F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
-F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
 F test/tkt-99378177930f87bd.test 9d6cff39b50d062c813ae1cb0ebbd1b7acf81ecc23ae5d5215e5bb05667dc137
 F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
 F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6
@@ -2214,8 +2204,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 6cb7cb7e33835d42cbab2e5468d73de7bb3b01971da078ce1c1344edc11ab1b3
-R 00f0377d2b4f46d55243305df3135edf
+P 1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5
+R b9b93d2e2084015bc7fa1134ed3eba38
+T *branch * omit-async
+T *sym-omit-async *
+T -sym-trunk *
 U drh
-Z 05dc840cebf23762b49de298db68f9dc
+Z e51dfe59488ba774ddcef48ab38dfbd3
 # Remove this line to create a well-formed Fossil manifest.
index 15921407326043712a6da232eb3a1f04413c78de..97058526f675627bb56e9829131415d9ed0be35e 100644 (file)
@@ -1 +1 @@
-1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5
+10b1b86821bfc21377e7ccceb31146ab01aa6eaf418b85a204abcab5b793958e
diff --git a/src/test_async.c b/src/test_async.c
deleted file mode 100644 (file)
index afe401a..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
-** 2005 December 14
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains a binding of the asynchronous IO extension interface
-** (defined in ext/async/sqlite3async.h) to Tcl.
-*/
-
-#define TCL_THREADS
-#include "tclsqlite.h"
-
-#ifdef SQLITE_ENABLE_ASYNCIO
-
-#include "sqlite3async.h"
-#include "sqlite3.h"
-#include <assert.h>
-
-/* From main.c */
-extern const char *sqlite3ErrName(int);
-
-
-struct TestAsyncGlobal {
-  int isInstalled;                     /* True when async VFS is installed */
-} testasync_g = { 0 };
-
-TCL_DECLARE_MUTEX(testasync_g_writerMutex);
-
-/*
-** sqlite3async_initialize PARENT-VFS ISDEFAULT
-*/
-static int SQLITE_TCLAPI testAsyncInit(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  const char *zParent;
-  int isDefault;
-  int rc;
-
-  if( objc!=3 ){
-    Tcl_WrongNumArgs(interp, 1, objv, "PARENT-VFS ISDEFAULT");
-    return TCL_ERROR;
-  }
-  zParent = Tcl_GetString(objv[1]);
-  if( !*zParent ) {
-    zParent = 0;
-  }
-  if( Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){
-    return TCL_ERROR;
-  }
-
-  rc = sqlite3async_initialize(zParent, isDefault);
-  if( rc!=SQLITE_OK ){
-    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
-    return TCL_ERROR;
-  }
-  return TCL_OK;
-}
-
-/*
-** sqlite3async_shutdown
-*/
-static int SQLITE_TCLAPI testAsyncShutdown(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  sqlite3async_shutdown();
-  return TCL_OK;
-}
-
-static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){
-  Tcl_MutexLock(&testasync_g_writerMutex);
-  *((int *)pIsStarted) = 1;
-  sqlite3async_run();
-  Tcl_MutexUnlock(&testasync_g_writerMutex);
-  Tcl_ExitThread(0);
-  TCL_THREAD_CREATE_RETURN;
-}
-
-/*
-** sqlite3async_start
-**
-** Start a new writer thread.
-*/
-static int SQLITE_TCLAPI testAsyncStart(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  volatile int isStarted = 0;
-  ClientData threadData = (ClientData)&isStarted;
-
-  Tcl_ThreadId x;
-  const int nStack = TCL_THREAD_STACK_DEFAULT;
-  const int flags = TCL_THREAD_NOFLAGS;
-  int rc;
-
-  rc = Tcl_CreateThread(&x, tclWriterThread, threadData, nStack, flags);
-  if( rc!=TCL_OK ){
-    Tcl_AppendResult(interp, "Tcl_CreateThread() failed", 0);
-    return TCL_ERROR;
-  }
-
-  while( isStarted==0 ) { /* Busy loop */ }
-  return TCL_OK;
-}
-
-/*
-** sqlite3async_wait
-**
-** Wait for the current writer thread to terminate.
-**
-** If the current writer thread is set to run forever then this
-** command would block forever.  To prevent that, an error is returned. 
-*/
-static int SQLITE_TCLAPI testAsyncWait(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  int eCond;
-  if( objc!=1 ){
-    Tcl_WrongNumArgs(interp, 1, objv, "");
-    return TCL_ERROR;
-  }
-
-  sqlite3async_control(SQLITEASYNC_GET_HALT, &eCond);
-  if( eCond==SQLITEASYNC_HALT_NEVER ){
-    Tcl_AppendResult(interp, "would block forever", (char*)0);
-    return TCL_ERROR;
-  }
-
-  Tcl_MutexLock(&testasync_g_writerMutex);
-  Tcl_MutexUnlock(&testasync_g_writerMutex);
-  return TCL_OK;
-}
-
-/*
-** sqlite3async_control OPTION ?VALUE?
-*/
-static int SQLITE_TCLAPI testAsyncControl(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  int rc = SQLITE_OK;
-  int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES };
-  const char *azOpt[] = { "halt", "delay", "lockfiles", 0 };
-  const char *az[] = { "never", "now", "idle", 0 };
-  int iVal;
-  int eOpt;
-
-  if( objc!=2 && objc!=3 ){
-    Tcl_WrongNumArgs(interp, 1, objv, "OPTION ?VALUE?");
-    return TCL_ERROR;
-  }
-  if( Tcl_GetIndexFromObj(interp, objv[1], azOpt, "option", 0, &eOpt) ){
-    return TCL_ERROR;
-  }
-  eOpt = aeOpt[eOpt];
-
-  if( objc==3 ){
-    switch( eOpt ){
-      case SQLITEASYNC_HALT: {
-        assert( SQLITEASYNC_HALT_NEVER==0 );
-        assert( SQLITEASYNC_HALT_NOW==1 );
-        assert( SQLITEASYNC_HALT_IDLE==2 );
-        if( Tcl_GetIndexFromObj(interp, objv[2], az, "value", 0, &iVal) ){
-          return TCL_ERROR;
-        }
-        break;
-      }
-      case SQLITEASYNC_DELAY:
-        if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ){
-          return TCL_ERROR;
-        }
-        break;
-
-      case SQLITEASYNC_LOCKFILES:
-        if( Tcl_GetBooleanFromObj(interp, objv[2], &iVal) ){
-          return TCL_ERROR;
-        }
-        break;
-    }
-
-    rc = sqlite3async_control(eOpt, iVal);
-  }
-
-  if( rc==SQLITE_OK ){
-    rc = sqlite3async_control(
-        eOpt==SQLITEASYNC_HALT ? SQLITEASYNC_GET_HALT :
-        eOpt==SQLITEASYNC_DELAY ? SQLITEASYNC_GET_DELAY :
-        SQLITEASYNC_GET_LOCKFILES, &iVal);
-  }
-
-  if( rc!=SQLITE_OK ){
-    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
-    return TCL_ERROR;
-  }
-
-  if( eOpt==SQLITEASYNC_HALT ){
-    Tcl_SetObjResult(interp, Tcl_NewStringObj(az[iVal], -1));
-  }else{
-    Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
-  }
-
-  return TCL_OK;
-}
-
-#endif  /* SQLITE_ENABLE_ASYNCIO */
-
-/*
-** This routine registers the custom TCL commands defined in this
-** module.  This should be the only procedure visible from outside
-** of this module.
-*/
-int Sqlitetestasync_Init(Tcl_Interp *interp){
-#ifdef SQLITE_ENABLE_ASYNCIO
-  Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0);
-  Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0);
-
-  Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0);
-  Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0);
-  Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0);
-#endif  /* SQLITE_ENABLE_ASYNCIO */
-  return TCL_OK;
-}
index db362049e7bb1481f2364b8437ea8682111d3c06..989cb97a62755d69efda50872fa5cd14adb87da7 100644 (file)
@@ -59,7 +59,6 @@ const char *sqlite3TestInit(Tcl_Interp *interp){
   extern int Sqlitetest6_Init(Tcl_Interp*);
   extern int Sqlitetest8_Init(Tcl_Interp*);
   extern int Sqlitetest9_Init(Tcl_Interp*);
-  extern int Sqlitetestasync_Init(Tcl_Interp*);
   extern int Sqlitetest_autoext_Init(Tcl_Interp*);
   extern int Sqlitetest_blob_Init(Tcl_Interp*);
   extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
@@ -131,7 +130,6 @@ const char *sqlite3TestInit(Tcl_Interp *interp){
   Sqlitetest6_Init(interp);
   Sqlitetest8_Init(interp);
   Sqlitetest9_Init(interp);
-  Sqlitetestasync_Init(interp);
   Sqlitetest_autoext_Init(interp);
   Sqlitetest_blob_Init(interp);
   Sqlitetest_demovfs_Init(interp);
diff --git a/test/async.test b/test/async.test
deleted file mode 100644 (file)
index e1bc086..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-#    May you do good and not evil.
-#    May you find forgiveness for yourself and forgive others.
-#    May you share freely, never taking more than you give.
-#
-#***********************************************************************
-# This file runs all tests.
-#
-# $Id: async.test,v 1.21 2009/06/05 17:09:12 drh Exp $
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-
-if {[info commands sqlite3async_initialize] eq ""} {
-  # The async logic is not built into this system
-  finish_test
-  return
-}
-
-rename finish_test async_really_finish_test
-proc finish_test {} {
-  catch {db close}
-  catch {db2 close}
-  catch {db3 close}
-}
-if {[info exists G(isquick)]} { set ASYNC_SAVE_ISQUICK $G(isquick) }
-set G(isquick) 1
-
-set ASYNC_INCLUDE {
-  insert.test
-  insert2.test
-  insert3.test
-  lock.test
-  lock2.test
-  lock3.test
-  select1.test
-  select2.test
-  select3.test
-  select4.test
-  trans.test
-}
-
-# Enable asynchronous IO.
-sqlite3async_initialize "" 1
-
-# This proc flushes the contents of the async-IO queue through to the 
-# underlying VFS. A couple of the test scripts identified in $ASYNC_INCLUDE
-# above contain lines like "catch flush_async_queue" in places where 
-# this is required for the tests to work in async mode.
-#
-proc flush_async_queue {} {
-  sqlite3async_control halt idle
-  sqlite3async_start
-  sqlite3async_wait
-  sqlite3async_control halt never
-}
-
-rename do_test async_really_do_test
-proc do_test {name args} {
-  uplevel async_really_do_test async_io-$name $args
-  flush_async_queue
-}
-
-foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
-  set tail [file tail $testfile]
-  if {[lsearch -exact $ASYNC_INCLUDE $tail]<0} continue
-  source $testfile
-
-  # Make sure everything is flushed through. This is because [source]ing 
-  # the next test file will delete the database file on disk (using
-  # [delete_file]). If the asynchronous backend still has the file
-  # open, it will become confused.
-  #
-  flush_async_queue
-}
-
-# Flush the write-queue and disable asynchronous IO. This should ensure
-# all allocated memory is cleaned up.
-set sqlite3async_trace 1
-flush_async_queue
-sqlite3async_shutdown
-set sqlite3async_trace 0
-
-rename do_test {}
-rename async_really_do_test do_test
-rename finish_test {}
-rename async_really_finish_test finish_test
-
-if {[info exists ASYNC_SAVE_ISQUICK]} { set G(isquick) $ASYNC_SAVE_ISQUICK }
-finish_test
diff --git a/test/async2.test b/test/async2.test
deleted file mode 100644 (file)
index 7994a72..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-#    May you do good and not evil.
-#    May you find forgiveness for yourself and forgive others.
-#    May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-# $Id: async2.test,v 1.12 2009/04/25 08:39:15 danielk1977 Exp $
-
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-
-if {
-  [info commands sqlite3async_initialize]=="" ||
-  [info command sqlite3_memdebug_fail]==""
-} {
-  # The async logic is not built into this system
-  puts "Skipping async2 tests: not compiled with required features"
-  finish_test
-  return
-}
-
-# Enable asynchronous IO.
-
-set setup_script {
-  CREATE TABLE counter(c);
-  INSERT INTO counter(c) VALUES (1);
-} 
-
-set sql_script {
-  BEGIN;
-    UPDATE counter SET c = 2;
-    CREATE TABLE t1(a PRIMARY KEY, b, c);
-    CREATE TABLE t2(a PRIMARY KEY, b, c);
-  COMMIT;
-
-  BEGIN;
-    UPDATE counter SET c = 3;
-    INSERT INTO t1 VALUES('abcdefghij', 'four', 'score');
-    INSERT INTO t2 VALUES('klmnopqrst', 'and', 'seven');
-  COMMIT;
-
-  UPDATE counter SET c = 'FIN';
-}
-
-db close
-
-foreach err [list ioerr malloc-transient malloc-persistent] {
-  set ::go 10
-  for {set n 1} {$::go} {incr n} {
-    set ::sqlite_io_error_pending 0
-    sqlite3_memdebug_fail -1
-    forcedelete test.db test.db-journal
-    sqlite3 db test.db
-    execsql $::setup_script
-    db close
-  
-    sqlite3async_initialize "" 1
-    sqlite3 db test.db
-    sqlite3_db_config_lookaside db 0 0 0
-  
-    switch -- $err {
-      ioerr             { set ::sqlite_io_error_pending $n }
-      malloc-persistent { sqlite3_memdebug_fail $n -repeat 1 }
-      malloc-transient  { sqlite3_memdebug_fail $n -repeat 0 }
-    }
-
-    catchsql $::sql_script
-    db close
-
-    sqlite3async_control halt idle
-    sqlite3async_start
-    sqlite3async_wait
-    sqlite3async_control halt never
-    sqlite3async_shutdown
-
-    set ::sqlite_io_error_pending 0
-    sqlite3_memdebug_fail -1
-
-    sqlite3 db test.db
-    set c [db one {SELECT c FROM counter LIMIT 1}]
-    switch -- $c {
-      1 {
-        do_test async-$err-1.1.$n {
-          execsql {
-            SELECT name FROM sqlite_master;
-          }
-        } {counter}
-      }
-      2 {
-        do_test async-$err-1.2.$n.1 {
-          execsql {
-            SELECT * FROM t1;
-          }
-        } {}
-        do_test async-$err-1.2.$n.2 {
-          execsql {
-            SELECT * FROM t2;
-          }
-        } {}
-      }
-      3 {
-        do_test async-$err-1.3.$n.1 {
-          execsql {
-            SELECT * FROM t1;
-          }
-        } {abcdefghij four score}
-        do_test async-$err-1.3.$n.2 {
-          execsql {
-            SELECT * FROM t2;
-          }
-        } {klmnopqrst and seven}
-      }
-      FIN {
-        incr ::go -1
-      }
-    }
-  
-    db close
-  }
-}
-
-catch {db close}
-
-finish_test
diff --git a/test/async3.test b/test/async3.test
deleted file mode 100644 (file)
index 9336b66..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-# 2007 September 5
-#
-# The author disclaims copyright to this source code.  In place of
-# a legal notice, here is a blessing:
-#
-#    May you do good and not evil.
-#    May you find forgiveness for yourself and forgive others.
-#    May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-# The focus of this file is testing the code in test_async.c.
-# Specifically, it tests that the xFullPathname() method of
-# of the asynchronous vfs works correctly.
-#
-# $Id: async3.test,v 1.5 2009/04/25 08:39:15 danielk1977 Exp $
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-
-if { [info commands sqlite3async_initialize]==""  } {
-  # The async logic is not built into this system
-  puts "Skipping async3 tests: not compiled with required features"
-  finish_test
-  return
-}
-
-db close
-sqlite3async_initialize "" 1
-#set sqlite3async_trace 1
-sqlite3async_start
-
-set paths {
-  chocolate/banana/vanilla/file.db
-  chocolate//banana/vanilla/file.db
-  chocolate/./banana//vanilla/file.db
-  chocolate/banana/./vanilla/file.db
-  chocolate/banana/../banana/vanilla/file.db
-  chocolate/banana/./vanilla/extra_bit/../file.db
-}
-
-do_test async3-1.0 {
-  file mkdir [file join chocolate banana vanilla]
-  forcedelete chocolate/banana/vanilla/file.db
-  forcedelete chocolate/banana/vanilla/file.db-journal
-} {}
-
-do_test async3-1.1 {
-  sqlite3 db chocolate/banana/vanilla/file.db
-  execsql {
-    CREATE TABLE abc(a, b, c);
-    BEGIN;
-    INSERT INTO abc VALUES(1, 2, 3);
-  }
-} {}
-
-set N 2
-foreach p $paths {
-  sqlite3 db2 $p
-  do_test async3-1.$N.1 {
-    execsql {SELECT * FROM abc} db2
-  } {}
-  do_test async3-1.$N.2 {
-    catchsql {INSERT INTO abc VALUES(4, 5, 6)} db2
-  } {1 {database is locked}}
-  db2 close
-  incr N
-}
-
-db close
-
-sqlite3async_control halt idle
-sqlite3async_wait
-sqlite3async_control halt never
-sqlite3async_shutdown
-finish_test
diff --git a/test/async4.test b/test/async4.test
deleted file mode 100644 (file)
index 92a8201..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-# 2009 April 25
-#
-# The author disclaims copyright to this source code.  In place of
-# a legal notice, here is a blessing:
-#
-#    May you do good and not evil.
-#    May you find forgiveness for yourself and forgive others.
-#    May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-# $Id: async4.test,v 1.4 2009/06/05 17:09:12 drh Exp $
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-
-# Do not use a codec for tests in this file, as the database file is
-# manipulated directly using tcl scripts (using the [hexio_write] command).
-#
-do_not_use_codec
-
-# These tests only work for Tcl version 8.5 and later on Windows (for now)
-#
-if {$tcl_platform(platform)=="windows"} {
-  scan $::tcl_version %f vx
-  if {$vx<8.5} {
-    finish_test
-    return
-  }
-}
-
-if {[info commands sqlite3async_initialize] eq ""} {
-  # The async logic is not built into this system
-  finish_test
-  return
-}
-db close
-
-# Test layout:
-#
-#   async4.1.*: Test the lockfiles parameter.
-#   async4.2.*: Test the delay parameter.
-
-do_test async4.1.1 {
-  sqlite3async_initialize {} 0
-  sqlite3async_control lockfiles
-} {1}
-do_test async4.1.2 {
-  sqlite3async_control lockfiles false
-} {0}
-do_test async4.1.3 {
-  sqlite3async_control lockfiles
-} {0}
-do_test async4.1.4 {
-  sqlite3async_control lockfiles true
-} {1}
-
-do_test async4.1.5 {
-  sqlite3 db test.db -vfs sqlite3async
-  execsql { CREATE TABLE t1(a, b, c) }
-} {}
-do_test async4.1.6 {
-  list [file exists test.db] [file size test.db]
-} {1 0}
-do_test async4.1.7 {
-  sqlite3 db2 test.db
-  catchsql { CREATE TABLE t2(a, b, c) } db2
-} {1 {database is locked}}
-do_test async4.1.8 {
-  sqlite3async_control halt idle
-  sqlite3async_start
-  sqlite3async_wait
-} {}
-do_test async4.1.9 {
-  catchsql { CREATE TABLE t2(a, b, c) } db2
-} {0 {}}
-do_test async4.1.10 {
-  list [catch {sqlite3async_control lockfiles false} msg] $msg
-} {1 SQLITE_MISUSE}
-do_test async4.1.11 {
-  db close
-  list [catch {sqlite3async_control lockfiles false} msg] $msg
-} {1 SQLITE_MISUSE}
-do_test async4.1.12 {
-  sqlite3async_start
-  sqlite3async_wait
-  sqlite3async_control lockfiles false
-} {0}
-do_test async4.1.13 {
-  sqlite3 db test.db -vfs sqlite3async
-  execsql { CREATE TABLE t3(a, b, c) } db
-} {}
-do_test async4.1.14 {
-  execsql { 
-    CREATE INDEX i1 ON t2(a);
-    CREATE INDEX i2 ON t1(a);
-  } db2
-} {}
-do_test async4.1.15 {
-  sqlite3async_start
-  sqlite3async_wait
-  hexio_write test.db 28 00000000
-  execsql { pragma integrity_check } db2
-} {{*** in database main ***
-Page 5 is never used}}
-do_test async4.1.16 {
-  db close
-  db2 close
-  sqlite3async_start
-  sqlite3async_wait
-} {}
-do_test async4.1.17 {
-  sqlite3async_control lockfiles true
-} {1}
-
-do_test async4.2.1 {
-  sqlite3async_control delay
-} {0}
-do_test async4.2.2 {
-  sqlite3async_control delay 23
-} {23}
-do_test async4.2.3 {
-  sqlite3async_control delay
-} {23}
-do_test async4.2.4 {
-  sqlite3async_control delay 0
-} {0}
-do_test async4.2.5 {
-  sqlite3 db test.db -vfs sqlite3async
-
-  execsql { CREATE TABLE t4(a, b) }
-  set T1 [lindex [time {
-    sqlite3async_start
-    sqlite3async_wait
-  }] 0]
-
-  sqlite3async_control delay 100
-  execsql { CREATE TABLE t5(a, b) }
-  set T2 [lindex [time {
-    sqlite3async_start
-    sqlite3async_wait
-  }] 0]
-
-  expr {($T1+1000000) < $T2}
-} {1}
-
-do_test async4.2.6 {
-  sqlite3async_control delay 0
-  execsql { CREATE TABLE t6(a, b) }
-  set T1 [lindex [time {
-    sqlite3async_start
-    sqlite3async_wait
-  }] 0]
-
-  expr {($T1+1000000) < $T2}
-} {1}
-
-do_test async4.2.7 {
-  list [catch { sqlite3async_control delay -1 } msg] $msg
-} {1 SQLITE_MISUSE}
-
-do_test async4.2.8 {
-  db close
-  sqlite3async_start
-  sqlite3async_wait
-} {}
-
-finish_test
diff --git a/test/async5.test b/test/async5.test
deleted file mode 100644 (file)
index abac11f..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-# 2009 July 19
-#
-#    May you do good and not evil.
-#    May you find forgiveness for yourself and forgive others.
-#    May you share freely, never taking more than you give.
-#
-#***********************************************************************
-# This file tests that asynchronous IO is compatible with multi-file
-# transactions.
-#
-# $Id: async5.test,v 1.1 2009/07/18 11:52:04 danielk1977 Exp $
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-
-if {[info commands sqlite3async_initialize] eq ""} {
-  # The async logic is not built into this system
-  finish_test
-  return
-}
-
-db close
-forcedelete test2.db
-sqlite3async_initialize "" 1
-sqlite3async_control halt never
-sqlite3 db test.db
-
-do_test async5-1.1 {
-  execsql {
-    ATTACH 'test2.db' AS next;
-    CREATE TABLE main.t1(a, b);
-    CREATE TABLE next.t2(a, b);
-    BEGIN;
-      INSERT INTO t1 VALUES(1, 2);
-      INSERT INTO t2 VALUES(3, 4);
-    COMMIT;
-  }
-} {}
-do_test async5-1.2 {
-  execsql { SELECT * FROM t1 }
-} {1 2}
-do_test async5-1.3 {
-  execsql { SELECT * FROM t2 }
-} {3 4}
-do_test async5-1.4 {
-  execsql {
-    BEGIN;
-      INSERT INTO t1 VALUES('a', 'b');
-      INSERT INTO t2 VALUES('c', 'd');
-    COMMIT;
-  }
-} {}
-do_test async5-1.5 {
-  execsql { SELECT * FROM t1 }
-} {1 2 a b}
-do_test async5-1.6 {
-  execsql { SELECT * FROM t2 }
-} {3 4 c d}
-
-db close
-
-sqlite3async_control halt idle
-sqlite3async_start
-sqlite3async_wait
-sqlite3async_control halt never
-sqlite3async_shutdown
-set sqlite3async_trace 0
-finish_test
index 534aa3b9a44aa420cc12a855a3febc93c899f671..cacb6d3ff1640b924a7bbc7f9275f362c95807fc 100644 (file)
@@ -21,7 +21,7 @@ source $testdir/tester.tcl
 #
 do_test lock-1.0 {
   # Give a complex pathname to stress the path simplification logic in
-  # the vxworks driver and in test_async.
+  # the vxworks driver.
   file mkdir tempdir/t1/t2
   sqlite3 db2 ./tempdir/../tempdir/t1/.//t2/../../..//test.db
   set dummy {}
index cdf9fb99e08616b9bc95955ea6d87c049ee91129..556a8bdfccbf5e1bce2d711a8a86f0b65f35944e 100644 (file)
@@ -472,49 +472,6 @@ do_test main-3.6 {
   catchsql {SELECT 'abc' + #9}
 } {1 {near "#9": syntax error}}
 
-# The following test-case tests the linked list code used to manage
-# sqlite3_vfs structures.
-if {$::tcl_platform(platform)=="unix" 
-     && [info command sqlite3async_initialize]!=""} {
-  ifcapable threadsafe {
-    do_test main-4.1 {
-      sqlite3_crash_enable 1
-      sqlite3_crash_enable 0
-    
-      sqlite3async_initialize "" 1
-      sqlite3async_shutdown
-    
-      sqlite3_crash_enable 1
-      sqlite3async_initialize "" 1
-      sqlite3_crash_enable 0
-      sqlite3async_shutdown
-    
-      sqlite3_crash_enable 1
-      sqlite3async_initialize "" 1
-      sqlite3async_shutdown
-      sqlite3_crash_enable 0
-    
-      sqlite3async_initialize "" 1
-      sqlite3_crash_enable 1
-      sqlite3_crash_enable 0
-      sqlite3async_shutdown
-    
-      sqlite3async_initialize "" 1
-      sqlite3_crash_enable 1
-      sqlite3async_shutdown
-      sqlite3_crash_enable 0
-    } {}
-    do_test main-4.2 {
-      set rc [catch {sqlite3 db test.db -vfs crash} msg]
-      list $rc $msg
-    } {1 {no such vfs: crash}}
-    do_test main-4.3 {
-      set rc [catch {sqlite3 db test.db -vfs async} msg]
-      list $rc $msg
-    } {1 {no such vfs: async}}
-  }
-}
-
 # Print the version number so that it can be picked up by releasetest.tcl.
 #
 puts [db one {SELECT 'VERSION: ' ||
index a24a901f50748e743dd202daf1ae8fd4118fc74c..8443162ed6e1e1295c85d966567171111f0a049b 100644 (file)
@@ -38,8 +38,6 @@ set EXCLUDE {
   misuse.test
   memleak.test
   btree2.test
-  async.test
-  async2.test
   trans.test
   crash.test
   autovacuum_crash.test
index c26d6ead1486092a91e050b355b56fdda1738293..5bbef184c73ecb4a2678e324ca14206ef8e3afd7 100644 (file)
@@ -108,14 +108,14 @@ if {$::tcl_platform(platform)!="unix"} {
   set alltests [test_set $alltests -exclude crash.test crash2.test]
 }
 set alltests [test_set $alltests -exclude {
-  all.test        async.test         quick.test  veryquick.test
+  all.test        quick.test  veryquick.test
   memleak.test    permutations.test  soak.test   fts3.test
   mallocAll.test  rtree.test         full.test   extraquick.test
   session.test    rbu.test
 }]
 
 set allquicktests [test_set $alltests -exclude {
-  async2.test async3.test backup_ioerr.test corrupt.test
+  backup_ioerr.test corrupt.test
   corruptC.test crash.test crash2.test crash3.test crash4.test crash5.test
   crash6.test crash7.test delete3.test e_fts3.test fts3rnd.test
   fkey_malloc.test fuzz.test fuzz3.test fuzz_malloc.test in2.test loadext.test
@@ -790,7 +790,7 @@ test_suite "inmemory_journal" -description {
   journal3.test 8_3_names.test shmlock.test
   pendingrace.test
 
-  pager1.test async4.test corrupt.test filefmt.test pager2.test
+  pager1.test corrupt.test filefmt.test pager2.test
   corrupt5.test corruptA.test pageropt.test
 
   # Exclude stmt.test, which expects sub-journals to use temporary files.
@@ -951,12 +951,11 @@ test_suite "safe_append" -description {
   set ::G(perm:sqlite3_args) [list -vfs devsym]
   sqlite3_simulate_device -char safe_append
 } -files [
-  test_set $::allquicktests shared_err.test -exclude async3.test
+  test_set $::allquicktests shared_err.test
 ]
 
 # The set of tests to run on the alternative-pcache
 set perm-alt-pcache-testset {
-  async.test
   attach.test
   delete.test delete2.test
   index.test
@@ -997,7 +996,7 @@ test_suite "journaltest" -description {
   unregister_jt_vfs
 } -files [test_set $::allquicktests -exclude {
   wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test 
-  async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test
+  bigfile.test backcompat.test e_wal* fstat.test mmap2.test
   pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock*
   pager2.test *fault* rowal* snapshot* superlock* symlink.test
   delete_db.test shmlock.test chunksize.test
diff --git a/test/tkt-94c04eaadb.test b/test/tkt-94c04eaadb.test
deleted file mode 100644 (file)
index 9de8aea..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-# 2009 October 19
-#
-# The author disclaims copyright to this source code.  In place of
-# a legal notice, here is a blessing:
-#
-#    May you do good and not evil.
-#    May you find forgiveness for yourself and forgive others.
-#    May you share freely, never taking more than you give.
-#
-#***********************************************************************
-# This file implements regression tests for SQLite library.
-#
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-
-if {[info commands sqlite3async_initialize] eq ""} {
-  # The async logic is not built into this system
-  finish_test
-  return
-}
-
-# Create a database.
-do_test tkt-94c94-1.1 {
-  execsql { CREATE TABLE t1(a, b) }
-} {}
-
-# Grow the file to larger than 4096MB (2^32 bytes)
-db close
-if {[catch {fake_big_file 4096 [get_pwd]/test.db} msg]} {
-  puts "**** Unable to create a file larger than 4096 MB. *****"
-  finish_test
-  return
-}
-
-# Switch to async mode.
-sqlite3async_initialize "" 1
-sqlite3 db test.db
-sqlite3 db2 test.db
-
-# Read from and write to the db just past the 4096MB mark.
-#
-do_test tkt-94c94-2.1 {
-  execsql { CREATE TABLE t2(x, y) } db
-} {}
-do_test tkt-94c94-2.2 {
-  execsql { INSERT INTO t2 VALUES(1, 2) } db2
-} {}
-do_test tkt-94c94-2.3 {
-  execsql { SELECT * FROM t2 } db
-} {1 2}
-do_test tkt-94c94-2.4 {
-  sqlite3async_control halt idle
-  sqlite3async_start
-  sqlite3async_wait
-} {}
-do_test tkt-94c94-2.5 {
-  execsql { SELECT * FROM t2 } db
-} {1 2}
-do_test tkt-94c94-2.6 {
-  sqlite3async_start
-  sqlite3async_wait
-} {}
-
-db close
-db2 close
-sqlite3async_start
-sqlite3async_wait
-sqlite3async_control halt never
-sqlite3async_shutdown
-
-finish_test