os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/threadtest2.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/threadtest2.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,133 @@
     1.4 +/*
     1.5 +** 2004 January 13
     1.6 +**
     1.7 +** The author disclaims copyright to this source code.  In place of
     1.8 +** a legal notice, here is a blessing:
     1.9 +**
    1.10 +**    May you do good and not evil.
    1.11 +**    May you find forgiveness for yourself and forgive others.
    1.12 +**    May you share freely, never taking more than you give.
    1.13 +**
    1.14 +*************************************************************************
    1.15 +** This file implements a simple standalone program used to test whether
    1.16 +** or not the SQLite library is threadsafe.
    1.17 +**
    1.18 +** This file is NOT part of the standard SQLite library.  It is used for
    1.19 +** testing only.
    1.20 +*/
    1.21 +#include <stdio.h>
    1.22 +#include <unistd.h>
    1.23 +#include <pthread.h>
    1.24 +#include <string.h>
    1.25 +#include <stdlib.h>
    1.26 +#include "sqlite.h"
    1.27 +
    1.28 +/*
    1.29 +** Name of the database
    1.30 +*/
    1.31 +#define DB_FILE "test.db"
    1.32 +
    1.33 +/* 
    1.34 +** When this variable becomes non-zero, all threads stop
    1.35 +** what they are doing.
    1.36 +*/
    1.37 +volatile int all_stop = 0;
    1.38 +
    1.39 +/* 
    1.40 +** Callback from the integrity check.  If the result is anything other
    1.41 +** than "ok" it means the integrity check has failed.  Set the "all_stop"
    1.42 +** global variable to stop all other activity.  Print the error message
    1.43 +** or print OK if the string "ok" is seen.
    1.44 +*/
    1.45 +int check_callback(void *pid, int argc, char **argv, char **notUsed2){
    1.46 +  int id = (int)pid;
    1.47 +  if( strcmp(argv[0],"ok") ){
    1.48 +    all_stop = 1;
    1.49 +    fprintf(stderr,"id: %s\n", id, argv[0]);
    1.50 +  }else{
    1.51 +    /* fprintf(stderr,"%d: OK\n", id); */
    1.52 +  }
    1.53 +  return 0;
    1.54 +}
    1.55 +
    1.56 +/*
    1.57 +** Do an integrity check on the database.  If the first integrity check
    1.58 +** fails, try it a second time.
    1.59 +*/
    1.60 +int integrity_check(sqlite *db, int id){
    1.61 +  int rc;
    1.62 +  if( all_stop ) return 0;
    1.63 +  /* fprintf(stderr,"%d: CHECK\n", id); */
    1.64 +  rc = sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
    1.65 +  if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
    1.66 +    fprintf(stderr,"%d, Integrity check returns %d\n", id, rc);
    1.67 +  }
    1.68 +  if( all_stop ){
    1.69 +    sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
    1.70 +  }
    1.71 +  return 0;
    1.72 +}
    1.73 +
    1.74 +/*
    1.75 +** This is the worker thread
    1.76 +*/
    1.77 +void *worker(void *workerArg){
    1.78 +  sqlite *db;
    1.79 +  int id = (int)workerArg;
    1.80 +  int rc;
    1.81 +  int cnt = 0;
    1.82 +  fprintf(stderr, "Starting worker %d\n", id);
    1.83 +  while( !all_stop && cnt++<10000 ){
    1.84 +    if( cnt%100==0 ) printf("%d: %d\n", id, cnt);
    1.85 +    while( (sqlite3_open(DB_FILE, &db))!=SQLITE_OK ) sched_yield();
    1.86 +    sqlite3_exec(db, "PRAGMA synchronous=OFF", 0, 0, 0);
    1.87 +    /* integrity_check(db, id); */
    1.88 +    if( all_stop ){ sqlite3_close(db); break; }
    1.89 +    /* fprintf(stderr, "%d: BEGIN\n", id); */
    1.90 +    rc = sqlite3_exec(db, "INSERT INTO t1 VALUES('bogus data')", 0, 0, 0);
    1.91 +    /* fprintf(stderr, "%d: END rc=%d\n", id, rc); */
    1.92 +    sqlite3_close(db);
    1.93 +  }
    1.94 +  fprintf(stderr, "Worker %d finished\n", id);
    1.95 +  return 0;
    1.96 +}
    1.97 +
    1.98 +/*
    1.99 +** Initialize the database and start the threads
   1.100 +*/
   1.101 +int main(int argc, char **argv){
   1.102 +  sqlite *db;
   1.103 +  int i, rc;
   1.104 +  pthread_t aThread[5];
   1.105 +
   1.106 +  if( strcmp(DB_FILE,":memory:") ){
   1.107 +    char *zJournal = sqlite3_mprintf("%s-journal", DB_FILE);
   1.108 +    unlink(DB_FILE);
   1.109 +    unlink(zJournal);
   1.110 +    sqlite3_free(zJournal);
   1.111 +  }  
   1.112 +  sqlite3_open(DB_FILE, &db);
   1.113 +  if( db==0 ){
   1.114 +    fprintf(stderr,"unable to initialize database\n");
   1.115 +    exit(1);
   1.116 +  }
   1.117 +  rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);
   1.118 +  if( rc ){
   1.119 +    fprintf(stderr,"cannot create table t1: %d\n", rc);
   1.120 +    exit(1);
   1.121 +  }
   1.122 +  sqlite3_close(db);
   1.123 +  for(i=0; i<sizeof(aThread)/sizeof(aThread[0]); i++){
   1.124 +    pthread_create(&aThread[i], 0, worker, (void*)i);
   1.125 +  }
   1.126 +  for(i=0; i<sizeof(aThread)/sizeof(aThread[i]); i++){
   1.127 +    pthread_join(aThread[i], 0);
   1.128 +  }
   1.129 +  if( !all_stop ){
   1.130 +    printf("Everything seems ok.\n");
   1.131 +    return 0;
   1.132 +  }else{
   1.133 +    printf("We hit an error.\n");
   1.134 +    return 1;
   1.135 +  }
   1.136 +}