AryaWu/sqlite
0
1/*2** 2004 January 133**4** The author disclaims copyright to this source code. In place of5** a legal notice, here is a blessing:6**7** May you do good and not evil.8** May you find forgiveness for yourself and forgive others.9** May you share freely, never taking more than you give.10**11*************************************************************************12** This file implements a simple standalone program used to test whether13** or not the SQLite library is threadsafe.14**15** This file is NOT part of the standard SQLite library. It is used for16** testing only.17*/18#include <stdio.h>19#include <unistd.h>20#include <pthread.h>21#include <string.h>22#include <stdlib.h>23#include "sqlite.h"24 25/*26** Name of the database27*/28#define DB_FILE "test.db"29 30/* 31** When this variable becomes non-zero, all threads stop32** what they are doing.33*/34volatile int all_stop = 0;35 36/* 37** Callback from the integrity check. If the result is anything other38** than "ok" it means the integrity check has failed. Set the "all_stop"39** global variable to stop all other activity. Print the error message40** or print OK if the string "ok" is seen.41*/42int check_callback(void *pid, int argc, char **argv, char **notUsed2){43 int id = (int)pid;44 if( strcmp(argv[0],"ok") ){45 all_stop = 1;46 fprintf(stderr,"%d: %s\n", id, argv[0]);47 }else{48 /* fprintf(stderr,"%d: OK\n", id); */49 }50 return 0;51}52 53/*54** Do an integrity check on the database. If the first integrity check55** fails, try it a second time.56*/57int integrity_check(sqlite *db, int id){58 int rc;59 if( all_stop ) return 0;60 /* fprintf(stderr,"%d: CHECK\n", id); */61 rc = sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);62 if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){63 fprintf(stderr,"%d, Integrity check returns %d\n", id, rc);64 }65 if( all_stop ){66 sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);67 }68 return 0;69}70 71/*72** This is the worker thread73*/74void *worker(void *workerArg){75 sqlite *db;76 int id = (int)workerArg;77 int rc;78 int cnt = 0;79 fprintf(stderr, "Starting worker %d\n", id);80 while( !all_stop && cnt++<10000 ){81 if( cnt%100==0 ) printf("%d: %d\n", id, cnt);82 while( (sqlite3_open(DB_FILE, &db))!=SQLITE_OK ) sched_yield();83 sqlite3_exec(db, "PRAGMA synchronous=OFF", 0, 0, 0);84 /* integrity_check(db, id); */85 if( all_stop ){ sqlite3_close(db); break; }86 /* fprintf(stderr, "%d: BEGIN\n", id); */87 rc = sqlite3_exec(db, "INSERT INTO t1 VALUES('bogus data')", 0, 0, 0);88 /* fprintf(stderr, "%d: END rc=%d\n", id, rc); */89 sqlite3_close(db);90 }91 fprintf(stderr, "Worker %d finished\n", id);92 return 0;93}94 95/*96** Initialize the database and start the threads97*/98int main(int argc, char **argv){99 sqlite *db;100 int i, rc;101 pthread_t aThread[5];102 103 if( strcmp(DB_FILE,":memory:") ){104 char *zJournal = sqlite3_mprintf("%s-journal", DB_FILE);105 unlink(DB_FILE);106 unlink(zJournal);107 sqlite3_free(zJournal);108 } 109 sqlite3_open(DB_FILE, &db);110 if( db==0 ){111 fprintf(stderr,"unable to initialize database\n");112 exit(1);113 }114 rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);115 if( rc ){116 fprintf(stderr,"cannot create table t1: %d\n", rc);117 exit(1);118 }119 sqlite3_close(db);120 for(i=0; i<sizeof(aThread)/sizeof(aThread[0]); i++){121 pthread_create(&aThread[i], 0, worker, (void*)i);122 }123 for(i=0; i<sizeof(aThread)/sizeof(aThread[i]); i++){124 pthread_join(aThread[i], 0);125 }126 if( !all_stop ){127 printf("Everything seems ok.\n");128 return 0;129 }else{130 printf("We hit an error.\n");131 return 1;132 }133}134 