Annotation of embedaddon/sqlite3/test/threadtest3.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3: ** The code in this file runs a few multi-threaded test cases using the
                      4: ** SQLite library. It can be compiled to an executable on unix using the
                      5: ** following command:
                      6: **
                      7: **   gcc -O2 threadtest3.c sqlite3.c -ldl -lpthread -lm
                      8: **
                      9: ** Then run the compiled program. The exit status is non-zero if any tests
                     10: ** failed (hopefully there is also some output to stdout to clarify what went
                     11: ** wrong).
                     12: **
                     13: ** There are three parts to the code in this file, in the following order:
                     14: **
                     15: **   1. Code for the SQL aggregate function md5sum() copied from 
                     16: **      tclsqlite.c in the SQLite distribution. The names of all the 
                     17: **      types and functions in this section begin with "MD5" or "md5".
                     18: **
                     19: **   2. A set of utility functions that may be used to implement
                     20: **      multi-threaded test cases. These are all called by test code
                     21: **      via macros that help with error reporting. The macros are defined
                     22: **      immediately below this comment.
                     23: **
                     24: **   3. The test code itself. And a main() routine to drive the test 
                     25: **      code.
                     26: */
                     27: 
                     28: /*************************************************************************
                     29: ** Start of test code/infrastructure interface macros.
                     30: **
                     31: ** The following macros constitute the interface between the test
                     32: ** programs and the test infrastructure. Test infrastructure code 
                     33: ** does not itself use any of these macros. Test code should not
                     34: ** call any of the macroname_x() functions directly.
                     35: **
                     36: ** See the header comments above the corresponding macroname_x()
                     37: ** function for a description of each interface.
                     38: */
                     39: 
                     40: /* Database functions */
                     41: #define opendb(w,x,y,z)         (SEL(w), opendb_x(w,x,y,z))
                     42: #define closedb(y,z)            (SEL(y), closedb_x(y,z))
                     43: 
                     44: /* Functions to execute SQL */
                     45: #define sql_script(x,y,z)       (SEL(x), sql_script_x(x,y,z))
                     46: #define integrity_check(x,y)    (SEL(x), integrity_check_x(x,y))
                     47: #define execsql_i64(x,y,...)    (SEL(x), execsql_i64_x(x,y,__VA_ARGS__))
                     48: #define execsql_text(x,y,z,...) (SEL(x), execsql_text_x(x,y,z,__VA_ARGS__))
                     49: #define execsql(x,y,...)        (SEL(x), (void)execsql_i64_x(x,y,__VA_ARGS__))
                     50: 
                     51: /* Thread functions */
                     52: #define launch_thread(w,x,y,z)  (SEL(w), launch_thread_x(w,x,y,z))
                     53: #define join_all_threads(y,z)   (SEL(y), join_all_threads_x(y,z))
                     54: 
                     55: /* Timer functions */
                     56: #define setstoptime(y,z)        (SEL(y), setstoptime_x(y,z))
                     57: #define timetostop(z)           (SEL(z), timetostop_x(z))
                     58: 
                     59: /* Report/clear errors. */
                     60: #define test_error(z, ...)      test_error_x(z, sqlite3_mprintf(__VA_ARGS__))
                     61: #define clear_error(y,z)        clear_error_x(y, z)
                     62: 
                     63: /* File-system operations */
                     64: #define filesize(y,z)           (SEL(y), filesize_x(y,z))
                     65: #define filecopy(x,y,z)         (SEL(x), filecopy_x(x,y,z))
                     66: 
                     67: /*
                     68: ** End of test code/infrastructure interface macros.
                     69: *************************************************************************/
                     70: 
                     71: 
                     72: 
                     73: 
                     74: #include <sqlite3.h>
                     75: #include <unistd.h>
                     76: #include <stdio.h>
                     77: #include <pthread.h>
                     78: #include <assert.h>
                     79: #include <sys/types.h> 
                     80: #include <sys/stat.h> 
                     81: #include <string.h>
                     82: #include <fcntl.h>
                     83: #include <errno.h>
                     84: 
                     85: /*
                     86:  * This code implements the MD5 message-digest algorithm.
                     87:  * The algorithm is due to Ron Rivest.  This code was
                     88:  * written by Colin Plumb in 1993, no copyright is claimed.
                     89:  * This code is in the public domain; do with it what you wish.
                     90:  *
                     91:  * Equivalent code is available from RSA Data Security, Inc.
                     92:  * This code has been tested against that, and is equivalent,
                     93:  * except that you don't need to include two pages of legalese
                     94:  * with every copy.
                     95:  *
                     96:  * To compute the message digest of a chunk of bytes, declare an
                     97:  * MD5Context structure, pass it to MD5Init, call MD5Update as
                     98:  * needed on buffers full of bytes, and then call MD5Final, which
                     99:  * will fill a supplied 16-byte array with the digest.
                    100:  */
                    101: 
                    102: /*
                    103:  * If compiled on a machine that doesn't have a 32-bit integer,
                    104:  * you just set "uint32" to the appropriate datatype for an
                    105:  * unsigned 32-bit integer.  For example:
                    106:  *
                    107:  *       cc -Duint32='unsigned long' md5.c
                    108:  *
                    109:  */
                    110: #ifndef uint32
                    111: #  define uint32 unsigned int
                    112: #endif
                    113: 
                    114: struct MD5Context {
                    115:   int isInit;
                    116:   uint32 buf[4];
                    117:   uint32 bits[2];
                    118:   unsigned char in[64];
                    119: };
                    120: typedef struct MD5Context MD5Context;
                    121: 
                    122: /*
                    123:  * Note: this code is harmless on little-endian machines.
                    124:  */
                    125: static void byteReverse (unsigned char *buf, unsigned longs){
                    126:   uint32 t;
                    127:   do {
                    128:     t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
                    129:           ((unsigned)buf[1]<<8 | buf[0]);
                    130:     *(uint32 *)buf = t;
                    131:     buf += 4;
                    132:   } while (--longs);
                    133: }
                    134: /* The four core functions - F1 is optimized somewhat */
                    135: 
                    136: /* #define F1(x, y, z) (x & y | ~x & z) */
                    137: #define F1(x, y, z) (z ^ (x & (y ^ z)))
                    138: #define F2(x, y, z) F1(z, x, y)
                    139: #define F3(x, y, z) (x ^ y ^ z)
                    140: #define F4(x, y, z) (y ^ (x | ~z))
                    141: 
                    142: /* This is the central step in the MD5 algorithm. */
                    143: #define MD5STEP(f, w, x, y, z, data, s) \
                    144:   ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
                    145: 
                    146: /*
                    147:  * The core of the MD5 algorithm, this alters an existing MD5 hash to
                    148:  * reflect the addition of 16 longwords of new data.  MD5Update blocks
                    149:  * the data and converts bytes into longwords for this routine.
                    150:  */
                    151: static void MD5Transform(uint32 buf[4], const uint32 in[16]){
                    152:   register uint32 a, b, c, d;
                    153: 
                    154:   a = buf[0];
                    155:   b = buf[1];
                    156:   c = buf[2];
                    157:   d = buf[3];
                    158: 
                    159:   MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
                    160:   MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
                    161:   MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
                    162:   MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
                    163:   MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
                    164:   MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
                    165:   MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
                    166:   MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
                    167:   MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
                    168:   MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
                    169:   MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
                    170:   MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
                    171:   MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
                    172:   MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
                    173:   MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
                    174:   MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
                    175: 
                    176:   MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
                    177:   MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
                    178:   MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
                    179:   MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
                    180:   MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
                    181:   MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
                    182:   MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
                    183:   MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
                    184:   MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
                    185:   MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
                    186:   MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
                    187:   MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
                    188:   MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
                    189:   MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
                    190:   MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
                    191:   MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
                    192: 
                    193:   MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
                    194:   MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
                    195:   MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
                    196:   MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
                    197:   MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
                    198:   MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
                    199:   MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
                    200:   MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
                    201:   MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
                    202:   MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
                    203:   MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
                    204:   MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
                    205:   MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
                    206:   MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
                    207:   MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
                    208:   MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
                    209: 
                    210:   MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
                    211:   MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
                    212:   MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
                    213:   MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
                    214:   MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
                    215:   MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
                    216:   MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
                    217:   MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
                    218:   MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
                    219:   MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
                    220:   MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
                    221:   MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
                    222:   MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
                    223:   MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
                    224:   MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
                    225:   MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
                    226: 
                    227:   buf[0] += a;
                    228:   buf[1] += b;
                    229:   buf[2] += c;
                    230:   buf[3] += d;
                    231: }
                    232: 
                    233: /*
                    234:  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
                    235:  * initialization constants.
                    236:  */
                    237: static void MD5Init(MD5Context *ctx){
                    238:   ctx->isInit = 1;
                    239:   ctx->buf[0] = 0x67452301;
                    240:   ctx->buf[1] = 0xefcdab89;
                    241:   ctx->buf[2] = 0x98badcfe;
                    242:   ctx->buf[3] = 0x10325476;
                    243:   ctx->bits[0] = 0;
                    244:   ctx->bits[1] = 0;
                    245: }
                    246: 
                    247: /*
                    248:  * Update context to reflect the concatenation of another buffer full
                    249:  * of bytes.
                    250:  */
                    251: static 
                    252: void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
                    253:   uint32 t;
                    254: 
                    255:   /* Update bitcount */
                    256: 
                    257:   t = ctx->bits[0];
                    258:   if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
                    259:     ctx->bits[1]++; /* Carry from low to high */
                    260:   ctx->bits[1] += len >> 29;
                    261: 
                    262:   t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
                    263: 
                    264:   /* Handle any leading odd-sized chunks */
                    265: 
                    266:   if ( t ) {
                    267:     unsigned char *p = (unsigned char *)ctx->in + t;
                    268: 
                    269:     t = 64-t;
                    270:     if (len < t) {
                    271:       memcpy(p, buf, len);
                    272:       return;
                    273:     }
                    274:     memcpy(p, buf, t);
                    275:     byteReverse(ctx->in, 16);
                    276:     MD5Transform(ctx->buf, (uint32 *)ctx->in);
                    277:     buf += t;
                    278:     len -= t;
                    279:   }
                    280: 
                    281:   /* Process data in 64-byte chunks */
                    282: 
                    283:   while (len >= 64) {
                    284:     memcpy(ctx->in, buf, 64);
                    285:     byteReverse(ctx->in, 16);
                    286:     MD5Transform(ctx->buf, (uint32 *)ctx->in);
                    287:     buf += 64;
                    288:     len -= 64;
                    289:   }
                    290: 
                    291:   /* Handle any remaining bytes of data. */
                    292: 
                    293:   memcpy(ctx->in, buf, len);
                    294: }
                    295: 
                    296: /*
                    297:  * Final wrapup - pad to 64-byte boundary with the bit pattern 
                    298:  * 1 0* (64-bit count of bits processed, MSB-first)
                    299:  */
                    300: static void MD5Final(unsigned char digest[16], MD5Context *ctx){
                    301:   unsigned count;
                    302:   unsigned char *p;
                    303: 
                    304:   /* Compute number of bytes mod 64 */
                    305:   count = (ctx->bits[0] >> 3) & 0x3F;
                    306: 
                    307:   /* Set the first char of padding to 0x80.  This is safe since there is
                    308:      always at least one byte free */
                    309:   p = ctx->in + count;
                    310:   *p++ = 0x80;
                    311: 
                    312:   /* Bytes of padding needed to make 64 bytes */
                    313:   count = 64 - 1 - count;
                    314: 
                    315:   /* Pad out to 56 mod 64 */
                    316:   if (count < 8) {
                    317:     /* Two lots of padding:  Pad the first block to 64 bytes */
                    318:     memset(p, 0, count);
                    319:     byteReverse(ctx->in, 16);
                    320:     MD5Transform(ctx->buf, (uint32 *)ctx->in);
                    321: 
                    322:     /* Now fill the next block with 56 bytes */
                    323:     memset(ctx->in, 0, 56);
                    324:   } else {
                    325:     /* Pad block to 56 bytes */
                    326:     memset(p, 0, count-8);
                    327:   }
                    328:   byteReverse(ctx->in, 14);
                    329: 
                    330:   /* Append length in bits and transform */
                    331:   ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
                    332:   ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
                    333: 
                    334:   MD5Transform(ctx->buf, (uint32 *)ctx->in);
                    335:   byteReverse((unsigned char *)ctx->buf, 4);
                    336:   memcpy(digest, ctx->buf, 16);
                    337:   memset(ctx, 0, sizeof(ctx));    /* In case it is sensitive */
                    338: }
                    339: 
                    340: /*
                    341: ** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
                    342: */
                    343: static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
                    344:   static char const zEncode[] = "0123456789abcdef";
                    345:   int i, j;
                    346: 
                    347:   for(j=i=0; i<16; i++){
                    348:     int a = digest[i];
                    349:     zBuf[j++] = zEncode[(a>>4)&0xf];
                    350:     zBuf[j++] = zEncode[a & 0xf];
                    351:   }
                    352:   zBuf[j] = 0;
                    353: }
                    354: 
                    355: /*
                    356: ** During testing, the special md5sum() aggregate function is available.
                    357: ** inside SQLite.  The following routines implement that function.
                    358: */
                    359: static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
                    360:   MD5Context *p;
                    361:   int i;
                    362:   if( argc<1 ) return;
                    363:   p = sqlite3_aggregate_context(context, sizeof(*p));
                    364:   if( p==0 ) return;
                    365:   if( !p->isInit ){
                    366:     MD5Init(p);
                    367:   }
                    368:   for(i=0; i<argc; i++){
                    369:     const char *zData = (char*)sqlite3_value_text(argv[i]);
                    370:     if( zData ){
                    371:       MD5Update(p, (unsigned char*)zData, strlen(zData));
                    372:     }
                    373:   }
                    374: }
                    375: static void md5finalize(sqlite3_context *context){
                    376:   MD5Context *p;
                    377:   unsigned char digest[16];
                    378:   char zBuf[33];
                    379:   p = sqlite3_aggregate_context(context, sizeof(*p));
                    380:   MD5Final(digest,p);
                    381:   MD5DigestToBase16(digest, zBuf);
                    382:   sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
                    383: }
                    384: 
                    385: /*************************************************************************
                    386: ** End of copied md5sum() code.
                    387: */
                    388: 
                    389: typedef sqlite3_int64 i64;
                    390: 
                    391: typedef struct Error Error;
                    392: typedef struct Sqlite Sqlite;
                    393: typedef struct Statement Statement;
                    394: 
                    395: typedef struct Threadset Threadset;
                    396: typedef struct Thread Thread;
                    397: 
                    398: /* Total number of errors in this process so far. */
                    399: static int nGlobalErr = 0;
                    400: 
                    401: /* Set to true to run in "process" instead of "thread" mode. */
                    402: static int bProcessMode = 0;
                    403: 
                    404: struct Error {
                    405:   int rc;
                    406:   int iLine;
                    407:   char *zErr;
                    408: };
                    409: 
                    410: struct Sqlite {
                    411:   sqlite3 *db;                    /* Database handle */
                    412:   Statement *pCache;              /* Linked list of cached statements */
                    413:   int nText;                      /* Size of array at aText[] */
                    414:   char **aText;                   /* Stored text results */
                    415: };
                    416: 
                    417: struct Statement {
                    418:   sqlite3_stmt *pStmt;            /* Pre-compiled statement handle */
                    419:   Statement *pNext;               /* Next statement in linked-list */
                    420: };
                    421: 
                    422: struct Thread {
                    423:   int iTid;                       /* Thread number within test */
                    424:   int iArg;                       /* Integer argument passed by caller */
                    425: 
                    426:   pthread_t tid;                  /* Thread id */
                    427:   char *(*xProc)(int, int);       /* Thread main proc */
                    428:   Thread *pNext;                  /* Next in this list of threads */
                    429: };
                    430: 
                    431: struct Threadset {
                    432:   int iMaxTid;                    /* Largest iTid value allocated so far */
                    433:   Thread *pThread;                /* Linked list of threads */
                    434: };
                    435: 
                    436: static void free_err(Error *p){
                    437:   sqlite3_free(p->zErr);
                    438:   p->zErr = 0;
                    439:   p->rc = 0;
                    440: }
                    441: 
                    442: static void print_err(Error *p){
                    443:   if( p->rc!=SQLITE_OK ){
                    444:     printf("Error: (%d) \"%s\" at line %d\n", p->rc, p->zErr, p->iLine);
                    445:     nGlobalErr++;
                    446:   }
                    447: }
                    448: 
                    449: static void print_and_free_err(Error *p){
                    450:   print_err(p);
                    451:   free_err(p);
                    452: }
                    453: 
                    454: static void system_error(Error *pErr, int iSys){
                    455:   pErr->rc = iSys;
                    456:   pErr->zErr = (char *)sqlite3_malloc(512);
                    457:   strerror_r(iSys, pErr->zErr, 512);
                    458:   pErr->zErr[511] = '\0';
                    459: }
                    460: 
                    461: static void sqlite_error(
                    462:   Error *pErr, 
                    463:   Sqlite *pDb, 
                    464:   const char *zFunc
                    465: ){
                    466:   pErr->rc = sqlite3_errcode(pDb->db);
                    467:   pErr->zErr = sqlite3_mprintf(
                    468:       "sqlite3_%s() - %s (%d)", zFunc, sqlite3_errmsg(pDb->db),
                    469:       sqlite3_extended_errcode(pDb->db)
                    470:   );
                    471: }
                    472: 
                    473: static void test_error_x(
                    474:   Error *pErr,
                    475:   char *zErr
                    476: ){
                    477:   if( pErr->rc==SQLITE_OK ){
                    478:     pErr->rc = 1;
                    479:     pErr->zErr = zErr;
                    480:   }else{
                    481:     sqlite3_free(zErr);
                    482:   }
                    483: }
                    484: 
                    485: static void clear_error_x(
                    486:   Error *pErr,
                    487:   int rc
                    488: ){
                    489:   if( pErr->rc==rc ){
                    490:     pErr->rc = SQLITE_OK;
                    491:     sqlite3_free(pErr->zErr);
                    492:     pErr->zErr = 0;
                    493:   }
                    494: }
                    495: 
                    496: static int busyhandler(void *pArg, int n){
                    497:   usleep(10*1000);
                    498:   return 1;
                    499: }
                    500: 
                    501: static void opendb_x(
                    502:   Error *pErr,                    /* IN/OUT: Error code */
                    503:   Sqlite *pDb,                    /* OUT: Database handle */
                    504:   const char *zFile,              /* Database file name */
                    505:   int bDelete                     /* True to delete db file before opening */
                    506: ){
                    507:   if( pErr->rc==SQLITE_OK ){
                    508:     int rc;
                    509:     if( bDelete ) unlink(zFile);
                    510:     rc = sqlite3_open(zFile, &pDb->db);
                    511:     if( rc ){
                    512:       sqlite_error(pErr, pDb, "open");
                    513:       sqlite3_close(pDb->db);
                    514:       pDb->db = 0;
                    515:     }else{
                    516:       sqlite3_create_function(
                    517:           pDb->db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize
                    518:       );
                    519:       sqlite3_busy_handler(pDb->db, busyhandler, 0);
                    520:       sqlite3_exec(pDb->db, "PRAGMA synchronous=OFF", 0, 0, 0);
                    521:     }
                    522:   }
                    523: }
                    524: 
                    525: static void closedb_x(
                    526:   Error *pErr,                    /* IN/OUT: Error code */
                    527:   Sqlite *pDb                     /* OUT: Database handle */
                    528: ){
                    529:   int rc;
                    530:   int i;
                    531:   Statement *pIter;
                    532:   Statement *pNext;
                    533:   for(pIter=pDb->pCache; pIter; pIter=pNext){
                    534:     pNext = pIter->pNext;
                    535:     sqlite3_finalize(pIter->pStmt);
                    536:     sqlite3_free(pIter);
                    537:   }
                    538:   for(i=0; i<pDb->nText; i++){
                    539:     sqlite3_free(pDb->aText[i]);
                    540:   }
                    541:   sqlite3_free(pDb->aText);
                    542:   rc = sqlite3_close(pDb->db);
                    543:   if( rc && pErr->rc==SQLITE_OK ){
                    544:     pErr->zErr = sqlite3_mprintf("%s", sqlite3_errmsg(pDb->db));
                    545:   }
                    546:   memset(pDb, 0, sizeof(Sqlite));
                    547: }
                    548: 
                    549: static void sql_script_x(
                    550:   Error *pErr,                    /* IN/OUT: Error code */
                    551:   Sqlite *pDb,                    /* Database handle */
                    552:   const char *zSql                /* SQL script to execute */
                    553: ){
                    554:   if( pErr->rc==SQLITE_OK ){
                    555:     pErr->rc = sqlite3_exec(pDb->db, zSql, 0, 0, &pErr->zErr);
                    556:   }
                    557: }
                    558: 
                    559: static Statement *getSqlStatement(
                    560:   Error *pErr,                    /* IN/OUT: Error code */
                    561:   Sqlite *pDb,                    /* Database handle */
                    562:   const char *zSql                /* SQL statement */
                    563: ){
                    564:   Statement *pRet;
                    565:   int rc;
                    566: 
                    567:   for(pRet=pDb->pCache; pRet; pRet=pRet->pNext){
                    568:     if( 0==strcmp(sqlite3_sql(pRet->pStmt), zSql) ){
                    569:       return pRet;
                    570:     }
                    571:   }
                    572: 
                    573:   pRet = sqlite3_malloc(sizeof(Statement));
                    574:   rc = sqlite3_prepare_v2(pDb->db, zSql, -1, &pRet->pStmt, 0);
                    575:   if( rc!=SQLITE_OK ){
                    576:     sqlite_error(pErr, pDb, "prepare_v2");
                    577:     return 0;
                    578:   }
                    579:   assert( 0==strcmp(sqlite3_sql(pRet->pStmt), zSql) );
                    580: 
                    581:   pRet->pNext = pDb->pCache;
                    582:   pDb->pCache = pRet;
                    583:   return pRet;
                    584: }
                    585: 
                    586: static sqlite3_stmt *getAndBindSqlStatement(
                    587:   Error *pErr,                    /* IN/OUT: Error code */
                    588:   Sqlite *pDb,                    /* Database handle */
                    589:   va_list ap                      /* SQL followed by parameters */
                    590: ){
                    591:   Statement *pStatement;          /* The SQLite statement wrapper */
                    592:   sqlite3_stmt *pStmt;            /* The SQLite statement to return */
                    593:   int i;                          /* Used to iterate through parameters */
                    594: 
                    595:   pStatement = getSqlStatement(pErr, pDb, va_arg(ap, const char *));
                    596:   if( !pStatement ) return 0;
                    597:   pStmt = pStatement->pStmt;
                    598:   for(i=1; i<=sqlite3_bind_parameter_count(pStmt); i++){
                    599:     const char *zName = sqlite3_bind_parameter_name(pStmt, i);
                    600:     void * pArg = va_arg(ap, void*);
                    601: 
                    602:     switch( zName[1] ){
                    603:       case 'i':
                    604:         sqlite3_bind_int64(pStmt, i, *(i64 *)pArg);
                    605:         break;
                    606: 
                    607:       default:
                    608:         pErr->rc = 1;
                    609:         pErr->zErr = sqlite3_mprintf("Cannot discern type: \"%s\"", zName);
                    610:         pStmt = 0;
                    611:         break;
                    612:     }
                    613:   }
                    614: 
                    615:   return pStmt;
                    616: }
                    617: 
                    618: static i64 execsql_i64_x(
                    619:   Error *pErr,                    /* IN/OUT: Error code */
                    620:   Sqlite *pDb,                    /* Database handle */
                    621:   ...                             /* SQL and pointers to parameter values */
                    622: ){
                    623:   i64 iRet = 0;
                    624:   if( pErr->rc==SQLITE_OK ){
                    625:     sqlite3_stmt *pStmt;          /* SQL statement to execute */
                    626:     va_list ap;                   /* ... arguments */
                    627:     int i;                        /* Used to iterate through parameters */
                    628:     va_start(ap, pDb);
                    629:     pStmt = getAndBindSqlStatement(pErr, pDb, ap);
                    630:     if( pStmt ){
                    631:       int rc;
                    632:       int first = 1;
                    633:       while( SQLITE_ROW==sqlite3_step(pStmt) ){
                    634:         if( first && sqlite3_column_count(pStmt)>0 ){
                    635:           iRet = sqlite3_column_int64(pStmt, 0);
                    636:         }
                    637:         first = 0;
                    638:       }
                    639:       if( SQLITE_OK!=sqlite3_reset(pStmt) ){
                    640:         sqlite_error(pErr, pDb, "reset");
                    641:       }
                    642:     }
                    643:     va_end(ap);
                    644:   }
                    645:   return iRet;
                    646: }
                    647: 
                    648: static char * execsql_text_x(
                    649:   Error *pErr,                    /* IN/OUT: Error code */
                    650:   Sqlite *pDb,                    /* Database handle */
                    651:   int iSlot,                      /* Db handle slot to store text in */
                    652:   ...                             /* SQL and pointers to parameter values */
                    653: ){
                    654:   char *zRet = 0;
                    655: 
                    656:   if( iSlot>=pDb->nText ){
                    657:     int nByte = sizeof(char *)*(iSlot+1);
                    658:     pDb->aText = (char **)sqlite3_realloc(pDb->aText, nByte);
                    659:     memset(&pDb->aText[pDb->nText], 0, sizeof(char*)*(iSlot+1-pDb->nText));
                    660:     pDb->nText = iSlot+1;
                    661:   }
                    662: 
                    663:   if( pErr->rc==SQLITE_OK ){
                    664:     sqlite3_stmt *pStmt;          /* SQL statement to execute */
                    665:     va_list ap;                   /* ... arguments */
                    666:     int i;                        /* Used to iterate through parameters */
                    667:     va_start(ap, iSlot);
                    668:     pStmt = getAndBindSqlStatement(pErr, pDb, ap);
                    669:     if( pStmt ){
                    670:       int rc;
                    671:       int first = 1;
                    672:       while( SQLITE_ROW==sqlite3_step(pStmt) ){
                    673:         if( first && sqlite3_column_count(pStmt)>0 ){
                    674:           zRet = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
                    675:           sqlite3_free(pDb->aText[iSlot]);
                    676:           pDb->aText[iSlot] = zRet;
                    677:         }
                    678:         first = 0;
                    679:       }
                    680:       if( SQLITE_OK!=sqlite3_reset(pStmt) ){
                    681:         sqlite_error(pErr, pDb, "reset");
                    682:       }
                    683:     }
                    684:     va_end(ap);
                    685:   }
                    686: 
                    687:   return zRet;
                    688: }
                    689: 
                    690: static void integrity_check_x(
                    691:   Error *pErr,                    /* IN/OUT: Error code */
                    692:   Sqlite *pDb                     /* Database handle */
                    693: ){
                    694:   if( pErr->rc==SQLITE_OK ){
                    695:     Statement *pStatement;        /* Statement to execute */
                    696:     int rc;                       /* Return code */
                    697:     char *zErr = 0;               /* Integrity check error */
                    698: 
                    699:     pStatement = getSqlStatement(pErr, pDb, "PRAGMA integrity_check");
                    700:     if( pStatement ){
                    701:       sqlite3_stmt *pStmt = pStatement->pStmt;
                    702:       while( SQLITE_ROW==sqlite3_step(pStmt) ){
                    703:         const char *z = sqlite3_column_text(pStmt, 0);
                    704:         if( strcmp(z, "ok") ){
                    705:           if( zErr==0 ){
                    706:             zErr = sqlite3_mprintf("%s", z);
                    707:           }else{
                    708:             zErr = sqlite3_mprintf("%z\n%s", zErr, z);
                    709:           }
                    710:         }
                    711:       }
                    712:       sqlite3_reset(pStmt);
                    713: 
                    714:       if( zErr ){
                    715:         pErr->zErr = zErr;
                    716:         pErr->rc = 1;
                    717:       }
                    718:     }
                    719:   }
                    720: }
                    721: 
                    722: static void *launch_thread_main(void *pArg){
                    723:   Thread *p = (Thread *)pArg;
                    724:   return (void *)p->xProc(p->iTid, p->iArg);
                    725: }
                    726: 
                    727: static void launch_thread_x(
                    728:   Error *pErr,                    /* IN/OUT: Error code */
                    729:   Threadset *pThreads,            /* Thread set */
                    730:   char *(*xProc)(int, int),       /* Proc to run */
                    731:   int iArg                        /* Argument passed to thread proc */
                    732: ){
                    733:   if( pErr->rc==SQLITE_OK ){
                    734:     int iTid = ++pThreads->iMaxTid;
                    735:     Thread *p;
                    736:     int rc;
                    737: 
                    738:     p = (Thread *)sqlite3_malloc(sizeof(Thread));
                    739:     memset(p, 0, sizeof(Thread));
                    740:     p->iTid = iTid;
                    741:     p->iArg = iArg;
                    742:     p->xProc = xProc;
                    743: 
                    744:     rc = pthread_create(&p->tid, NULL, launch_thread_main, (void *)p);
                    745:     if( rc!=0 ){
                    746:       system_error(pErr, rc);
                    747:       sqlite3_free(p);
                    748:     }else{
                    749:       p->pNext = pThreads->pThread;
                    750:       pThreads->pThread = p;
                    751:     }
                    752:   }
                    753: }
                    754: 
                    755: static void join_all_threads_x(
                    756:   Error *pErr,                    /* IN/OUT: Error code */
                    757:   Threadset *pThreads             /* Thread set */
                    758: ){
                    759:   Thread *p;
                    760:   Thread *pNext;
                    761:   for(p=pThreads->pThread; p; p=pNext){
                    762:     void *ret;
                    763:     pNext = p->pNext;
                    764:     int rc;
                    765:     rc = pthread_join(p->tid, &ret);
                    766:     if( rc!=0 ){
                    767:       if( pErr->rc==SQLITE_OK ) system_error(pErr, rc);
                    768:     }else{
                    769:       printf("Thread %d says: %s\n", p->iTid, (ret==0 ? "..." : (char *)ret));
                    770:     }
                    771:     sqlite3_free(p);
                    772:   }
                    773:   pThreads->pThread = 0;
                    774: }
                    775: 
                    776: static i64 filesize_x(
                    777:   Error *pErr,
                    778:   const char *zFile
                    779: ){
                    780:   i64 iRet = 0;
                    781:   if( pErr->rc==SQLITE_OK ){
                    782:     struct stat sStat;
                    783:     if( stat(zFile, &sStat) ){
                    784:       iRet = -1;
                    785:     }else{
                    786:       iRet = sStat.st_size;
                    787:     }
                    788:   }
                    789:   return iRet;
                    790: }
                    791: 
                    792: static void filecopy_x(
                    793:   Error *pErr,
                    794:   const char *zFrom,
                    795:   const char *zTo
                    796: ){
                    797:   if( pErr->rc==SQLITE_OK ){
                    798:     i64 nByte = filesize_x(pErr, zFrom);
                    799:     if( nByte<0 ){
                    800:       test_error_x(pErr, sqlite3_mprintf("no such file: %s", zFrom));
                    801:     }else{
                    802:       i64 iOff;
                    803:       char aBuf[1024];
                    804:       int fd1;
                    805:       int fd2;
                    806:       unlink(zTo);
                    807: 
                    808:       fd1 = open(zFrom, O_RDONLY);
                    809:       if( fd1<0 ){
                    810:         system_error(pErr, errno);
                    811:         return;
                    812:       }
                    813:       fd2 = open(zTo, O_RDWR|O_CREAT|O_EXCL, 0644);
                    814:       if( fd2<0 ){
                    815:         system_error(pErr, errno);
                    816:         close(fd1);
                    817:         return;
                    818:       }
                    819: 
                    820:       iOff = 0;
                    821:       while( iOff<nByte ){
                    822:         int nCopy = sizeof(aBuf);
                    823:         if( nCopy+iOff>nByte ){
                    824:           nCopy = nByte - iOff;
                    825:         }
                    826:         if( nCopy!=read(fd1, aBuf, nCopy) ){
                    827:           system_error(pErr, errno);
                    828:           break;
                    829:         }
                    830:         if( nCopy!=write(fd2, aBuf, nCopy) ){
                    831:           system_error(pErr, errno);
                    832:           break;
                    833:         }
                    834:         iOff += nCopy;
                    835:       }
                    836: 
                    837:       close(fd1);
                    838:       close(fd2);
                    839:     }
                    840:   }
                    841: }
                    842: 
                    843: /* 
                    844: ** Used by setstoptime() and timetostop().
                    845: */
                    846: static double timelimit = 0.0;
                    847: static sqlite3_vfs *pTimelimitVfs = 0;
                    848: 
                    849: static void setstoptime_x(
                    850:   Error *pErr,                    /* IN/OUT: Error code */
                    851:   int nMs                         /* Milliseconds until "stop time" */
                    852: ){
                    853:   if( pErr->rc==SQLITE_OK ){
                    854:     double t;
                    855:     int rc;
                    856:     pTimelimitVfs = sqlite3_vfs_find(0);
                    857:     rc = pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t);
                    858:     if( rc!=SQLITE_OK ){
                    859:       pErr->rc = rc;
                    860:     }else{
                    861:       timelimit = t + ((double)nMs)/(1000.0*60.0*60.0*24.0);
                    862:     }
                    863:   }
                    864: }
                    865: 
                    866: static int timetostop_x(
                    867:   Error *pErr                     /* IN/OUT: Error code */
                    868: ){
                    869:   int ret = 1;
                    870:   if( pErr->rc==SQLITE_OK ){
                    871:     double t;
                    872:     int rc;
                    873:     rc = pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t);
                    874:     if( rc!=SQLITE_OK ){
                    875:       pErr->rc = rc;
                    876:     }else{
                    877:       ret = (t >= timelimit);
                    878:     }
                    879:   }
                    880:   return ret;
                    881: }
                    882: 
                    883: /* 
                    884: ** The "Set Error Line" macro.
                    885: */
                    886: #define SEL(e) ((e)->iLine = ((e)->rc ? (e)->iLine : __LINE__))
                    887: 
                    888: 
                    889: /*************************************************************************
                    890: **************************************************************************
                    891: **************************************************************************
                    892: ** End infrastructure. Begin tests.
                    893: */
                    894: 
                    895: #define WALTHREAD1_NTHREAD  10
                    896: #define WALTHREAD3_NTHREAD  6
                    897: 
                    898: static char *walthread1_thread(int iTid, int iArg){
                    899:   Error err = {0};                /* Error code and message */
                    900:   Sqlite db = {0};                /* SQLite database connection */
                    901:   int nIter = 0;                  /* Iterations so far */
                    902: 
                    903:   opendb(&err, &db, "test.db", 0);
                    904:   while( !timetostop(&err) ){
                    905:     const char *azSql[] = {
                    906:       "SELECT md5sum(x) FROM t1 WHERE rowid != (SELECT max(rowid) FROM t1)",
                    907:       "SELECT x FROM t1 WHERE rowid = (SELECT max(rowid) FROM t1)",
                    908:     };
                    909:     char *z1, *z2, *z3;
                    910: 
                    911:     execsql(&err, &db, "BEGIN");
                    912:     integrity_check(&err, &db);
                    913:     z1 = execsql_text(&err, &db, 1, azSql[0]);
                    914:     z2 = execsql_text(&err, &db, 2, azSql[1]);
                    915:     z3 = execsql_text(&err, &db, 3, azSql[0]);
                    916:     execsql(&err, &db, "COMMIT");
                    917: 
                    918:     if( strcmp(z1, z2) || strcmp(z1, z3) ){
                    919:       test_error(&err, "Failed read: %s %s %s", z1, z2, z3);
                    920:     }
                    921: 
                    922:     sql_script(&err, &db,
                    923:         "BEGIN;"
                    924:           "INSERT INTO t1 VALUES(randomblob(100));"
                    925:           "INSERT INTO t1 VALUES(randomblob(100));"
                    926:           "INSERT INTO t1 SELECT md5sum(x) FROM t1;"
                    927:         "COMMIT;"
                    928:     );
                    929:     nIter++;
                    930:   }
                    931:   closedb(&err, &db);
                    932: 
                    933:   print_and_free_err(&err);
                    934:   return sqlite3_mprintf("%d iterations", nIter);
                    935: }
                    936: 
                    937: static char *walthread1_ckpt_thread(int iTid, int iArg){
                    938:   Error err = {0};                /* Error code and message */
                    939:   Sqlite db = {0};                /* SQLite database connection */
                    940:   int nCkpt = 0;                  /* Checkpoints so far */
                    941: 
                    942:   opendb(&err, &db, "test.db", 0);
                    943:   while( !timetostop(&err) ){
                    944:     usleep(500*1000);
                    945:     execsql(&err, &db, "PRAGMA wal_checkpoint");
                    946:     if( err.rc==SQLITE_OK ) nCkpt++;
                    947:     clear_error(&err, SQLITE_BUSY);
                    948:   }
                    949:   closedb(&err, &db);
                    950: 
                    951:   print_and_free_err(&err);
                    952:   return sqlite3_mprintf("%d checkpoints", nCkpt);
                    953: }
                    954: 
                    955: static void walthread1(int nMs){
                    956:   Error err = {0};                /* Error code and message */
                    957:   Sqlite db = {0};                /* SQLite database connection */
                    958:   Threadset threads = {0};        /* Test threads */
                    959:   int i;                          /* Iterator variable */
                    960: 
                    961:   opendb(&err, &db, "test.db", 1);
                    962:   sql_script(&err, &db,
                    963:       "PRAGMA journal_mode = WAL;"
                    964:       "CREATE TABLE t1(x PRIMARY KEY);"
                    965:       "INSERT INTO t1 VALUES(randomblob(100));"
                    966:       "INSERT INTO t1 VALUES(randomblob(100));"
                    967:       "INSERT INTO t1 SELECT md5sum(x) FROM t1;"
                    968:   );
                    969: 
                    970:   setstoptime(&err, nMs);
                    971:   for(i=0; i<WALTHREAD1_NTHREAD; i++){
                    972:     launch_thread(&err, &threads, walthread1_thread, 0);
                    973:   }
                    974:   launch_thread(&err, &threads, walthread1_ckpt_thread, 0);
                    975:   join_all_threads(&err, &threads);
                    976: 
                    977:   print_and_free_err(&err);
                    978: }
                    979: 
                    980: static char *walthread2_thread(int iTid, int iArg){
                    981:   Error err = {0};                /* Error code and message */
                    982:   Sqlite db = {0};                /* SQLite database connection */
                    983:   int anTrans[2] = {0, 0};        /* Number of WAL and Rollback transactions */
                    984: 
                    985:   const char *zJournal = "PRAGMA journal_mode = WAL";
                    986:   if( iArg ){ zJournal = "PRAGMA journal_mode = DELETE"; }
                    987: 
                    988:   while( !timetostop(&err) ){
                    989:     int journal_exists = 0;
                    990:     int wal_exists = 0;
                    991: 
                    992:     opendb(&err, &db, "test.db", 0);
                    993: 
                    994:     sql_script(&err, &db, zJournal);
                    995:     clear_error(&err, SQLITE_BUSY);
                    996:     sql_script(&err, &db, "BEGIN");
                    997:     sql_script(&err, &db, "INSERT INTO t1 VALUES(NULL, randomblob(100))");
                    998: 
                    999:     journal_exists = (filesize(&err, "test.db-journal") >= 0);
                   1000:     wal_exists = (filesize(&err, "test.db-wal") >= 0);
                   1001:     if( (journal_exists+wal_exists)!=1 ){
                   1002:       test_error(&err, "File system looks incorrect (%d, %d)", 
                   1003:           journal_exists, wal_exists
                   1004:       );
                   1005:     }
                   1006:     anTrans[journal_exists]++;
                   1007: 
                   1008:     sql_script(&err, &db, "COMMIT");
                   1009:     integrity_check(&err, &db);
                   1010:     closedb(&err, &db);
                   1011:   }
                   1012: 
                   1013:   print_and_free_err(&err);
                   1014:   return sqlite3_mprintf("W %d R %d", anTrans[0], anTrans[1]);
                   1015: }
                   1016: 
                   1017: static void walthread2(int nMs){
                   1018:   Error err = {0};
                   1019:   Sqlite db = {0};
                   1020:   Threadset threads = {0};
                   1021: 
                   1022:   opendb(&err, &db, "test.db", 1);
                   1023:   sql_script(&err, &db, "CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE)");
                   1024:   closedb(&err, &db);
                   1025: 
                   1026:   setstoptime(&err, nMs);
                   1027:   launch_thread(&err, &threads, walthread2_thread, 0);
                   1028:   launch_thread(&err, &threads, walthread2_thread, 0);
                   1029:   launch_thread(&err, &threads, walthread2_thread, 1);
                   1030:   launch_thread(&err, &threads, walthread2_thread, 1);
                   1031:   join_all_threads(&err, &threads);
                   1032: 
                   1033:   print_and_free_err(&err);
                   1034: }
                   1035: 
                   1036: static char *walthread3_thread(int iTid, int iArg){
                   1037:   Error err = {0};                /* Error code and message */
                   1038:   Sqlite db = {0};                /* SQLite database connection */
                   1039:   i64 iNextWrite;                 /* Next value this thread will write */
                   1040: 
                   1041:   opendb(&err, &db, "test.db", 0);
                   1042:   sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 10");
                   1043: 
                   1044:   iNextWrite = iArg+1;
                   1045:   while( 1 ){
                   1046:     i64 sum1;
                   1047:     i64 sum2;
                   1048:     int stop = 0;                 /* True to stop executing (test timed out) */
                   1049: 
                   1050:     while( 0==(stop = timetostop(&err)) ){
                   1051:       i64 iMax = execsql_i64(&err, &db, "SELECT max(cnt) FROM t1");
                   1052:       if( iMax+1==iNextWrite ) break;
                   1053:     }
                   1054:     if( stop ) break;
                   1055: 
                   1056:     sum1 = execsql_i64(&err, &db, "SELECT sum(cnt) FROM t1");
                   1057:     sum2 = execsql_i64(&err, &db, "SELECT sum(sum1) FROM t1");
                   1058:     execsql_i64(&err, &db, 
                   1059:         "INSERT INTO t1 VALUES(:iNextWrite, :iSum1, :iSum2)",
                   1060:         &iNextWrite, &sum1, &sum2
                   1061:     );
                   1062:     integrity_check(&err, &db);
                   1063: 
                   1064:     iNextWrite += WALTHREAD3_NTHREAD;
                   1065:   }
                   1066: 
                   1067:   closedb(&err, &db);
                   1068:   print_and_free_err(&err);
                   1069:   return 0;
                   1070: }
                   1071: 
                   1072: static void walthread3(int nMs){
                   1073:   Error err = {0};
                   1074:   Sqlite db = {0};
                   1075:   Threadset threads = {0};
                   1076:   int i;
                   1077: 
                   1078:   opendb(&err, &db, "test.db", 1);
                   1079:   sql_script(&err, &db, 
                   1080:       "PRAGMA journal_mode = WAL;"
                   1081:       "CREATE TABLE t1(cnt PRIMARY KEY, sum1, sum2);"
                   1082:       "CREATE INDEX i1 ON t1(sum1);"
                   1083:       "CREATE INDEX i2 ON t1(sum2);"
                   1084:       "INSERT INTO t1 VALUES(0, 0, 0);"
                   1085:   );
                   1086:   closedb(&err, &db);
                   1087: 
                   1088:   setstoptime(&err, nMs);
                   1089:   for(i=0; i<WALTHREAD3_NTHREAD; i++){
                   1090:     launch_thread(&err, &threads, walthread3_thread, i);
                   1091:   }
                   1092:   join_all_threads(&err, &threads);
                   1093: 
                   1094:   print_and_free_err(&err);
                   1095: }
                   1096: 
                   1097: static char *walthread4_reader_thread(int iTid, int iArg){
                   1098:   Error err = {0};                /* Error code and message */
                   1099:   Sqlite db = {0};                /* SQLite database connection */
                   1100: 
                   1101:   opendb(&err, &db, "test.db", 0);
                   1102:   while( !timetostop(&err) ){
                   1103:     integrity_check(&err, &db);
                   1104:   }
                   1105:   closedb(&err, &db);
                   1106: 
                   1107:   print_and_free_err(&err);
                   1108:   return 0;
                   1109: }
                   1110: 
                   1111: static char *walthread4_writer_thread(int iTid, int iArg){
                   1112:   Error err = {0};                /* Error code and message */
                   1113:   Sqlite db = {0};                /* SQLite database connection */
                   1114:   i64 iRow = 1;
                   1115: 
                   1116:   opendb(&err, &db, "test.db", 0);
                   1117:   sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 15;");
                   1118:   while( !timetostop(&err) ){
                   1119:     execsql_i64(
                   1120:         &err, &db, "REPLACE INTO t1 VALUES(:iRow, randomblob(300))", &iRow
                   1121:     );
                   1122:     iRow++;
                   1123:     if( iRow==10 ) iRow = 0;
                   1124:   }
                   1125:   closedb(&err, &db);
                   1126: 
                   1127:   print_and_free_err(&err);
                   1128:   return 0;
                   1129: }
                   1130: 
                   1131: static void walthread4(int nMs){
                   1132:   Error err = {0};
                   1133:   Sqlite db = {0};
                   1134:   Threadset threads = {0};
                   1135: 
                   1136:   opendb(&err, &db, "test.db", 1);
                   1137:   sql_script(&err, &db, 
                   1138:       "PRAGMA journal_mode = WAL;"
                   1139:       "CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);"
                   1140:   );
                   1141:   closedb(&err, &db);
                   1142: 
                   1143:   setstoptime(&err, nMs);
                   1144:   launch_thread(&err, &threads, walthread4_reader_thread, 0);
                   1145:   launch_thread(&err, &threads, walthread4_writer_thread, 0);
                   1146:   join_all_threads(&err, &threads);
                   1147: 
                   1148:   print_and_free_err(&err);
                   1149: }
                   1150: 
                   1151: static char *walthread5_thread(int iTid, int iArg){
                   1152:   Error err = {0};                /* Error code and message */
                   1153:   Sqlite db = {0};                /* SQLite database connection */
                   1154:   i64 nRow;
                   1155: 
                   1156:   opendb(&err, &db, "test.db", 0);
                   1157:   nRow = execsql_i64(&err, &db, "SELECT count(*) FROM t1");
                   1158:   closedb(&err, &db);
                   1159: 
                   1160:   if( nRow!=65536 ) test_error(&err, "Bad row count: %d", (int)nRow);
                   1161:   print_and_free_err(&err);
                   1162:   return 0;
                   1163: }
                   1164: static void walthread5(int nMs){
                   1165:   Error err = {0};
                   1166:   Sqlite db = {0};
                   1167:   Threadset threads = {0};
                   1168: 
                   1169:   opendb(&err, &db, "test.db", 1);
                   1170:   sql_script(&err, &db, 
                   1171:       "PRAGMA wal_autocheckpoint = 0;"
                   1172:       "PRAGMA page_size = 1024;"
                   1173:       "PRAGMA journal_mode = WAL;"
                   1174:       "CREATE TABLE t1(x);"
                   1175:       "BEGIN;"
                   1176:       "INSERT INTO t1 VALUES(randomblob(900));"
                   1177:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*     2 */"
                   1178:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*     4 */"
                   1179:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*     8 */"
                   1180:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*    16 */"
                   1181:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*    32 */"
                   1182:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*    64 */"
                   1183:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*   128 */"
                   1184:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*   256 */"
                   1185:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*   512 */"
                   1186:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  1024 */"
                   1187:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  2048 */"
                   1188:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  4096 */"
                   1189:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /*  8192 */"
                   1190:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /* 16384 */"
                   1191:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /* 32768 */"
                   1192:       "INSERT INTO t1 SELECT randomblob(900) FROM t1;      /* 65536 */"
                   1193:       "COMMIT;"
                   1194:   );
                   1195:   filecopy(&err, "test.db", "test_sv.db");
                   1196:   filecopy(&err, "test.db-wal", "test_sv.db-wal");
                   1197:   closedb(&err, &db);
                   1198: 
                   1199:   filecopy(&err, "test_sv.db", "test.db");
                   1200:   filecopy(&err, "test_sv.db-wal", "test.db-wal");
                   1201: 
                   1202:   if( err.rc==SQLITE_OK ){
                   1203:     printf("  WAL file is %d bytes,", (int)filesize(&err,"test.db-wal"));
                   1204:     printf(" DB file is %d.\n", (int)filesize(&err,"test.db"));
                   1205:   }
                   1206: 
                   1207:   setstoptime(&err, nMs);
                   1208:   launch_thread(&err, &threads, walthread5_thread, 0);
                   1209:   launch_thread(&err, &threads, walthread5_thread, 0);
                   1210:   launch_thread(&err, &threads, walthread5_thread, 0);
                   1211:   launch_thread(&err, &threads, walthread5_thread, 0);
                   1212:   launch_thread(&err, &threads, walthread5_thread, 0);
                   1213:   join_all_threads(&err, &threads);
                   1214: 
                   1215:   if( err.rc==SQLITE_OK ){
                   1216:     printf("  WAL file is %d bytes,", (int)filesize(&err,"test.db-wal"));
                   1217:     printf(" DB file is %d.\n", (int)filesize(&err,"test.db"));
                   1218:   }
                   1219: 
                   1220:   print_and_free_err(&err);
                   1221: }
                   1222: 
                   1223: /*------------------------------------------------------------------------
                   1224: ** Test case "cgt_pager_1"
                   1225: */
                   1226: #define CALLGRINDTEST1_NROW 10000
                   1227: static void cgt_pager_1_populate(Error *pErr, Sqlite *pDb){
                   1228:   const char *zInsert = "INSERT INTO t1 VALUES(:iRow, zeroblob(:iBlob))";
                   1229:   i64 iRow;
                   1230:   sql_script(pErr, pDb, "BEGIN");
                   1231:   for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
                   1232:     i64 iBlob = 600 + (iRow%300);
                   1233:     execsql(pErr, pDb, zInsert, &iRow, &iBlob);
                   1234:   }
                   1235:   sql_script(pErr, pDb, "COMMIT");
                   1236: }
                   1237: static void cgt_pager_1_update(Error *pErr, Sqlite *pDb){
                   1238:   const char *zUpdate = "UPDATE t1 SET b = zeroblob(:iBlob) WHERE a = :iRow";
                   1239:   i64 iRow;
                   1240:   sql_script(pErr, pDb, "BEGIN");
                   1241:   for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
                   1242:     i64 iBlob = 600 + ((iRow+100)%300);
                   1243:     execsql(pErr, pDb, zUpdate, &iBlob, &iRow);
                   1244:   }
                   1245:   sql_script(pErr, pDb, "COMMIT");
                   1246: }
                   1247: static void cgt_pager_1_read(Error *pErr, Sqlite *pDb){
                   1248:   i64 iRow;
                   1249:   sql_script(pErr, pDb, "BEGIN");
                   1250:   for(iRow=1; iRow<=CALLGRINDTEST1_NROW; iRow++){
                   1251:     execsql(pErr, pDb, "SELECT * FROM t1 WHERE a = :iRow", &iRow);
                   1252:   }
                   1253:   sql_script(pErr, pDb, "COMMIT");
                   1254: }
                   1255: static void cgt_pager_1(int nMs){
                   1256:   void (*xSub)(Error *, Sqlite *);
                   1257:   Error err = {0};
                   1258:   Sqlite db = {0};
                   1259: 
                   1260:   opendb(&err, &db, "test.db", 1);
                   1261:   sql_script(&err, &db,
                   1262:       "PRAGMA cache_size = 2000;"
                   1263:       "PRAGMA page_size = 1024;"
                   1264:       "CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);"
                   1265:   );
                   1266: 
                   1267:   xSub = cgt_pager_1_populate; xSub(&err, &db);
                   1268:   xSub = cgt_pager_1_update;   xSub(&err, &db);
                   1269:   xSub = cgt_pager_1_read;     xSub(&err, &db);
                   1270: 
                   1271:   closedb(&err, &db);
                   1272:   print_and_free_err(&err);
                   1273: }
                   1274: 
                   1275: /*------------------------------------------------------------------------
                   1276: ** Test case "dynamic_triggers"
                   1277: **
                   1278: **   Two threads executing statements that cause deeply nested triggers
                   1279: **   to fire. And one thread busily creating and deleting triggers. This
                   1280: **   is an attempt to find a bug reported to us.
                   1281: */
                   1282: 
                   1283: static char *dynamic_triggers_1(int iTid, int iArg){
                   1284:   Error err = {0};                /* Error code and message */
                   1285:   Sqlite db = {0};                /* SQLite database connection */
                   1286:   int nDrop = 0;
                   1287:   int nCreate = 0;
                   1288: 
                   1289:   opendb(&err, &db, "test.db", 0);
                   1290:   while( !timetostop(&err) ){
                   1291:     int i;
                   1292: 
                   1293:     for(i=1; i<9; i++){
                   1294:       char *zSql = sqlite3_mprintf(
                   1295:         "CREATE TRIGGER itr%d BEFORE INSERT ON t%d BEGIN "
                   1296:           "INSERT INTO t%d VALUES(new.x, new.y);"
                   1297:         "END;", i, i, i+1
                   1298:       );
                   1299:       execsql(&err, &db, zSql);
                   1300:       sqlite3_free(zSql);
                   1301:       nCreate++;
                   1302:     }
                   1303: 
                   1304:     for(i=1; i<9; i++){
                   1305:       char *zSql = sqlite3_mprintf(
                   1306:         "CREATE TRIGGER dtr%d BEFORE DELETE ON t%d BEGIN "
                   1307:           "DELETE FROM t%d WHERE x = old.x; "
                   1308:         "END;", i, i, i+1
                   1309:       );
                   1310:       execsql(&err, &db, zSql);
                   1311:       sqlite3_free(zSql);
                   1312:       nCreate++;
                   1313:     }
                   1314: 
                   1315:     for(i=1; i<9; i++){
                   1316:       char *zSql = sqlite3_mprintf("DROP TRIGGER itr%d", i);
                   1317:       execsql(&err, &db, zSql);
                   1318:       sqlite3_free(zSql);
                   1319:       nDrop++;
                   1320:     }
                   1321: 
                   1322:     for(i=1; i<9; i++){
                   1323:       char *zSql = sqlite3_mprintf("DROP TRIGGER dtr%d", i);
                   1324:       execsql(&err, &db, zSql);
                   1325:       sqlite3_free(zSql);
                   1326:       nDrop++;
                   1327:     }
                   1328:   }
                   1329: 
                   1330:   print_and_free_err(&err);
                   1331:   return sqlite3_mprintf("%d created, %d dropped", nCreate, nDrop);
                   1332: }
                   1333: 
                   1334: static char *dynamic_triggers_2(int iTid, int iArg){
                   1335:   Error err = {0};                /* Error code and message */
                   1336:   Sqlite db = {0};                /* SQLite database connection */
                   1337:   i64 iVal = 0;
                   1338:   int nInsert = 0;
                   1339:   int nDelete = 0;
                   1340: 
                   1341:   opendb(&err, &db, "test.db", 0);
                   1342:   while( !timetostop(&err) ){
                   1343:     do {
                   1344:       iVal = (iVal+1)%100;
                   1345:       execsql(&err, &db, "INSERT INTO t1 VALUES(:iX, :iY+1)", &iVal, &iVal);
                   1346:       nInsert++;
                   1347:     } while( iVal );
                   1348: 
                   1349:     do {
                   1350:       iVal = (iVal+1)%100;
                   1351:       execsql(&err, &db, "DELETE FROM t1 WHERE x = :iX", &iVal);
                   1352:       nDelete++;
                   1353:     } while( iVal );
                   1354:   }
                   1355: 
                   1356:   print_and_free_err(&err);
                   1357:   return sqlite3_mprintf("%d inserts, %d deletes", nInsert, nDelete);
                   1358: }
                   1359: 
                   1360: static void dynamic_triggers(int nMs){
                   1361:   Error err = {0};
                   1362:   Sqlite db = {0};
                   1363:   Threadset threads = {0};
                   1364: 
                   1365:   opendb(&err, &db, "test.db", 1);
                   1366:   sql_script(&err, &db, 
                   1367:       "PRAGMA page_size = 1024;"
                   1368:       "PRAGMA journal_mode = WAL;"
                   1369:       "CREATE TABLE t1(x, y);"
                   1370:       "CREATE TABLE t2(x, y);"
                   1371:       "CREATE TABLE t3(x, y);"
                   1372:       "CREATE TABLE t4(x, y);"
                   1373:       "CREATE TABLE t5(x, y);"
                   1374:       "CREATE TABLE t6(x, y);"
                   1375:       "CREATE TABLE t7(x, y);"
                   1376:       "CREATE TABLE t8(x, y);"
                   1377:       "CREATE TABLE t9(x, y);"
                   1378:   );
                   1379: 
                   1380:   setstoptime(&err, nMs);
                   1381: 
                   1382:   sqlite3_enable_shared_cache(1);
                   1383:   launch_thread(&err, &threads, dynamic_triggers_2, 0);
                   1384:   launch_thread(&err, &threads, dynamic_triggers_2, 0);
                   1385:   sqlite3_enable_shared_cache(0);
                   1386: 
                   1387:   sleep(2);
                   1388: 
                   1389:   launch_thread(&err, &threads, dynamic_triggers_2, 0);
                   1390:   launch_thread(&err, &threads, dynamic_triggers_1, 0);
                   1391: 
                   1392:   join_all_threads(&err, &threads);
                   1393: 
                   1394:   print_and_free_err(&err);
                   1395: }
                   1396: 
                   1397: #include "tt3_checkpoint.c"
                   1398: 
                   1399: int main(int argc, char **argv){
                   1400:   struct ThreadTest {
                   1401:     void (*xTest)(int);
                   1402:     const char *zTest;
                   1403:     int nMs;
                   1404:   } aTest[] = {
                   1405:     { walthread1, "walthread1", 20000 },
                   1406:     { walthread2, "walthread2", 20000 },
                   1407:     { walthread3, "walthread3", 20000 },
                   1408:     { walthread4, "walthread4", 20000 },
                   1409:     { walthread5, "walthread5",  1000 },
                   1410:     { walthread5, "walthread5",  1000 },
                   1411:     
                   1412:     { cgt_pager_1,      "cgt_pager_1", 0 },
                   1413:     { dynamic_triggers, "dynamic_triggers", 20000 },
                   1414: 
                   1415:     { checkpoint_starvation_1, "checkpoint_starvation_1", 10000 },
                   1416:     { checkpoint_starvation_2, "checkpoint_starvation_2", 10000 },
                   1417:   };
                   1418: 
                   1419:   int i;
                   1420:   char *zTest = 0;
                   1421:   int nTest = 0;
                   1422:   int bTestfound = 0;
                   1423:   int bPrefix = 0;
                   1424: 
                   1425:   if( argc>2 ) goto usage;
                   1426:   if( argc==2 ){
                   1427:     zTest = argv[1];
                   1428:     nTest = strlen(zTest);
                   1429:     if( zTest[nTest-1]=='*' ){
                   1430:       nTest--;
                   1431:       bPrefix = 1;
                   1432:     }
                   1433:   }
                   1434: 
                   1435:   sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
                   1436: 
                   1437:   for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
                   1438:     char const *z = aTest[i].zTest;
                   1439:     int n = strlen(z);
                   1440:     if( !zTest || ((bPrefix || n==nTest) && 0==strncmp(zTest, z, nTest)) ){
                   1441:       printf("Running %s for %d seconds...\n", z, aTest[i].nMs/1000);
                   1442:       aTest[i].xTest(aTest[i].nMs);
                   1443:       bTestfound++;
                   1444:     }
                   1445:   }
                   1446:   if( bTestfound==0 ) goto usage;
                   1447: 
                   1448:   printf("Total of %d errors across all tests\n", nGlobalErr);
                   1449:   return (nGlobalErr>0 ? 255 : 0);
                   1450: 
                   1451:  usage:
                   1452:   printf("Usage: %s [testname|testprefix*]\n", argv[0]);
                   1453:   printf("Available tests are:\n");
                   1454:   for(i=0; i<sizeof(aTest)/sizeof(aTest[0]); i++){
                   1455:     printf("   %s\n", aTest[i].zTest);
                   1456:   }
                   1457: 
                   1458:   return 254;
                   1459: }
                   1460: 
                   1461: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>