threadtest2.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. ** Name of the database
  26. */
  27. #define DB_FILE "test.db"
  28. /*
  29. ** When this variable becomes non-zero, all threads stop
  30. ** what they are doing.
  31. */
  32. volatile int all_stop = 0;
  33. /*
  34. ** Callback from the integrity check. If the result is anything other
  35. ** than "ok" it means the integrity check has failed. Set the "all_stop"
  36. ** global variable to stop all other activity. Print the error message
  37. ** or print OK if the string "ok" is seen.
  38. */
  39. int check_callback(void *pid, int argc, char **argv, char **notUsed2){
  40. int id = (int)pid;
  41. if( strcmp(argv[0],"ok") ){
  42. all_stop = 1;
  43. fprintf(stderr,"id: %s\n", id, argv[0]);
  44. }else{
  45. /* fprintf(stderr,"%d: OK\n", id); */
  46. }
  47. return 0;
  48. }
  49. /*
  50. ** Do an integrity check on the database. If the first integrity check
  51. ** fails, try it a second time.
  52. */
  53. int integrity_check(sqlite *db, int id){
  54. int rc;
  55. if( all_stop ) return 0;
  56. /* fprintf(stderr,"%d: CHECK\n", id); */
  57. rc = sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
  58. if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
  59. fprintf(stderr,"%d, Integrity check returns %d\n", id, rc);
  60. }
  61. if( all_stop ){
  62. sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
  63. }
  64. return 0;
  65. }
  66. /*
  67. ** This is the worker thread
  68. */
  69. void *worker(void *workerArg){
  70. sqlite *db;
  71. int id = (int)workerArg;
  72. int rc;
  73. int cnt = 0;
  74. fprintf(stderr, "Starting worker %d\n", id);
  75. while( !all_stop && cnt++<10000 ){
  76. if( cnt%100==0 ) printf("%d: %d\n", id, cnt);
  77. while( (sqlite3_open(DB_FILE, &db))!=SQLITE_OK ) sched_yield();
  78. sqlite3_exec(db, "PRAGMA synchronous=OFF", 0, 0, 0);
  79. /* integrity_check(db, id); */
  80. if( all_stop ){ sqlite3_close(db); break; }
  81. /* fprintf(stderr, "%d: BEGIN\n", id); */
  82. rc = sqlite3_exec(db, "INSERT INTO t1 VALUES('bogus data')", 0, 0, 0);
  83. /* fprintf(stderr, "%d: END rc=%d\n", id, rc); */
  84. sqlite3_close(db);
  85. }
  86. fprintf(stderr, "Worker %d finished\n", id);
  87. return 0;
  88. }
  89. /*
  90. ** Initialize the database and start the threads
  91. */
  92. int main(int argc, char **argv){
  93. sqlite *db;
  94. int i, rc;
  95. pthread_t aThread[5];
  96. if( strcmp(DB_FILE,":memory:") ){
  97. char *zJournal = sqlite3_mprintf("%s-journal", DB_FILE);
  98. unlink(DB_FILE);
  99. unlink(zJournal);
  100. sqlite3_free(zJournal);
  101. }
  102. sqlite3_open(DB_FILE, &db);
  103. if( db==0 ){
  104. fprintf(stderr,"unable to initialize database\n");
  105. exit(1);
  106. }
  107. rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);
  108. if( rc ){
  109. fprintf(stderr,"cannot create table t1: %d\n", rc);
  110. exit(1);
  111. }
  112. sqlite3_close(db);
  113. for(i=0; i<sizeof(aThread)/sizeof(aThread[0]); i++){
  114. pthread_create(&aThread[i], 0, worker, (void*)i);
  115. }
  116. for(i=0; i<sizeof(aThread)/sizeof(aThread[i]); i++){
  117. pthread_join(aThread[i], 0);
  118. }
  119. if( !all_stop ){
  120. printf("Everything seems ok.\n");
  121. return 0;
  122. }else{
  123. printf("We hit an error.\n");
  124. return 1;
  125. }
  126. }