/* ** 2011-02-02 ** ** 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 is part of the test program "threadtest3". Despite being a C ** file it is not compiled separately, but included by threadtest3.c using ** the #include directive normally used with header files. ** ** This file contains the implementation of test cases: ** ** bcwal2_1 */ static char *bcwal2_1_checkpointer(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ int nIter = 0; opendb(&err, &db, "test.db", 0); while( !timetostop(&err) ){ sql_script(&err, &db, "PRAGMA wal_checkpoint;"); nIter++; } closedb(&err, &db); print_and_free_err(&err); return sqlite3_mprintf("%d iterations", nIter); } static char *bcwal2_1_integrity(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ int nIter = 0; opendb(&err, &db, "test.db", 0); while( !timetostop(&err) ){ // integrity_check(&err, &db); sql_script(&err, &db, "SELECT * FROM t1;"); nIter++; } closedb(&err, &db); print_and_free_err(&err); return sqlite3_mprintf("%d integrity-checks", nIter); } static char *bcwal2_1_writer(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ int nWrite = 0; /* Writes so far */ int nBusy = 0; /* Busy errors so far */ sqlite3_mutex *pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_APP1); opendb(&err, &db, "test.db", 0); while( !timetostop(&err) ){ sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 0;" "BEGIN CONCURRENT;" " REPLACE INTO t1 VALUES( abs(random() % 100000), " " hex(randomblob( abs( random() % 200 ) + 50 ))" " );" ); if( err.rc==SQLITE_OK ){ sqlite3_mutex_enter(pMutex); sql_script(&err, &db, "COMMIT"); sqlite3_mutex_leave(pMutex); if( err.rc==SQLITE_OK ){ nWrite++; }else{ clear_error(&err, SQLITE_BUSY); sql_script(&err, &db, "ROLLBACK"); nBusy++; } assert( err.rc!=SQLITE_OK || sqlite3_get_autocommit(db.db)==1 ); } } closedb(&err, &db); print_and_free_err(&err); return sqlite3_mprintf("%d successful writes, %d busy", nWrite, nBusy); } static void bcwal2_1(int nMs){ Error err = {0}; Sqlite db = {0}; Threadset threads = {0}; opendb(&err, &db, "test.db", 1); sql_script(&err, &db, "PRAGMA page_size = 1024;" "PRAGMA journal_mode = wal2;" "CREATE TABLE t1(ii INTEGER PRIMARY KEY, tt TEXT);" "CREATE INDEX t1tt ON t1(tt);" ); setstoptime(&err, nMs); launch_thread(&err, &threads, bcwal2_1_writer, 0); launch_thread(&err, &threads, bcwal2_1_writer, 0); launch_thread(&err, &threads, bcwal2_1_writer, 0); launch_thread(&err, &threads, bcwal2_1_integrity, 0); launch_thread(&err, &threads, bcwal2_1_checkpointer, 0); join_all_threads(&err, &threads); /* Do a final integrity-check on the db */ integrity_check(&err, &db); closedb(&err, &db); print_and_free_err(&err); }