persistentstorage/sqlite3api/TEST/TclScript/threadtest2.c
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 /*
       
     2 ** 2004 January 13
       
     3 **
       
     4 ** The author disclaims copyright to this source code.  In place of
       
     5 ** 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 whether
       
    13 ** or not the SQLite library is threadsafe.
       
    14 **
       
    15 ** This file is NOT part of the standard SQLite library.  It is used for
       
    16 ** 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 database
       
    27 */
       
    28 #define DB_FILE "test.db"
       
    29 
       
    30 /* 
       
    31 ** When this variable becomes non-zero, all threads stop
       
    32 ** what they are doing.
       
    33 */
       
    34 volatile int all_stop = 0;
       
    35 
       
    36 /* 
       
    37 ** Callback from the integrity check.  If the result is anything other
       
    38 ** than "ok" it means the integrity check has failed.  Set the "all_stop"
       
    39 ** global variable to stop all other activity.  Print the error message
       
    40 ** or print OK if the string "ok" is seen.
       
    41 */
       
    42 int 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,"id: %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 check
       
    55 ** fails, try it a second time.
       
    56 */
       
    57 int 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 thread
       
    73 */
       
    74 void *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 threads
       
    97 */
       
    98 int 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 }