/ Check-in [06216d0d]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Get threadtest2.c working again after being long neglected. (CVS 3562)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 06216d0d3be38bfabda9f5f450a5eaccd20b52b9
User & Date: drh 2007-01-05 01:58:27
Context
2007-01-05
02:00
In the btree.c, when releasing the page1 lock, first make sure the pager has not reset and released the lock already. This fixes a bug introduced by (3549). (CVS 3563) check-in: 36a2db96 user: drh tags: trunk
01:58
Get threadtest2.c working again after being long neglected. (CVS 3562) check-in: 06216d0d user: drh tags: trunk
00:14
Fix a test case that changed due to (3560). Ticket #2143 (CVS 3561) check-in: c28664d3 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to test/threadtest2.c.

35
36
37
38
39
40
41
42

43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76

77
78

79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

/* 
** Callback from the integrity check.  If the result is anything other
** than "ok" it means the integrity check has failed.  Set the "all_stop"
** global variable to stop all other activity.  Print the error message
** or print OK if the string "ok" is seen.
*/
int check_callback(void *notUsed, int argc, char **argv, char **notUsed2){

  if( strcmp(argv[0],"ok") ){
    all_stop = 1;
    fprintf(stderr,"pid=%d. %s\n", getpid(), argv[0]);

  }else{
    /* fprintf(stderr,"pid=%d. OK\n", getpid()); */
  }
  return 0;
}

/*
** Do an integrity check on the database.  If the first integrity check
** fails, try it a second time.
*/
int integrity_check(sqlite *db){
  int rc;
  if( all_stop ) return 0;
  /* fprintf(stderr,"pid=%d: CHECK\n", getpid()); */
  rc = sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
  if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
    fprintf(stderr,"pid=%d, Integrity check returns %d\n", getpid(), rc);
  }
  if( all_stop ){
    sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
  }
  return 0;
}

/*
** This is the worker thread
*/
void *worker(void *notUsed){
  sqlite *db;

  int rc;
  int cnt = 0;

  while( !all_stop && cnt++<10000 ){
    if( cnt%1000==0 ) printf("pid=%d: %d\n", getpid(), cnt);

    while( (sqlite3_open(DB_FILE, &db))!=SQLITE_OK ) sched_yield();
    sqlite3_exec(db, "PRAGMA synchronous=OFF", 0, 0, 0);
    integrity_check(db);
    if( all_stop ){ sqlite3_close(db); break; }
    /* fprintf(stderr, "pid=%d: BEGIN\n", getpid()); */
    rc = sqlite3_exec(db, "INSERT INTO t1 VALUES('bogus data')", 0, 0, 0);
    /* fprintf(stderr, "pid=%d: END rc=%d\n", getpid(), rc); */
    sqlite3_close(db);
  }

  return 0;
}

/*
** Initialize the database and start the threads
*/
int main(int argc, char **argv){
................................................................................
  int i, rc;
  pthread_t aThread[5];

  if( strcmp(DB_FILE,":memory:") ){
    char *zJournal = sqlite3_mprintf("%s-journal", DB_FILE);
    unlink(DB_FILE);
    unlink(zJournal);
    free(zJournal);
  }  
  sqlite3_open(DB_FILE, &db);
  if( db==0 ){
    fprintf(stderr,"unable to initialize database\n");
    exit(1);
  }
  rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);
  if( rc ){
    fprintf(stderr,"cannot create table t1: %d\n", rc);
    exit(1);
  }
  sqlite3_close(db);
  for(i=0; i<sizeof(aThread)/sizeof(aThread[0]); i++){
    pthread_create(&aThread[i], 0, worker, 0);
  }
  for(i=0; i<sizeof(aThread)/sizeof(aThread[i]); i++){
    pthread_join(aThread[i], 0);
  }
  if( !all_stop ){
    printf("Everything seems ok.\n");
    return 0;
  }else{
    printf("We hit an error.\n");
    return 1;
  }
}







|
>


<
>

|








|


|


|










|

>


>

<
>


|

|

|


>







 







|













|












35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

/* 
** Callback from the integrity check.  If the result is anything other
** than "ok" it means the integrity check has failed.  Set the "all_stop"
** global variable to stop all other activity.  Print the error message
** or print OK if the string "ok" is seen.
*/
int check_callback(void *pid, int argc, char **argv, char **notUsed2){
  int id = (int)pid;
  if( strcmp(argv[0],"ok") ){
    all_stop = 1;

    fprintf(stderr,"id: %s\n", id, argv[0]);
  }else{
    /* fprintf(stderr,"%d: OK\n", id); */
  }
  return 0;
}

/*
** Do an integrity check on the database.  If the first integrity check
** fails, try it a second time.
*/
int integrity_check(sqlite *db, int id){
  int rc;
  if( all_stop ) return 0;
  /* fprintf(stderr,"%d: CHECK\n", id); */
  rc = sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
  if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
    fprintf(stderr,"%d, Integrity check returns %d\n", id, rc);
  }
  if( all_stop ){
    sqlite3_exec(db, "pragma integrity_check", check_callback, 0, 0);
  }
  return 0;
}

/*
** This is the worker thread
*/
void *worker(void *workerArg){
  sqlite *db;
  int id = (int)workerArg;
  int rc;
  int cnt = 0;
  fprintf(stderr, "Starting worker %d\n", id);
  while( !all_stop && cnt++<10000 ){

    if( cnt%100==0 ) printf("%d: %d\n", id, cnt);
    while( (sqlite3_open(DB_FILE, &db))!=SQLITE_OK ) sched_yield();
    sqlite3_exec(db, "PRAGMA synchronous=OFF", 0, 0, 0);
    /* integrity_check(db, id); */
    if( all_stop ){ sqlite3_close(db); break; }
    /* fprintf(stderr, "%d: BEGIN\n", id); */
    rc = sqlite3_exec(db, "INSERT INTO t1 VALUES('bogus data')", 0, 0, 0);
    /* fprintf(stderr, "%d: END rc=%d\n", id, rc); */
    sqlite3_close(db);
  }
  fprintf(stderr, "Worker %d finished\n", id);
  return 0;
}

/*
** Initialize the database and start the threads
*/
int main(int argc, char **argv){
................................................................................
  int i, rc;
  pthread_t aThread[5];

  if( strcmp(DB_FILE,":memory:") ){
    char *zJournal = sqlite3_mprintf("%s-journal", DB_FILE);
    unlink(DB_FILE);
    unlink(zJournal);
    sqlite3_free(zJournal);
  }  
  sqlite3_open(DB_FILE, &db);
  if( db==0 ){
    fprintf(stderr,"unable to initialize database\n");
    exit(1);
  }
  rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);
  if( rc ){
    fprintf(stderr,"cannot create table t1: %d\n", rc);
    exit(1);
  }
  sqlite3_close(db);
  for(i=0; i<sizeof(aThread)/sizeof(aThread[0]); i++){
    pthread_create(&aThread[i], 0, worker, (void*)i);
  }
  for(i=0; i<sizeof(aThread)/sizeof(aThread[i]); i++){
    pthread_join(aThread[i], 0);
  }
  if( !all_stop ){
    printf("Everything seems ok.\n");
    return 0;
  }else{
    printf("We hit an error.\n");
    return 1;
  }
}