Tests for the new asynchronous IO API. (CVS 6549)

FossilOrigin-Name: 11b2564e7159168cd0815bb9bc93688586fad1e0
This commit is contained in:
danielk1977 2009-04-25 08:39:14 +00:00
parent 4fa326564a
commit 6f050aa2bf
10 changed files with 306 additions and 132 deletions

View File

@ -90,7 +90,7 @@
AC_INIT(sqlite, m4_esyscmd([cat VERSION | tr -d '\n']))
dnl Make sure the local VERSION file matches this configure script
sqlite_version_sanity_check=`cat VERSION | tr -d '\n'`
sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'`
if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then
AC_MSG_ERROR([configure script is out of date:
configure \$PACKAGE_VERSION = $PACKAGE_VERSION
@ -101,7 +101,7 @@ fi
dnl Put the RCS revision string after AC_INIT so that it will also
dnl show in in configure.
# The following RCS revision string applies to configure.in
# $Revision: 1.55 $
# $Revision: 1.56 $
#########
# Programs needed

View File

@ -10,7 +10,7 @@
**
*************************************************************************
**
** $Id: sqlite3async.c,v 1.3 2009/04/24 10:13:06 danielk1977 Exp $
** $Id: sqlite3async.c,v 1.4 2009/04/25 08:39:15 danielk1977 Exp $
**
** This file contains the implementation of an asynchronous IO backend
** for SQLite.
@ -1550,7 +1550,7 @@ static void asyncWriterThread(void){
async_mutex_leave(ASYNC_MUTEX_QUEUE);
holdingMutex = 0;
if( async.ioDelay>0 ){
pVfs->xSleep(pVfs, async.ioDelay);
pVfs->xSleep(pVfs, async.ioDelay*1000);
}else{
async_sched_yield();
}

View File

@ -1,5 +1,5 @@
C Add\sanother\stest\scase\sfor\sthe\s"x\sIS\sNULL"\suniqueness\sproblem\sof\sticket\s#3824.\nNo\schanges\sto\scode.\s\sThis\sjust\sdouble-checks\sthat\severything\sis\sworking\snow.\s(CVS\s6548)
D 2009-04-24T20:32:31
C Tests\sfor\sthe\snew\sasynchronous\sIO\sAPI.\s(CVS\s6549)
D 2009-04-25T08:39:15
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -19,13 +19,13 @@ F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 868fdb48c028421a203470e15c69ada15b9ba673
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 487875e451ac922f10276ee41611e0967ea72af0 x
F configure.ac 660b4e3e930cdd469e6ac5c1f3d9ba9cec2c8be0
F configure.ac 14740970ddb674d92a9f5da89083dff1179014ff
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
F ext/async/README.txt 0c541f418b14b415212264cbaaf51c924ec62e5b
F ext/async/sqlite3async.c 35eddf1c696c7ab9c92934dec9ff251896d93439
F ext/async/sqlite3async.c 2e1048922c1d544f0d2a7c3533909e5d67f466f2
F ext/async/sqlite3async.h b6d74dbf9aa5a0ac4e79aa15a4d987f3552a0f75
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
@ -176,7 +176,7 @@ F src/test6.c 1a0a7a1f179469044b065b4a88aab9faee114101
F src/test7.c b94e68c2236de76889d82b8d7d8e00ad6a4d80b1
F src/test8.c b1061548f7ce3aeedea3cc4d649ee1487c2b4eaf
F src/test9.c 963d380922f25c1c323712d05db01b19197ee6f7
F src/test_async.c d17e8c21461474d807ca1ee6a51f21210df7cf64
F src/test_async.c 7e16faf71e43ccf748b942d535f25c0b35dfe9c1
F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad
F src/test_backup.c 1384a18985a5a2d275c2662e48473bf1542ebd08
F src/test_btree.c d7b8716544611c323860370ee364e897c861f1b0
@ -222,9 +222,10 @@ F test/alter3.test 25b95a136708f22b87184fa6a4309eea03d65153
F test/alter4.test 9386ffd1e9c7245f43eca412b2058d747509cc1f
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/analyze.test ad5329098fe4de4a96852231d53e3e9e6283ad4b
F test/async.test 44109d3ae82db2071e3c2b417f79258cc05f0f49
F test/async2.test d4da437a6383770b8b2ed3e72ef9eb399e2c6086
F test/async3.test e72255549dde94ef89e9779884001527b44c5389
F test/async.test c042ff6d2a29f65e05d498a52448229d25bb5d9d
F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
F test/async4.test 9e00a380c5cfce90177ed3d2a35d55fc5809a6e6
F test/attach.test 75a5d22f88e730967d68f2c9f95e786e3953d8e3
F test/attach2.test a295d2d7061adcee5884ef4a93c7c96a82765437
F test/attach3.test 7b92dc8e40c1ebca9732ca6f2d3fefbd46f196df
@ -441,7 +442,7 @@ F test/lock4.test 991b57669a868bbfd39fe0c0df0d493985829105
F test/lock5.test 6b1f78f09ad1522843dad571b76b321e6f439bf7
F test/lock6.test 862aa71e97b288d6b3f92ba3313f51bd0b003776
F test/lookaside.test 1dd350dc6dff015c47c07fcc5a727a72fc5bae02
F test/main.test 187a9a1b5248ed74a83838c581c15ec6023b555b
F test/main.test 9b048ee1d2fdbc0a232b87b236d64e9ff7b68e68
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test cd2b9f515ba98beb5e335acdd94c3ad7a6f7fc4a
F test/malloc3.test 4bc57f850b212f706f3e1b37c4eced1d5a727cd1
@ -724,7 +725,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 600482d1619c07690b6517ded9655462bdab7538
R 71d404284132ce2fe7a2834055b5d726
U drh
Z 1cf62362f2b3736c4e9a302fbf33112d
P 3ceae3579bc42974865cf6fe0bc42001e786e894
R 44d916fcf80f3e78683dbc53a4849cab
U danielk1977
Z d6aacbfa0984c74675fa8631efe9436d

View File

@ -1 +1 @@
3ceae3579bc42974865cf6fe0bc42001e786e894
11b2564e7159168cd0815bb9bc93688586fad1e0

View File

@ -10,7 +10,7 @@
**
*************************************************************************
**
** $Id: test_async.c,v 1.60 2009/04/24 10:13:06 danielk1977 Exp $
** $Id: test_async.c,v 1.61 2009/04/25 08:39:15 danielk1977 Exp $
**
** This file contains a binding of the asynchronous IO extension interface
** (defined in ext/async/sqlite3async.h) to Tcl.
@ -25,6 +25,9 @@
#include "sqlite3.h"
#include <assert.h>
/* From test1.c */
const char *sqlite3TestErrorName(int);
struct TestAsyncGlobal {
int isInstalled; /* True when async VFS is installed */
@ -33,101 +36,48 @@ struct TestAsyncGlobal {
TCL_DECLARE_MUTEX(testasync_g_writerMutex);
/*
** sqlite3async_enable ?YES/NO?
**
** Enable or disable the asynchronous I/O backend. This command is
** not thread-safe. Do not call it while any database connections
** are open.
** sqlite3async_initialize PARENT-VFS ISDEFAULT
*/
static int testAsyncEnable(
static int testAsyncInit(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?YES/NO?");
const char *zParent;
int isDefault;
int rc;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "PARENT-VFS ISDEFAULT");
return TCL_ERROR;
}
if( objc==1 ){
Tcl_SetObjResult(interp, Tcl_NewIntObj(testasync_g.isInstalled));
}else{
int enable;
if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ) return TCL_ERROR;
if( enable ){
sqlite3async_initialize(0, 1);
}else{
sqlite3async_shutdown();
}
testasync_g.isInstalled = enable;
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(sqlite3TestErrorName(rc), -1));
return TCL_ERROR;
}
return TCL_OK;
}
/*
** sqlite3async_halt ?"now"|"idle"|"never"?
**
** Set the conditions at which the writer thread will halt.
** sqlite3async_shutdown
*/
static int testAsyncHalt(
static int testAsyncShutdown(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int eWhen;
const char *azConstant[] = { "never", "now", "idle", 0 };
assert( SQLITEASYNC_HALT_NEVER==0 );
assert( SQLITEASYNC_HALT_NOW==1 );
assert( SQLITEASYNC_HALT_IDLE==2 );
if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?OPTION?");
return TCL_ERROR;
}
if( objc==2 ){
if( Tcl_GetIndexFromObj(interp, objv[1], azConstant, "option", 0, &eWhen) ){
return TCL_ERROR;
}
sqlite3async_control(SQLITEASYNC_HALT, eWhen);
}
/* Always return the current value of the 'halt' option. */
sqlite3async_control(SQLITEASYNC_GET_HALT, &eWhen);
Tcl_SetObjResult(interp, Tcl_NewStringObj(azConstant[eWhen], -1));
return TCL_OK;
}
/*
** sqlite3async_delay ?MS?
**
** Query or set the number of milliseconds of delay in the writer
** thread after each write operation. The default is 0. By increasing
** the memory delay we can simulate the effect of slow disk I/O.
*/
static int testAsyncDelay(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int iMs;
if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?MS?");
return TCL_ERROR;
}
if( objc==2 ){
if( Tcl_GetIntFromObj(interp, objv[1], &iMs) ){
return TCL_ERROR;
}
sqlite3async_control(SQLITEASYNC_DELAY, iMs);
}
/* Always return the current value of the 'delay' option. */
sqlite3async_control(SQLITEASYNC_GET_DELAY, &iMs);
Tcl_SetObjResult(interp, Tcl_NewIntObj(iMs));
sqlite3async_shutdown();
return TCL_OK;
}
@ -199,6 +149,79 @@ static int testAsyncWait(
return TCL_OK;
}
/*
** sqlite3async_control OPTION ?VALUE?
*/
static int 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(sqlite3TestErrorName(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 */
/*
@ -208,11 +231,12 @@ static int testAsyncWait(
*/
int Sqlitetestasync_Init(Tcl_Interp *interp){
#if SQLITE_ENABLE_ASYNCIO
Tcl_CreateObjCommand(interp,"sqlite3async_enable",testAsyncEnable,0,0);
Tcl_CreateObjCommand(interp,"sqlite3async_halt",testAsyncHalt,0,0);
Tcl_CreateObjCommand(interp,"sqlite3async_delay",testAsyncDelay,0,0);
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;
}

View File

@ -6,12 +6,12 @@
#***********************************************************************
# This file runs all tests.
#
# $Id: async.test,v 1.19 2009/04/11 10:25:04 danielk1977 Exp $
# $Id: async.test,v 1.20 2009/04/25 08:39:15 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {[catch {sqlite3async_enable}]} {
if {[info commands sqlite3async_initialize] eq ""} {
# The async logic is not built into this system
finish_test
return
@ -41,15 +41,15 @@ set ASYNC_INCLUDE {
}
# Enable asynchronous IO.
sqlite3async_enable 1
sqlite3async_initialize "" 1
rename do_test async_really_do_test
proc do_test {name args} {
uplevel async_really_do_test async_io-$name $args
sqlite3async_start
sqlite3async_halt idle
sqlite3async_control halt idle
sqlite3async_wait
sqlite3async_halt never
sqlite3async_control halt never
}
foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
@ -62,20 +62,20 @@ foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
# [file delete]). If the asynchronous backend still has the file
# open, it will become confused.
#
sqlite3async_halt idle
sqlite3async_control halt idle
sqlite3async_start
sqlite3async_wait
sqlite3async_halt never
sqlite3async_control halt never
}
# Flush the write-queue and disable asynchronous IO. This should ensure
# all allocated memory is cleaned up.
set sqlite3async_trace 1
sqlite3async_halt idle
sqlite3async_control halt idle
sqlite3async_start
sqlite3async_wait
sqlite3async_halt never
sqlite3async_enable 0
sqlite3async_control halt never
sqlite3async_shutdown
set sqlite3async_trace 0
rename do_test {}

View File

@ -5,14 +5,14 @@
#
#***********************************************************************
#
# $Id: async2.test,v 1.11 2009/04/23 18:41:26 shane Exp $
# $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_enable]=="" ||
[info commands sqlite3async_initialize]=="" ||
[info command sqlite3_memdebug_fail]==""
} {
# The async logic is not built into this system
@ -56,7 +56,7 @@ foreach err [list ioerr malloc-transient malloc-persistent] {
execsql $::setup_script
db close
sqlite3async_enable 1
sqlite3async_initialize "" 1
sqlite3 db test.db
sqlite3_db_config_lookaside db 0 0 0
@ -69,11 +69,11 @@ foreach err [list ioerr malloc-transient malloc-persistent] {
catchsql $::sql_script
db close
sqlite3async_halt idle
sqlite3async_control halt idle
sqlite3async_start
sqlite3async_wait
sqlite3async_halt never
sqlite3async_enable 0
sqlite3async_control halt never
sqlite3async_shutdown
set ::sqlite_io_error_pending 0
sqlite3_memdebug_fail -1

View File

@ -13,12 +13,12 @@
# Specifically, it tests that the xFullPathname() method of
# of the asynchronous vfs works correctly.
#
# $Id: async3.test,v 1.4 2009/03/28 18:56:14 drh Exp $
# $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_enable]=="" } {
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
@ -26,7 +26,7 @@ if { [info commands sqlite3async_enable]=="" } {
}
db close
sqlite3async_enable 1
sqlite3async_initialize "" 1
#set sqlite3async_trace 1
sqlite3async_start
@ -69,8 +69,8 @@ foreach p $paths {
db close
sqlite3async_halt idle
sqlite3async_control halt idle
sqlite3async_wait
sqlite3async_halt never
sqlite3async_enable 0
sqlite3async_control halt never
sqlite3async_shutdown
finish_test

149
test/async4.test Normal file
View File

@ -0,0 +1,149 @@
# 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.1 2009/04/25 08:39:15 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
# 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
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.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

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is exercising the code in main.c.
#
# $Id: main.test,v 1.30 2008/09/18 18:18:29 drh Exp $
# $Id: main.test,v 1.31 2009/04/25 08:39:15 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -444,33 +444,33 @@ do_test main-3.6 {
# The following test-case tests the linked list code used to manage
# sqlite3_vfs structures.
if {$::tcl_platform(platform)=="unix"
&& [info command sqlite3async_enable]!=""} {
&& [info command sqlite3async_initialize]!=""} {
ifcapable threadsafe {
do_test main-4.1 {
sqlite3_crash_enable 1
sqlite3_crash_enable 0
sqlite3async_enable 1
sqlite3async_enable 0
sqlite3async_initialize "" 1
sqlite3async_shutdown
sqlite3_crash_enable 1
sqlite3async_enable 1
sqlite3async_initialize "" 1
sqlite3_crash_enable 0
sqlite3async_enable 0
sqlite3async_shutdown
sqlite3_crash_enable 1
sqlite3async_enable 1
sqlite3async_enable 0
sqlite3async_initialize "" 1
sqlite3async_shutdown
sqlite3_crash_enable 0
sqlite3async_enable 1
sqlite3async_initialize "" 1
sqlite3_crash_enable 1
sqlite3_crash_enable 0
sqlite3async_enable 0
sqlite3async_shutdown
sqlite3async_enable 1
sqlite3async_initialize "" 1
sqlite3_crash_enable 1
sqlite3async_enable 0
sqlite3async_shutdown
sqlite3_crash_enable 0
} {}
do_test main-4.2 {