xref: /sqlite-3.40.0/test/tt3_lookaside1.c (revision 053542d7)
1 /*
2 ** 2014 December 9
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 **
13 **     lookaside1
14 */
15 
16 /*
17 ** The test in this file attempts to expose a specific race condition
18 ** that is suspected to exist at time of writing.
19 */
20 
lookaside1_thread_reader(int iTid,void * pArg)21 static char *lookaside1_thread_reader(int iTid, void *pArg){
22   Error err = {0};                /* Error code and message */
23   Sqlite db = {0};                /* SQLite database connection */
24 
25   opendb(&err, &db, "test.db", 0);
26 
27   while( !timetostop(&err) ){
28     sqlite3_stmt *pStmt = 0;
29     int rc;
30 
31     sqlite3_prepare_v2(db.db, "SELECT 1 FROM t1", -1, &pStmt, 0);
32     while( sqlite3_step(pStmt)==SQLITE_ROW ){
33       execsql(&err, &db, "SELECT length(x||y||z) FROM t2");
34     }
35     rc = sqlite3_finalize(pStmt);
36     if( err.rc==SQLITE_OK && rc!=SQLITE_OK ){
37       sqlite_error(&err, &db, "finalize");
38     }
39   }
40 
41   closedb(&err, &db);
42   print_and_free_err(&err);
43   return sqlite3_mprintf("ok");
44 }
45 
lookaside1_thread_writer(int iTid,void * pArg)46 static char *lookaside1_thread_writer(int iTid, void *pArg){
47   Error err = {0};                /* Error code and message */
48   Sqlite db = {0};                /* SQLite database connection */
49 
50   opendb(&err, &db, "test.db", 0);
51 
52   do{
53     sql_script(&err, &db,
54       "BEGIN;"
55         "UPDATE t3 SET i=i+1 WHERE x=1;"
56       "ROLLBACK;"
57     );
58   }while( !timetostop(&err) );
59 
60   closedb(&err, &db);
61   print_and_free_err(&err);
62   return sqlite3_mprintf("ok");
63 }
64 
65 
lookaside1(int nMs)66 static void lookaside1(int nMs){
67   Error err = {0};
68   Sqlite db = {0};
69   Threadset threads = {0};
70 
71   opendb(&err, &db, "test.db", 1);
72   sql_script(&err, &db,
73      "CREATE TABLE t1(x PRIMARY KEY) WITHOUT ROWID;"
74      "WITH data(x,y) AS ("
75      "  SELECT 1, quote(randomblob(750)) UNION ALL "
76      "  SELECT x*2, y||y FROM data WHERE x<5) "
77      "INSERT INTO t1 SELECT y FROM data;"
78 
79      "CREATE TABLE t3(x PRIMARY KEY,i) WITHOUT ROWID;"
80      "INSERT INTO t3 VALUES(1, 1);"
81 
82      "CREATE TABLE t2(x,y,z);"
83      "INSERT INTO t2 VALUES(randomblob(50), randomblob(50), randomblob(50));"
84   );
85   closedb(&err, &db);
86 
87   setstoptime(&err, nMs);
88 
89   sqlite3_enable_shared_cache(1);
90   launch_thread(&err, &threads, lookaside1_thread_reader, 0);
91   launch_thread(&err, &threads, lookaside1_thread_reader, 0);
92   launch_thread(&err, &threads, lookaside1_thread_reader, 0);
93   launch_thread(&err, &threads, lookaside1_thread_reader, 0);
94   launch_thread(&err, &threads, lookaside1_thread_reader, 0);
95   launch_thread(&err, &threads, lookaside1_thread_writer, 0);
96   join_all_threads(&err, &threads);
97   sqlite3_enable_shared_cache(0);
98   print_and_free_err(&err);
99 }
100