/ Hex Artifact Content
Login

Artifact 34848a9fd31aa65857b20a8bfc03aff77d8c3426:


0000: 2f 2a 0a 2a 2a 20 32 30 30 33 20 44 65 63 65 6d  /*.** 2003 Decem
0010: 62 65 72 20 31 38 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 18.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou give..**.****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 20 43 6f 64 65 20 66 6f  *****.** Code fo
0180: 72 20 74 65 73 74 69 6e 67 20 74 68 65 20 74 68  r testing the th
0190: 65 20 53 51 4c 69 74 65 20 6c 69 62 72 61 72 79  e SQLite library
01a0: 20 69 6e 20 61 20 6d 75 6c 74 69 74 68 72 65 61   in a multithrea
01b0: 64 65 64 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 2e  ded environment.
01c0: 0a 2a 2a 0a 2a 2a 20 24 49 64 3a 20 74 65 73 74  .**.** $Id: test
01d0: 34 2e 63 2c 76 20 31 2e 38 20 32 30 30 34 2f 30  4.c,v 1.8 2004/0
01e0: 35 2f 32 36 20 32 33 3a 32 35 3a 33 31 20 64 72  5/26 23:25:31 dr
01f0: 68 20 45 78 70 20 24 0a 2a 2f 0a 23 69 6e 63 6c  h Exp $.*/.#incl
0200: 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74 2e 68  ude "sqliteInt.h
0210: 22 0a 23 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e  ".#include "tcl.
0220: 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 6f 73 2e  h".#include "os.
0230: 68 22 0a 23 69 66 20 64 65 66 69 6e 65 64 28 4f  h".#if defined(O
0240: 53 5f 55 4e 49 58 29 20 26 26 20 4f 53 5f 55 4e  S_UNIX) && OS_UN
0250: 49 58 3d 3d 31 20 26 26 20 64 65 66 69 6e 65 64  IX==1 && defined
0260: 28 54 48 52 45 41 44 53 41 46 45 29 20 26 26 20  (THREADSAFE) && 
0270: 54 48 52 45 41 44 53 41 46 45 3d 3d 31 0a 23 69  THREADSAFE==1.#i
0280: 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62 2e 68  nclude <stdlib.h
0290: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69  >.#include <stri
02a0: 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  ng.h>.#include <
02b0: 70 74 68 72 65 61 64 2e 68 3e 0a 23 69 6e 63 6c  pthread.h>.#incl
02c0: 75 64 65 20 3c 73 63 68 65 64 2e 68 3e 0a 23 69  ude <sched.h>.#i
02d0: 6e 63 6c 75 64 65 20 3c 63 74 79 70 65 2e 68 3e  nclude <ctype.h>
02e0: 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 74 68 72  ../*.** Each thr
02f0: 65 61 64 20 69 73 20 63 6f 6e 74 72 6f 6c 6c 65  ead is controlle
0300: 64 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65  d by an instance
0310: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
0320: 67 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 0a  g.** structure..
0330: 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
0340: 74 20 54 68 72 65 61 64 20 54 68 72 65 61 64 3b  t Thread Thread;
0350: 0a 73 74 72 75 63 74 20 54 68 72 65 61 64 20 7b  .struct Thread {
0360: 0a 20 20 2f 2a 20 54 68 65 20 66 69 72 73 74 20  .  /* The first 
0370: 67 72 6f 75 70 20 6f 66 20 66 69 65 6c 64 73 20  group of fields 
0380: 61 72 65 20 77 72 69 74 61 62 6c 65 20 62 79 20  are writable by 
0390: 74 68 65 20 6d 61 73 74 65 72 20 61 6e 64 20 72  the master and r
03a0: 65 61 64 2d 6f 6e 6c 79 0a 20 20 2a 2a 20 74 6f  ead-only.  ** to
03b0: 20 74 68 65 20 74 68 72 65 61 64 2e 20 2a 2f 0a   the thread. */.
03c0: 20 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d    char *zFilenam
03d0: 65 3b 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65  e;       /* Name
03e0: 20 6f 66 20 64 61 74 61 62 61 73 65 20 66 69 6c   of database fil
03f0: 65 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 4f  e */.  void (*xO
0400: 70 29 28 54 68 72 65 61 64 2a 29 3b 20 20 2f 2a  p)(Thread*);  /*
0410: 20 6e 65 78 74 20 6f 70 65 72 61 74 69 6f 6e 20   next operation 
0420: 74 6f 20 64 6f 20 2a 2f 0a 20 20 63 68 61 72 20  to do */.  char 
0430: 2a 7a 41 72 67 3b 20 20 20 20 20 20 20 20 20 20  *zArg;          
0440: 20 20 2f 2a 20 61 72 67 75 6d 65 6e 74 20 75 73    /* argument us
0450: 61 62 6c 65 20 62 79 20 78 4f 70 20 2a 2f 0a 20  able by xOp */. 
0460: 20 69 6e 74 20 6f 70 6e 75 6d 3b 20 20 20 20 20   int opnum;     
0470: 20 20 20 20 20 20 20 20 2f 2a 20 4f 70 65 72 61          /* Opera
0480: 74 69 6f 6e 20 6e 75 6d 62 65 72 20 2a 2f 0a 20  tion number */. 
0490: 20 69 6e 74 20 62 75 73 79 3b 20 20 20 20 20 20   int busy;      
04a0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
04b0: 69 66 20 74 68 69 73 20 74 68 72 65 61 64 20 69  if this thread i
04c0: 73 20 69 6e 20 75 73 65 20 2a 2f 0a 0a 20 20 2f  s in use */..  /
04d0: 2a 20 54 68 65 20 6e 65 78 74 20 67 72 6f 75 70  * The next group
04e0: 20 6f 66 20 66 69 65 6c 64 73 20 61 72 65 20 77   of fields are w
04f0: 72 69 74 61 62 6c 65 20 62 79 20 74 68 65 20 74  ritable by the t
0500: 68 72 65 61 64 20 62 75 74 20 72 65 61 64 2d 6f  hread but read-o
0510: 6e 6c 79 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20  nly to the.  ** 
0520: 6d 61 73 74 65 72 2e 20 2a 2f 0a 20 20 69 6e 74  master. */.  int
0530: 20 63 6f 6d 70 6c 65 74 65 64 3b 20 20 20 20 20   completed;     
0540: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
0550: 6f 70 65 72 61 74 69 6f 6e 73 20 63 6f 6d 70 6c  operations compl
0560: 65 74 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65  eted */.  sqlite
0570: 20 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20   *db;           
0580: 2f 2a 20 4f 70 65 6e 20 64 61 74 61 62 61 73 65  /* Open database
0590: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73 74   */.  sqlite3_st
05a0: 6d 74 20 2a 70 53 74 6d 74 3b 20 20 20 20 20 2f  mt *pStmt;     /
05b0: 2a 20 50 65 6e 64 69 6e 67 20 6f 70 65 72 61 74  * Pending operat
05c0: 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  ion */.  char *z
05d0: 45 72 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f  Err;           /
05e0: 2a 20 6f 70 65 72 61 74 69 6f 6e 20 65 72 72 6f  * operation erro
05f0: 72 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 74  r */.  char *zSt
0600: 61 74 69 63 45 72 72 3b 20 20 20 20 20 2f 2a 20  aticErr;     /* 
0610: 53 74 61 74 69 63 20 65 72 72 6f 72 20 6d 65 73  Static error mes
0620: 73 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63  sage */.  int rc
0630: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0640: 2f 2a 20 6f 70 65 72 61 74 69 6f 6e 20 72 65 74  /* operation ret
0650: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e  urn code */.  in
0660: 74 20 61 72 67 63 3b 20 20 20 20 20 20 20 20 20  t argc;         
0670: 20 20 20 20 2f 2a 20 6e 75 6d 62 65 72 20 6f 66      /* number of
0680: 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 72 65 73 75   columns in resu
0690: 6c 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  lt */.  const ch
06a0: 61 72 20 2a 61 72 67 76 5b 31 30 30 5d 3b 20 20  ar *argv[100];  
06b0: 20 20 2f 2a 20 72 65 73 75 6c 74 20 63 6f 6c 75    /* result colu
06c0: 6d 6e 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  mns */.  const c
06d0: 68 61 72 20 2a 63 6f 6c 76 5b 31 30 30 5d 3b 20  har *colv[100]; 
06e0: 20 20 20 2f 2a 20 72 65 73 75 6c 74 20 63 6f 6c     /* result col
06f0: 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a 7d 3b 0a  umn names */.};.
0700: 0a 2f 2a 0a 2a 2a 20 54 68 65 72 65 20 63 61 6e  ./*.** There can
0710: 20 62 65 20 61 73 20 6d 61 6e 79 20 61 73 20 32   be as many as 2
0720: 36 20 74 68 72 65 61 64 73 20 72 75 6e 6e 69 6e  6 threads runnin
0730: 67 20 61 74 20 6f 6e 63 65 2e 20 20 45 61 63 68  g at once.  Each
0740: 20 69 73 20 6e 61 6d 65 64 0a 2a 2a 20 62 79 20   is named.** by 
0750: 61 20 63 61 70 69 74 61 6c 20 6c 65 74 74 65 72  a capital letter
0760: 3a 20 41 2c 20 42 2c 20 43 2c 20 2e 2e 2e 2c 20  : A, B, C, ..., 
0770: 59 2c 20 5a 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  Y, Z..*/.#define
0780: 20 4e 5f 54 48 52 45 41 44 20 32 36 0a 73 74 61   N_THREAD 26.sta
0790: 74 69 63 20 54 68 72 65 61 64 20 74 68 72 65 61  tic Thread threa
07a0: 64 73 65 74 5b 4e 5f 54 48 52 45 41 44 5d 3b 0a  dset[N_THREAD];.
07b0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 69 6e  ../*.** The main
07c0: 20 6c 6f 6f 70 20 66 6f 72 20 61 20 74 68 72 65   loop for a thre
07d0: 61 64 2e 20 20 54 68 72 65 61 64 73 20 75 73 65  ad.  Threads use
07e0: 20 62 75 73 79 20 77 61 69 74 69 6e 67 2e 20 0a   busy waiting. .
07f0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a  */.static void *
0800: 74 68 72 65 61 64 5f 6d 61 69 6e 28 76 6f 69 64  thread_main(void
0810: 20 2a 70 41 72 67 29 7b 0a 20 20 54 68 72 65 61   *pArg){.  Threa
0820: 64 20 2a 70 20 3d 20 28 54 68 72 65 61 64 2a 29  d *p = (Thread*)
0830: 70 41 72 67 3b 0a 20 20 69 66 28 20 70 2d 3e 64  pArg;.  if( p->d
0840: 62 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  b ){.    sqlite3
0850: 5f 63 6c 6f 73 65 28 70 2d 3e 64 62 29 3b 0a 20  _close(p->db);. 
0860: 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 6f 70 65   }.  sqlite3_ope
0870: 6e 28 70 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  n(p->zFilename, 
0880: 26 70 2d 3e 64 62 2c 20 30 29 3b 0a 20 20 69 66  &p->db, 0);.  if
0890: 28 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 73 71 6c  ( SQLITE_OK!=sql
08a0: 69 74 65 33 5f 65 72 72 63 6f 64 65 28 70 2d 3e  ite3_errcode(p->
08b0: 64 62 29 20 29 7b 0a 20 20 20 20 70 2d 3e 7a 45  db) ){.    p->zE
08c0: 72 72 20 3d 20 73 74 72 64 75 70 28 73 71 6c 69  rr = strdup(sqli
08d0: 74 65 33 5f 65 72 72 6d 73 67 28 70 2d 3e 64 62  te3_errmsg(p->db
08e0: 29 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  ));.    sqlite3_
08f0: 63 6c 6f 73 65 28 70 2d 3e 64 62 29 3b 0a 20 20  close(p->db);.  
0900: 20 20 70 2d 3e 64 62 20 3d 20 30 3b 0a 20 20 7d    p->db = 0;.  }
0910: 0a 20 20 70 2d 3e 70 53 74 6d 74 20 3d 20 30 3b  .  p->pStmt = 0;
0920: 0a 20 20 70 2d 3e 63 6f 6d 70 6c 65 74 65 64 20  .  p->completed 
0930: 3d 20 31 3b 0a 20 20 77 68 69 6c 65 28 20 70 2d  = 1;.  while( p-
0940: 3e 6f 70 6e 75 6d 3c 3d 70 2d 3e 63 6f 6d 70 6c  >opnum<=p->compl
0950: 65 74 65 64 20 29 20 73 63 68 65 64 5f 79 69 65  eted ) sched_yie
0960: 6c 64 28 29 3b 0a 20 20 77 68 69 6c 65 28 20 70  ld();.  while( p
0970: 2d 3e 78 4f 70 20 29 7b 0a 20 20 20 20 69 66 28  ->xOp ){.    if(
0980: 20 70 2d 3e 7a 45 72 72 20 26 26 20 70 2d 3e 7a   p->zErr && p->z
0990: 45 72 72 21 3d 70 2d 3e 7a 53 74 61 74 69 63 45  Err!=p->zStaticE
09a0: 72 72 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  rr ){.      sqli
09b0: 74 65 33 5f 66 72 65 65 6d 65 6d 28 70 2d 3e 7a  te3_freemem(p->z
09c0: 45 72 72 29 3b 0a 20 20 20 20 20 20 70 2d 3e 7a  Err);.      p->z
09d0: 45 72 72 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20  Err = 0;.    }. 
09e0: 20 20 20 28 2a 70 2d 3e 78 4f 70 29 28 70 29 3b     (*p->xOp)(p);
09f0: 0a 20 20 20 20 70 2d 3e 63 6f 6d 70 6c 65 74 65  .    p->complete
0a00: 64 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  d++;.    while( 
0a10: 70 2d 3e 6f 70 6e 75 6d 3c 3d 70 2d 3e 63 6f 6d  p->opnum<=p->com
0a20: 70 6c 65 74 65 64 20 29 20 73 63 68 65 64 5f 79  pleted ) sched_y
0a30: 69 65 6c 64 28 29 3b 0a 20 20 7d 0a 20 20 69 66  ield();.  }.  if
0a40: 28 20 70 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20  ( p->pStmt ){.  
0a50: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
0a60: 7a 65 28 70 2d 3e 70 53 74 6d 74 29 3b 0a 20 20  ze(p->pStmt);.  
0a70: 20 20 70 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a    p->pStmt = 0;.
0a80: 20 20 7d 0a 20 20 69 66 28 20 70 2d 3e 64 62 20    }.  if( p->db 
0a90: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 63  ){.    sqlite3_c
0aa0: 6c 6f 73 65 28 70 2d 3e 64 62 29 3b 0a 20 20 20  lose(p->db);.   
0ab0: 20 70 2d 3e 64 62 20 3d 20 30 3b 0a 20 20 7d 0a   p->db = 0;.  }.
0ac0: 20 20 69 66 28 20 70 2d 3e 7a 45 72 72 20 26 26    if( p->zErr &&
0ad0: 20 70 2d 3e 7a 45 72 72 21 3d 70 2d 3e 7a 53 74   p->zErr!=p->zSt
0ae0: 61 74 69 63 45 72 72 20 29 7b 0a 20 20 20 20 73  aticErr ){.    s
0af0: 71 6c 69 74 65 33 5f 66 72 65 65 6d 65 6d 28 70  qlite3_freemem(p
0b00: 2d 3e 7a 45 72 72 29 3b 0a 20 20 20 20 70 2d 3e  ->zErr);.    p->
0b10: 7a 45 72 72 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  zErr = 0;.  }.  
0b20: 70 2d 3e 63 6f 6d 70 6c 65 74 65 64 2b 2b 3b 0a  p->completed++;.
0b30: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f    return 0;.}../
0b40: 2a 0a 2a 2a 20 47 65 74 20 61 20 74 68 72 65 61  *.** Get a threa
0b50: 64 20 49 44 20 77 68 69 63 68 20 69 73 20 61 6e  d ID which is an
0b60: 20 75 70 70 65 72 20 63 61 73 65 20 6c 65 74 74   upper case lett
0b70: 65 72 2e 20 20 52 65 74 75 72 6e 20 74 68 65 20  er.  Return the 
0b80: 69 6e 64 65 78 2e 0a 2a 2a 20 49 66 20 74 68 65  index..** If the
0b90: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 74   argument is not
0ba0: 20 61 20 76 61 6c 69 64 20 74 68 72 65 61 64 20   a valid thread 
0bb0: 49 44 20 70 75 74 20 61 6e 20 65 72 72 6f 72 20  ID put an error 
0bc0: 6d 65 73 73 61 67 65 20 69 6e 0a 2a 2a 20 74 68  message in.** th
0bd0: 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 61 6e  e interpreter an
0be0: 64 20 72 65 74 75 72 6e 20 2d 31 2e 0a 2a 2f 0a  d return -1..*/.
0bf0: 73 74 61 74 69 63 20 69 6e 74 20 70 61 72 73 65  static int parse
0c00: 5f 74 68 72 65 61 64 5f 69 64 28 54 63 6c 5f 49  _thread_id(Tcl_I
0c10: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63  nterp *interp, c
0c20: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72 67 29  onst char *zArg)
0c30: 7b 0a 20 20 69 66 28 20 7a 41 72 67 3d 3d 30 20  {.  if( zArg==0 
0c40: 7c 7c 20 7a 41 72 67 5b 30 5d 3d 3d 30 20 7c 7c  || zArg[0]==0 ||
0c50: 20 7a 41 72 67 5b 31 5d 21 3d 30 20 7c 7c 20 21   zArg[1]!=0 || !
0c60: 69 73 75 70 70 65 72 28 7a 41 72 67 5b 30 5d 29  isupper(zArg[0])
0c70: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65   ){.    Tcl_Appe
0c80: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
0c90: 20 22 74 68 72 65 61 64 20 49 44 20 6d 75 73 74   "thread ID must
0ca0: 20 62 65 20 61 6e 20 75 70 70 65 72 20 63 61 73   be an upper cas
0cb0: 65 20 6c 65 74 74 65 72 22 2c 20 30 29 3b 0a 20  e letter", 0);. 
0cc0: 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20     return -1;.  
0cd0: 7d 0a 20 20 72 65 74 75 72 6e 20 7a 41 72 67 5b  }.  return zArg[
0ce0: 30 5d 20 2d 20 27 41 27 3b 0a 7d 0a 0a 2f 2a 0a  0] - 'A';.}../*.
0cf0: 2a 2a 20 55 73 61 67 65 3a 20 20 20 20 74 68 72  ** Usage:    thr
0d00: 65 61 64 5f 63 72 65 61 74 65 20 4e 41 4d 45 20  ead_create NAME 
0d10: 20 46 49 4c 45 4e 41 4d 45 0a 2a 2a 0a 2a 2a 20   FILENAME.**.** 
0d20: 4e 41 4d 45 20 73 68 6f 75 6c 64 20 62 65 20 61  NAME should be a
0d30: 6e 20 75 70 70 65 72 20 63 61 73 65 20 6c 65 74  n upper case let
0d40: 74 65 72 2e 20 20 53 74 61 72 74 20 74 68 65 20  ter.  Start the 
0d50: 74 68 72 65 61 64 20 72 75 6e 6e 69 6e 67 20 77  thread running w
0d60: 69 74 68 0a 2a 2a 20 61 6e 20 6f 70 65 6e 20 63  ith.** an open c
0d70: 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 74 68 65  onnection to the
0d80: 20 67 69 76 65 6e 20 64 61 74 61 62 61 73 65 2e   given database.
0d90: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
0da0: 63 6c 5f 74 68 72 65 61 64 5f 63 72 65 61 74 65  cl_thread_create
0db0: 28 0a 20 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65  (.  void *NotUse
0dc0: 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  d,.  Tcl_Interp 
0dd0: 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54  *interp,    /* T
0de0: 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  he TCL interpret
0df0: 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20  er that invoked 
0e00: 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a  this command */.
0e10: 20 20 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20    int argc,     
0e20: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
0e30: 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20  er of arguments 
0e40: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
0e50: 2a 2a 61 72 67 76 20 20 20 20 20 20 2f 2a 20 54  **argv      /* T
0e60: 65 78 74 20 6f 66 20 65 61 63 68 20 61 72 67 75  ext of each argu
0e70: 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ment */.){.  int
0e80: 20 69 3b 0a 20 20 70 74 68 72 65 61 64 5f 74 20   i;.  pthread_t 
0e90: 78 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  x;.  int rc;..  
0ea0: 69 66 28 20 61 72 67 63 21 3d 33 20 29 7b 0a 20  if( argc!=3 ){. 
0eb0: 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73     Tcl_AppendRes
0ec0: 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 77 72 6f  ult(interp, "wro
0ed0: 6e 67 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c  ng # args: shoul
0ee0: 64 20 62 65 20 5c 22 22 2c 20 61 72 67 76 5b 30  d be \"", argv[0
0ef0: 5d 2c 0a 20 20 20 20 20 20 20 22 20 49 44 20 46  ],.       " ID F
0f00: 49 4c 45 4e 41 4d 45 22 2c 20 30 29 3b 0a 20 20  ILENAME", 0);.  
0f10: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
0f20: 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d 20 70 61  OR;.  }.  i = pa
0f30: 72 73 65 5f 74 68 72 65 61 64 5f 69 64 28 69 6e  rse_thread_id(in
0f40: 74 65 72 70 2c 20 61 72 67 76 5b 31 5d 29 3b 0a  terp, argv[1]);.
0f50: 20 20 69 66 28 20 69 3c 30 20 29 20 72 65 74 75    if( i<0 ) retu
0f60: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
0f70: 69 66 28 20 74 68 72 65 61 64 73 65 74 5b 69 5d  if( threadset[i]
0f80: 2e 62 75 73 79 20 29 7b 0a 20 20 20 20 54 63 6c  .busy ){.    Tcl
0f90: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
0fa0: 74 65 72 70 2c 20 22 74 68 72 65 61 64 20 22 2c  terp, "thread ",
0fb0: 20 61 72 67 76 5b 31 5d 2c 20 22 20 69 73 20 61   argv[1], " is a
0fc0: 6c 72 65 61 64 79 20 72 75 6e 6e 69 6e 67 22 2c  lready running",
0fd0: 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20   0);.    return 
0fe0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
0ff0: 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75   threadset[i].bu
1000: 73 79 20 3d 20 31 3b 0a 20 20 73 71 6c 69 74 65  sy = 1;.  sqlite
1010: 46 72 65 65 28 74 68 72 65 61 64 73 65 74 5b 69  Free(threadset[i
1020: 5d 2e 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20  ].zFilename);.  
1030: 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 7a 46 69  threadset[i].zFi
1040: 6c 65 6e 61 6d 65 20 3d 20 73 71 6c 69 74 65 53  lename = sqliteS
1050: 74 72 44 75 70 28 61 72 67 76 5b 32 5d 29 3b 0a  trDup(argv[2]);.
1060: 20 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 6f    threadset[i].o
1070: 70 6e 75 6d 20 3d 20 31 3b 0a 20 20 74 68 72 65  pnum = 1;.  thre
1080: 61 64 73 65 74 5b 69 5d 2e 63 6f 6d 70 6c 65 74  adset[i].complet
1090: 65 64 20 3d 20 30 3b 0a 20 20 72 63 20 3d 20 70  ed = 0;.  rc = p
10a0: 74 68 72 65 61 64 5f 63 72 65 61 74 65 28 26 78  thread_create(&x
10b0: 2c 20 30 2c 20 74 68 72 65 61 64 5f 6d 61 69 6e  , 0, thread_main
10c0: 2c 20 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29  , &threadset[i])
10d0: 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20  ;.  if( rc ){.  
10e0: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
10f0: 6c 74 28 69 6e 74 65 72 70 2c 20 22 66 61 69 6c  lt(interp, "fail
1100: 65 64 20 74 6f 20 63 72 65 61 74 65 20 74 68 65  ed to create the
1110: 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20   thread", 0);.  
1120: 20 20 73 71 6c 69 74 65 46 72 65 65 28 74 68 72    sqliteFree(thr
1130: 65 61 64 73 65 74 5b 69 5d 2e 7a 46 69 6c 65 6e  eadset[i].zFilen
1140: 61 6d 65 29 3b 0a 20 20 20 20 74 68 72 65 61 64  ame);.    thread
1150: 73 65 74 5b 69 5d 2e 62 75 73 79 20 3d 20 30 3b  set[i].busy = 0;
1160: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
1170: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 70 74 68  ERROR;.  }.  pth
1180: 72 65 61 64 5f 64 65 74 61 63 68 28 78 29 3b 0a  read_detach(x);.
1190: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
11a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 61 69 74 20 66  .}../*.** Wait f
11b0: 6f 72 20 61 20 74 68 72 65 61 64 20 74 6f 20 72  or a thread to r
11c0: 65 61 63 68 20 69 74 73 20 69 64 6c 65 20 73 74  each its idle st
11d0: 61 74 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ate..*/.static v
11e0: 6f 69 64 20 74 68 72 65 61 64 5f 77 61 69 74 28  oid thread_wait(
11f0: 54 68 72 65 61 64 20 2a 70 29 7b 0a 20 20 77 68  Thread *p){.  wh
1200: 69 6c 65 28 20 70 2d 3e 6f 70 6e 75 6d 3e 70 2d  ile( p->opnum>p-
1210: 3e 63 6f 6d 70 6c 65 74 65 64 20 29 20 73 63 68  >completed ) sch
1220: 65 64 5f 79 69 65 6c 64 28 29 3b 0a 7d 0a 0a 2f  ed_yield();.}../
1230: 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 20 74 68 72  *.** Usage:  thr
1240: 65 61 64 5f 77 61 69 74 20 49 44 0a 2a 2a 0a 2a  ead_wait ID.**.*
1250: 2a 20 57 61 69 74 20 6f 6e 20 74 68 72 65 61 64  * Wait on thread
1260: 20 49 44 20 74 6f 20 72 65 61 63 68 20 69 74 73   ID to reach its
1270: 20 69 64 6c 65 20 73 74 61 74 65 2e 0a 2a 2f 0a   idle state..*/.
1280: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 74  static int tcl_t
1290: 68 72 65 61 64 5f 77 61 69 74 28 0a 20 20 76 6f  hread_wait(.  vo
12a0: 69 64 20 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54  id *NotUsed,.  T
12b0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
12c0: 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c  p,    /* The TCL
12d0: 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61   interpreter tha
12e0: 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63  t invoked this c
12f0: 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20  ommand */.  int 
1300: 61 72 67 63 2c 20 20 20 20 20 20 20 20 20 20 20  argc,           
1310: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
1320: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63  arguments */.  c
1330: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 72 67 76  onst char **argv
1340: 20 20 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66        /* Text of
1350: 20 65 61 63 68 20 61 72 67 75 6d 65 6e 74 20 2a   each argument *
1360: 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20  /.){.  int i;.. 
1370: 20 69 66 28 20 61 72 67 63 21 3d 32 20 29 7b 0a   if( argc!=2 ){.
1380: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65      Tcl_AppendRe
1390: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 77 72  sult(interp, "wr
13a0: 6f 6e 67 20 23 20 61 72 67 73 3a 20 73 68 6f 75  ong # args: shou
13b0: 6c 64 20 62 65 20 5c 22 22 2c 20 61 72 67 76 5b  ld be \"", argv[
13c0: 30 5d 2c 0a 20 20 20 20 20 20 20 22 20 49 44 22  0],.       " ID"
13d0: 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  , 0);.    return
13e0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
13f0: 20 20 69 20 3d 20 70 61 72 73 65 5f 74 68 72 65    i = parse_thre
1400: 61 64 5f 69 64 28 69 6e 74 65 72 70 2c 20 61 72  ad_id(interp, ar
1410: 67 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20 69 3c  gv[1]);.  if( i<
1420: 30 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45  0 ) return TCL_E
1430: 52 52 4f 52 3b 0a 20 20 69 66 28 20 21 74 68 72  RROR;.  if( !thr
1440: 65 61 64 73 65 74 5b 69 5d 2e 62 75 73 79 20 29  eadset[i].busy )
1450: 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64  {.    Tcl_Append
1460: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
1470: 6e 6f 20 73 75 63 68 20 74 68 72 65 61 64 22 2c  no such thread",
1480: 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20   0);.    return 
1490: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
14a0: 20 74 68 72 65 61 64 5f 77 61 69 74 28 26 74 68   thread_wait(&th
14b0: 72 65 61 64 73 65 74 5b 69 5d 29 3b 0a 20 20 72  readset[i]);.  r
14c0: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
14d0: 0a 2f 2a 0a 2a 2a 20 53 74 6f 70 20 61 20 74 68  ./*.** Stop a th
14e0: 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  read..*/.static 
14f0: 76 6f 69 64 20 73 74 6f 70 5f 74 68 72 65 61 64  void stop_thread
1500: 28 54 68 72 65 61 64 20 2a 70 29 7b 0a 20 20 74  (Thread *p){.  t
1510: 68 72 65 61 64 5f 77 61 69 74 28 70 29 3b 0a 20  hread_wait(p);. 
1520: 20 70 2d 3e 78 4f 70 20 3d 20 30 3b 0a 20 20 70   p->xOp = 0;.  p
1530: 2d 3e 6f 70 6e 75 6d 2b 2b 3b 0a 20 20 74 68 72  ->opnum++;.  thr
1540: 65 61 64 5f 77 61 69 74 28 70 29 3b 0a 20 20 73  ead_wait(p);.  s
1550: 71 6c 69 74 65 46 72 65 65 28 70 2d 3e 7a 41 72  qliteFree(p->zAr
1560: 67 29 3b 0a 20 20 70 2d 3e 7a 41 72 67 20 3d 20  g);.  p->zArg = 
1570: 30 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28  0;.  sqliteFree(
1580: 70 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20  p->zFilename);. 
1590: 20 70 2d 3e 7a 46 69 6c 65 6e 61 6d 65 20 3d 20   p->zFilename = 
15a0: 30 3b 0a 20 20 70 2d 3e 62 75 73 79 20 3d 20 30  0;.  p->busy = 0
15b0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65  ;.}../*.** Usage
15c0: 3a 20 20 74 68 72 65 61 64 5f 68 61 6c 74 20 49  :  thread_halt I
15d0: 44 0a 2a 2a 0a 2a 2a 20 43 61 75 73 65 20 61 20  D.**.** Cause a 
15e0: 74 68 72 65 61 64 20 74 6f 20 73 68 75 74 20 69  thread to shut i
15f0: 74 73 65 6c 66 20 64 6f 77 6e 2e 20 20 57 61 69  tself down.  Wai
1600: 74 20 66 6f 72 20 74 68 65 20 73 68 75 74 64 6f  t for the shutdo
1610: 77 6e 20 74 6f 20 62 65 0a 2a 2a 20 63 6f 6d 70  wn to be.** comp
1620: 6c 65 74 65 64 2e 20 20 49 66 20 49 44 20 69 73  leted.  If ID is
1630: 20 22 2a 22 20 74 68 65 6e 20 73 74 6f 70 20 61   "*" then stop a
1640: 6c 6c 20 74 68 72 65 61 64 73 2e 0a 2a 2f 0a 73  ll threads..*/.s
1650: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 74 68  tatic int tcl_th
1660: 72 65 61 64 5f 68 61 6c 74 28 0a 20 20 76 6f 69  read_halt(.  voi
1670: 64 20 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54 63  d *NotUsed,.  Tc
1680: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
1690: 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20  ,    /* The TCL 
16a0: 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61 74  interpreter that
16b0: 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f   invoked this co
16c0: 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 61  mmand */.  int a
16d0: 72 67 63 2c 20 20 20 20 20 20 20 20 20 20 20 20  rgc,            
16e0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61    /* Number of a
16f0: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f  rguments */.  co
1700: 6e 73 74 20 63 68 61 72 20 2a 2a 61 72 67 76 20  nst char **argv 
1710: 20 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20       /* Text of 
1720: 65 61 63 68 20 61 72 67 75 6d 65 6e 74 20 2a 2f  each argument */
1730: 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20  .){.  int i;..  
1740: 69 66 28 20 61 72 67 63 21 3d 32 20 29 7b 0a 20  if( argc!=2 ){. 
1750: 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73     Tcl_AppendRes
1760: 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 77 72 6f  ult(interp, "wro
1770: 6e 67 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c  ng # args: shoul
1780: 64 20 62 65 20 5c 22 22 2c 20 61 72 67 76 5b 30  d be \"", argv[0
1790: 5d 2c 0a 20 20 20 20 20 20 20 22 20 49 44 22 2c  ],.       " ID",
17a0: 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20   0);.    return 
17b0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
17c0: 20 69 66 28 20 61 72 67 76 5b 31 5d 5b 30 5d 3d   if( argv[1][0]=
17d0: 3d 27 2a 27 20 26 26 20 61 72 67 76 5b 31 5d 5b  ='*' && argv[1][
17e0: 31 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 66 6f 72  1]==0 ){.    for
17f0: 28 69 3d 30 3b 20 69 3c 4e 5f 54 48 52 45 41 44  (i=0; i<N_THREAD
1800: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; i++){.      if
1810: 28 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62  ( threadset[i].b
1820: 75 73 79 20 29 20 73 74 6f 70 5f 74 68 72 65 61  usy ) stop_threa
1830: 64 28 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29  d(&threadset[i])
1840: 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b  ;.    }.  }else{
1850: 0a 20 20 20 20 69 20 3d 20 70 61 72 73 65 5f 74  .    i = parse_t
1860: 68 72 65 61 64 5f 69 64 28 69 6e 74 65 72 70 2c  hread_id(interp,
1870: 20 61 72 67 76 5b 31 5d 29 3b 0a 20 20 20 20 69   argv[1]);.    i
1880: 66 28 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20  f( i<0 ) return 
1890: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 69  TCL_ERROR;.    i
18a0: 66 28 20 21 74 68 72 65 61 64 73 65 74 5b 69 5d  f( !threadset[i]
18b0: 2e 62 75 73 79 20 29 7b 0a 20 20 20 20 20 20 54  .busy ){.      T
18c0: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
18d0: 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68  interp, "no such
18e0: 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20   thread", 0);.  
18f0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
1900: 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 20 20  RROR;.    }.    
1910: 73 74 6f 70 5f 74 68 72 65 61 64 28 26 74 68 72  stop_thread(&thr
1920: 65 61 64 73 65 74 5b 69 5d 29 3b 0a 20 20 7d 0a  eadset[i]);.  }.
1930: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
1940: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a  .}../*.** Usage:
1950: 20 74 68 72 65 61 64 5f 61 72 67 63 20 20 49 44   thread_argc  ID
1960: 0a 2a 2a 0a 2a 2a 20 57 61 69 74 20 6f 6e 20 74  .**.** Wait on t
1970: 68 65 20 6d 6f 73 74 20 72 65 63 65 6e 74 20 74  he most recent t
1980: 68 72 65 61 64 5f 73 74 65 70 20 74 6f 20 63 6f  hread_step to co
1990: 6d 70 6c 65 74 65 2c 20 74 68 65 6e 20 72 65 74  mplete, then ret
19a0: 75 72 6e 20 74 68 65 0a 2a 2a 20 6e 75 6d 62 65  urn the.** numbe
19b0: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
19c0: 74 68 65 20 72 65 73 75 6c 74 20 73 65 74 2e 0a  the result set..
19d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  */.static int tc
19e0: 6c 5f 74 68 72 65 61 64 5f 61 72 67 63 28 0a 20  l_thread_argc(. 
19f0: 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 2c 0a   void *NotUsed,.
1a00: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
1a10: 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20  terp,    /* The 
1a20: 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20  TCL interpreter 
1a30: 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69  that invoked thi
1a40: 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69  s command */.  i
1a50: 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20 20  nt argc,        
1a60: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
1a70: 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  of arguments */.
1a80: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61    const char **a
1a90: 72 67 76 20 20 20 20 20 20 2f 2a 20 54 65 78 74  rgv      /* Text
1aa0: 20 6f 66 20 65 61 63 68 20 61 72 67 75 6d 65 6e   of each argumen
1ab0: 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b  t */.){.  int i;
1ac0: 0a 20 20 63 68 61 72 20 7a 42 75 66 5b 31 30 30  .  char zBuf[100
1ad0: 5d 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 21 3d  ];..  if( argc!=
1ae0: 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70  2 ){.    Tcl_App
1af0: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
1b00: 2c 20 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a  , "wrong # args:
1b10: 20 73 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20   should be \"", 
1b20: 61 72 67 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20  argv[0],.       
1b30: 22 20 49 44 22 2c 20 30 29 3b 0a 20 20 20 20 72  " ID", 0);.    r
1b40: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
1b50: 0a 20 20 7d 0a 20 20 69 20 3d 20 70 61 72 73 65  .  }.  i = parse
1b60: 5f 74 68 72 65 61 64 5f 69 64 28 69 6e 74 65 72  _thread_id(inter
1b70: 70 2c 20 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69  p, argv[1]);.  i
1b80: 66 28 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20  f( i<0 ) return 
1b90: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28  TCL_ERROR;.  if(
1ba0: 20 21 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62   !threadset[i].b
1bb0: 75 73 79 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41  usy ){.    Tcl_A
1bc0: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
1bd0: 72 70 2c 20 22 6e 6f 20 73 75 63 68 20 74 68 72  rp, "no such thr
1be0: 65 61 64 22 2c 20 30 29 3b 0a 20 20 20 20 72 65  ead", 0);.    re
1bf0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
1c00: 20 20 7d 0a 20 20 74 68 72 65 61 64 5f 77 61 69    }.  thread_wai
1c10: 74 28 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29  t(&threadset[i])
1c20: 3b 0a 20 20 73 70 72 69 6e 74 66 28 7a 42 75 66  ;.  sprintf(zBuf
1c30: 2c 20 22 25 64 22 2c 20 74 68 72 65 61 64 73 65  , "%d", threadse
1c40: 74 5b 69 5d 2e 61 72 67 63 29 3b 0a 20 20 54 63  t[i].argc);.  Tc
1c50: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
1c60: 6e 74 65 72 70 2c 20 7a 42 75 66 2c 20 30 29 3b  nterp, zBuf, 0);
1c70: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
1c80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65  ;.}../*.** Usage
1c90: 3a 20 74 68 72 65 61 64 5f 61 72 67 76 20 20 49  : thread_argv  I
1ca0: 44 20 20 20 4e 0a 2a 2a 0a 2a 2a 20 57 61 69 74  D   N.**.** Wait
1cb0: 20 6f 6e 20 74 68 65 20 6d 6f 73 74 20 72 65 63   on the most rec
1cc0: 65 6e 74 20 74 68 72 65 61 64 5f 73 74 65 70 20  ent thread_step 
1cd0: 74 6f 20 63 6f 6d 70 6c 65 74 65 2c 20 74 68 65  to complete, the
1ce0: 6e 20 72 65 74 75 72 6e 20 74 68 65 0a 2a 2a 20  n return the.** 
1cf0: 76 61 6c 75 65 20 6f 66 20 74 68 65 20 4e 2d 74  value of the N-t
1d00: 68 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65  h columns in the
1d10: 20 72 65 73 75 6c 74 20 73 65 74 2e 0a 2a 2f 0a   result set..*/.
1d20: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 74  static int tcl_t
1d30: 68 72 65 61 64 5f 61 72 67 76 28 0a 20 20 76 6f  hread_argv(.  vo
1d40: 69 64 20 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54  id *NotUsed,.  T
1d50: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
1d60: 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c  p,    /* The TCL
1d70: 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61   interpreter tha
1d80: 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63  t invoked this c
1d90: 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20  ommand */.  int 
1da0: 61 72 67 63 2c 20 20 20 20 20 20 20 20 20 20 20  argc,           
1db0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
1dc0: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63  arguments */.  c
1dd0: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 72 67 76  onst char **argv
1de0: 20 20 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66        /* Text of
1df0: 20 65 61 63 68 20 61 72 67 75 6d 65 6e 74 20 2a   each argument *
1e00: 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  /.){.  int i;.  
1e10: 69 6e 74 20 6e 3b 0a 0a 20 20 69 66 28 20 61 72  int n;..  if( ar
1e20: 67 63 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c  gc!=3 ){.    Tcl
1e30: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
1e40: 74 65 72 70 2c 20 22 77 72 6f 6e 67 20 23 20 61  terp, "wrong # a
1e50: 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20 5c  rgs: should be \
1e60: 22 22 2c 20 61 72 67 76 5b 30 5d 2c 0a 20 20 20  "", argv[0],.   
1e70: 20 20 20 20 22 20 49 44 20 4e 22 2c 20 30 29 3b      " ID N", 0);
1e80: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
1e90: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d  ERROR;.  }.  i =
1ea0: 20 70 61 72 73 65 5f 74 68 72 65 61 64 5f 69 64   parse_thread_id
1eb0: 28 69 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d  (interp, argv[1]
1ec0: 29 3b 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72  );.  if( i<0 ) r
1ed0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
1ee0: 0a 20 20 69 66 28 20 21 74 68 72 65 61 64 73 65  .  if( !threadse
1ef0: 74 5b 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20  t[i].busy ){.   
1f00: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
1f10: 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75  t(interp, "no su
1f20: 63 68 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a  ch thread", 0);.
1f30: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
1f40: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20  RROR;.  }.  if( 
1f50: 54 63 6c 5f 47 65 74 49 6e 74 28 69 6e 74 65 72  Tcl_GetInt(inter
1f60: 70 2c 20 61 72 67 76 5b 32 5d 2c 20 26 6e 29 20  p, argv[2], &n) 
1f70: 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52  ) return TCL_ERR
1f80: 4f 52 3b 0a 20 20 74 68 72 65 61 64 5f 77 61 69  OR;.  thread_wai
1f90: 74 28 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29  t(&threadset[i])
1fa0: 3b 0a 20 20 69 66 28 20 6e 3c 30 20 7c 7c 20 6e  ;.  if( n<0 || n
1fb0: 3e 3d 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 61  >=threadset[i].a
1fc0: 72 67 63 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41  rgc ){.    Tcl_A
1fd0: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
1fe0: 72 70 2c 20 22 63 6f 6c 75 6d 6e 20 6e 75 6d 62  rp, "column numb
1ff0: 65 72 20 6f 75 74 20 6f 66 20 72 61 6e 67 65 22  er out of range"
2000: 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  , 0);.    return
2010: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
2020: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
2030: 6c 74 28 69 6e 74 65 72 70 2c 20 74 68 72 65 61  lt(interp, threa
2040: 64 73 65 74 5b 69 5d 2e 61 72 67 76 5b 6e 5d 2c  dset[i].argv[n],
2050: 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43   0);.  return TC
2060: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55  L_OK;.}../*.** U
2070: 73 61 67 65 3a 20 74 68 72 65 61 64 5f 63 6f 6c  sage: thread_col
2080: 6e 61 6d 65 20 20 49 44 20 20 20 4e 0a 2a 2a 0a  name  ID   N.**.
2090: 2a 2a 20 57 61 69 74 20 6f 6e 20 74 68 65 20 6d  ** Wait on the m
20a0: 6f 73 74 20 72 65 63 65 6e 74 20 74 68 72 65 61  ost recent threa
20b0: 64 5f 73 74 65 70 20 74 6f 20 63 6f 6d 70 6c 65  d_step to comple
20c0: 74 65 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20  te, then return 
20d0: 74 68 65 0a 2a 2a 20 6e 61 6d 65 20 6f 66 20 74  the.** name of t
20e0: 68 65 20 4e 2d 74 68 20 63 6f 6c 75 6d 6e 73 20  he N-th columns 
20f0: 69 6e 20 74 68 65 20 72 65 73 75 6c 74 20 73 65  in the result se
2100: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
2110: 20 74 63 6c 5f 74 68 72 65 61 64 5f 63 6f 6c 6e   tcl_thread_coln
2120: 61 6d 65 28 0a 20 20 76 6f 69 64 20 2a 4e 6f 74  ame(.  void *Not
2130: 55 73 65 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Used,.  Tcl_Inte
2140: 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f  rp *interp,    /
2150: 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70  * The TCL interp
2160: 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b  reter that invok
2170: 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ed this command 
2180: 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 20  */.  int argc,  
2190: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
21a0: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
21b0: 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ts */.  const ch
21c0: 61 72 20 2a 2a 61 72 67 76 20 20 20 20 20 20 2f  ar **argv      /
21d0: 2a 20 54 65 78 74 20 6f 66 20 65 61 63 68 20 61  * Text of each a
21e0: 72 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20  rgument */.){.  
21f0: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 6e 3b 0a  int i;.  int n;.
2200: 0a 20 20 69 66 28 20 61 72 67 63 21 3d 33 20 29  .  if( argc!=3 )
2210: 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64  {.    Tcl_Append
2220: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
2230: 77 72 6f 6e 67 20 23 20 61 72 67 73 3a 20 73 68  wrong # args: sh
2240: 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20 61 72 67  ould be \"", arg
2250: 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20 22 20 49  v[0],.       " I
2260: 44 20 4e 22 2c 20 30 29 3b 0a 20 20 20 20 72 65  D N", 0);.    re
2270: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
2280: 20 20 7d 0a 20 20 69 20 3d 20 70 61 72 73 65 5f    }.  i = parse_
2290: 74 68 72 65 61 64 5f 69 64 28 69 6e 74 65 72 70  thread_id(interp
22a0: 2c 20 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69 66  , argv[1]);.  if
22b0: 28 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20 54  ( i<0 ) return T
22c0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20  CL_ERROR;.  if( 
22d0: 21 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75  !threadset[i].bu
22e0: 73 79 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70  sy ){.    Tcl_Ap
22f0: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
2300: 70 2c 20 22 6e 6f 20 73 75 63 68 20 74 68 72 65  p, "no such thre
2310: 61 64 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  ad", 0);.    ret
2320: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
2330: 20 7d 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74   }.  if( Tcl_Get
2340: 49 6e 74 28 69 6e 74 65 72 70 2c 20 61 72 67 76  Int(interp, argv
2350: 5b 32 5d 2c 20 26 6e 29 20 29 20 72 65 74 75 72  [2], &n) ) retur
2360: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 74  n TCL_ERROR;.  t
2370: 68 72 65 61 64 5f 77 61 69 74 28 26 74 68 72 65  hread_wait(&thre
2380: 61 64 73 65 74 5b 69 5d 29 3b 0a 20 20 69 66 28  adset[i]);.  if(
2390: 20 6e 3c 30 20 7c 7c 20 6e 3e 3d 74 68 72 65 61   n<0 || n>=threa
23a0: 64 73 65 74 5b 69 5d 2e 61 72 67 63 20 29 7b 0a  dset[i].argc ){.
23b0: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65      Tcl_AppendRe
23c0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 63 6f  sult(interp, "co
23d0: 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 6f 75 74 20  lumn number out 
23e0: 6f 66 20 72 61 6e 67 65 22 2c 20 30 29 3b 0a 20  of range", 0);. 
23f0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
2400: 52 4f 52 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 41  ROR;.  }.  Tcl_A
2410: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
2420: 72 70 2c 20 74 68 72 65 61 64 73 65 74 5b 69 5d  rp, threadset[i]
2430: 2e 63 6f 6c 76 5b 6e 5d 2c 20 30 29 3b 0a 20 20  .colv[n], 0);.  
2440: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d  return TCL_OK;.}
2450: 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 74  ../*.** Usage: t
2460: 68 72 65 61 64 5f 72 65 73 75 6c 74 20 20 49 44  hread_result  ID
2470: 0a 2a 2a 0a 2a 2a 20 57 61 69 74 20 6f 6e 20 74  .**.** Wait on t
2480: 68 65 20 6d 6f 73 74 20 72 65 63 65 6e 74 20 6f  he most recent o
2490: 70 65 72 61 74 69 6f 6e 20 74 6f 20 63 6f 6d 70  peration to comp
24a0: 6c 65 74 65 2c 20 74 68 65 6e 20 72 65 74 75 72  lete, then retur
24b0: 6e 20 74 68 65 0a 2a 2a 20 72 65 73 75 6c 74 20  n the.** result 
24c0: 63 6f 64 65 20 66 72 6f 6d 20 74 68 61 74 20 6f  code from that o
24d0: 70 65 72 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61  peration..*/.sta
24e0: 74 69 63 20 69 6e 74 20 74 63 6c 5f 74 68 72 65  tic int tcl_thre
24f0: 61 64 5f 72 65 73 75 6c 74 28 0a 20 20 76 6f 69  ad_result(.  voi
2500: 64 20 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54 63  d *NotUsed,.  Tc
2510: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
2520: 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20  ,    /* The TCL 
2530: 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61 74  interpreter that
2540: 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f   invoked this co
2550: 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 61  mmand */.  int a
2560: 72 67 63 2c 20 20 20 20 20 20 20 20 20 20 20 20  rgc,            
2570: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61    /* Number of a
2580: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f  rguments */.  co
2590: 6e 73 74 20 63 68 61 72 20 2a 2a 61 72 67 76 20  nst char **argv 
25a0: 20 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20       /* Text of 
25b0: 65 61 63 68 20 61 72 67 75 6d 65 6e 74 20 2a 2f  each argument */
25c0: 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63  .){.  int i;.  c
25d0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
25e0: 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 21 3d 32  ;..  if( argc!=2
25f0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65   ){.    Tcl_Appe
2600: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
2610: 20 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a 20   "wrong # args: 
2620: 73 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20 61  should be \"", a
2630: 72 67 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20 22  rgv[0],.       "
2640: 20 49 44 22 2c 20 30 29 3b 0a 20 20 20 20 72 65   ID", 0);.    re
2650: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
2660: 20 20 7d 0a 20 20 69 20 3d 20 70 61 72 73 65 5f    }.  i = parse_
2670: 74 68 72 65 61 64 5f 69 64 28 69 6e 74 65 72 70  thread_id(interp
2680: 2c 20 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69 66  , argv[1]);.  if
2690: 28 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20 54  ( i<0 ) return T
26a0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20  CL_ERROR;.  if( 
26b0: 21 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75  !threadset[i].bu
26c0: 73 79 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70  sy ){.    Tcl_Ap
26d0: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
26e0: 70 2c 20 22 6e 6f 20 73 75 63 68 20 74 68 72 65  p, "no such thre
26f0: 61 64 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  ad", 0);.    ret
2700: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
2710: 20 7d 0a 20 20 74 68 72 65 61 64 5f 77 61 69 74   }.  thread_wait
2720: 28 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29 3b  (&threadset[i]);
2730: 0a 20 20 73 77 69 74 63 68 28 20 74 68 72 65 61  .  switch( threa
2740: 64 73 65 74 5b 69 5d 2e 72 63 20 29 7b 0a 20 20  dset[i].rc ){.  
2750: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 4f 4b    case SQLITE_OK
2760: 3a 20 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 20  :         zName 
2770: 3d 20 22 53 51 4c 49 54 45 5f 4f 4b 22 3b 20 20  = "SQLITE_OK";  
2780: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
2790: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 45     case SQLITE_E
27a0: 52 52 4f 52 3a 20 20 20 20 20 20 7a 4e 61 6d 65  RROR:      zName
27b0: 20 3d 20 22 53 51 4c 49 54 45 5f 45 52 52 4f 52   = "SQLITE_ERROR
27c0: 22 3b 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  ";       break;.
27d0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
27e0: 49 4e 54 45 52 4e 41 4c 3a 20 20 20 7a 4e 61 6d  INTERNAL:   zNam
27f0: 65 20 3d 20 22 53 51 4c 49 54 45 5f 49 4e 54 45  e = "SQLITE_INTE
2800: 52 4e 41 4c 22 3b 20 20 20 20 62 72 65 61 6b 3b  RNAL";    break;
2810: 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45  .    case SQLITE
2820: 5f 50 45 52 4d 3a 20 20 20 20 20 20 20 7a 4e 61  _PERM:       zNa
2830: 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f 50 45 52  me = "SQLITE_PER
2840: 4d 22 3b 20 20 20 20 20 20 20 20 62 72 65 61 6b  M";        break
2850: 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49 54  ;.    case SQLIT
2860: 45 5f 41 42 4f 52 54 3a 20 20 20 20 20 20 7a 4e  E_ABORT:      zN
2870: 61 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f 41 42  ame = "SQLITE_AB
2880: 4f 52 54 22 3b 20 20 20 20 20 20 20 62 72 65 61  ORT";       brea
2890: 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49  k;.    case SQLI
28a0: 54 45 5f 42 55 53 59 3a 20 20 20 20 20 20 20 7a  TE_BUSY:       z
28b0: 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f 42  Name = "SQLITE_B
28c0: 55 53 59 22 3b 20 20 20 20 20 20 20 20 62 72 65  USY";        bre
28d0: 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c  ak;.    case SQL
28e0: 49 54 45 5f 4c 4f 43 4b 45 44 3a 20 20 20 20 20  ITE_LOCKED:     
28f0: 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f  zName = "SQLITE_
2900: 4c 4f 43 4b 45 44 22 3b 20 20 20 20 20 20 62 72  LOCKED";      br
2910: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51  eak;.    case SQ
2920: 4c 49 54 45 5f 4e 4f 4d 45 4d 3a 20 20 20 20 20  LITE_NOMEM:     
2930: 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54 45   zName = "SQLITE
2940: 5f 4e 4f 4d 45 4d 22 3b 20 20 20 20 20 20 20 62  _NOMEM";       b
2950: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53  reak;.    case S
2960: 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3a 20  QLITE_READONLY: 
2970: 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54    zName = "SQLIT
2980: 45 5f 52 45 41 44 4f 4e 4c 59 22 3b 20 20 20 20  E_READONLY";    
2990: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
29a0: 53 51 4c 49 54 45 5f 49 4e 54 45 52 52 55 50 54  SQLITE_INTERRUPT
29b0: 3a 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49  :  zName = "SQLI
29c0: 54 45 5f 49 4e 54 45 52 52 55 50 54 22 3b 20 20  TE_INTERRUPT";  
29d0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
29e0: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3a 20 20   SQLITE_IOERR:  
29f0: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c      zName = "SQL
2a00: 49 54 45 5f 49 4f 45 52 52 22 3b 20 20 20 20 20  ITE_IOERR";     
2a10: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73    break;.    cas
2a20: 65 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54  e SQLITE_CORRUPT
2a30: 3a 20 20 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51  :    zName = "SQ
2a40: 4c 49 54 45 5f 43 4f 52 52 55 50 54 22 3b 20 20  LITE_CORRUPT";  
2a50: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61     break;.    ca
2a60: 73 65 20 53 51 4c 49 54 45 5f 4e 4f 54 46 4f 55  se SQLITE_NOTFOU
2a70: 4e 44 3a 20 20 20 7a 4e 61 6d 65 20 3d 20 22 53  ND:   zName = "S
2a80: 51 4c 49 54 45 5f 4e 4f 54 46 4f 55 4e 44 22 3b  QLITE_NOTFOUND";
2a90: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63      break;.    c
2aa0: 61 73 65 20 53 51 4c 49 54 45 5f 46 55 4c 4c 3a  ase SQLITE_FULL:
2ab0: 20 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 22         zName = "
2ac0: 53 51 4c 49 54 45 5f 46 55 4c 4c 22 3b 20 20 20  SQLITE_FULL";   
2ad0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
2ae0: 63 61 73 65 20 53 51 4c 49 54 45 5f 43 41 4e 54  case SQLITE_CANT
2af0: 4f 50 45 4e 3a 20 20 20 7a 4e 61 6d 65 20 3d 20  OPEN:   zName = 
2b00: 22 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e  "SQLITE_CANTOPEN
2b10: 22 3b 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20  ";    break;.   
2b20: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 50 52 4f   case SQLITE_PRO
2b30: 54 4f 43 4f 4c 3a 20 20 20 7a 4e 61 6d 65 20 3d  TOCOL:   zName =
2b40: 20 22 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f   "SQLITE_PROTOCO
2b50: 4c 22 3b 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  L";    break;.  
2b60: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 45 4d    case SQLITE_EM
2b70: 50 54 59 3a 20 20 20 20 20 20 7a 4e 61 6d 65 20  PTY:      zName 
2b80: 3d 20 22 53 51 4c 49 54 45 5f 45 4d 50 54 59 22  = "SQLITE_EMPTY"
2b90: 3b 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;       break;. 
2ba0: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 53     case SQLITE_S
2bb0: 43 48 45 4d 41 3a 20 20 20 20 20 7a 4e 61 6d 65  CHEMA:     zName
2bc0: 20 3d 20 22 53 51 4c 49 54 45 5f 53 43 48 45 4d   = "SQLITE_SCHEM
2bd0: 41 22 3b 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  A";      break;.
2be0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
2bf0: 54 4f 4f 42 49 47 3a 20 20 20 20 20 7a 4e 61 6d  TOOBIG:     zNam
2c00: 65 20 3d 20 22 53 51 4c 49 54 45 5f 54 4f 4f 42  e = "SQLITE_TOOB
2c10: 49 47 22 3b 20 20 20 20 20 20 62 72 65 61 6b 3b  IG";      break;
2c20: 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45  .    case SQLITE
2c30: 5f 43 4f 4e 53 54 52 41 49 4e 54 3a 20 7a 4e 61  _CONSTRAINT: zNa
2c40: 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f 43 4f 4e  me = "SQLITE_CON
2c50: 53 54 52 41 49 4e 54 22 3b 20 20 62 72 65 61 6b  STRAINT";  break
2c60: 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49 54  ;.    case SQLIT
2c70: 45 5f 4d 49 53 4d 41 54 43 48 3a 20 20 20 7a 4e  E_MISMATCH:   zN
2c80: 61 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f 4d 49  ame = "SQLITE_MI
2c90: 53 4d 41 54 43 48 22 3b 20 20 20 20 62 72 65 61  SMATCH";    brea
2ca0: 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49  k;.    case SQLI
2cb0: 54 45 5f 4d 49 53 55 53 45 3a 20 20 20 20 20 7a  TE_MISUSE:     z
2cc0: 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f 4d  Name = "SQLITE_M
2cd0: 49 53 55 53 45 22 3b 20 20 20 20 20 20 62 72 65  ISUSE";      bre
2ce0: 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c  ak;.    case SQL
2cf0: 49 54 45 5f 4e 4f 4c 46 53 3a 20 20 20 20 20 20  ITE_NOLFS:      
2d00: 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54 45 5f  zName = "SQLITE_
2d10: 4e 4f 4c 46 53 22 3b 20 20 20 20 20 20 20 62 72  NOLFS";       br
2d20: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51  eak;.    case SQ
2d30: 4c 49 54 45 5f 41 55 54 48 3a 20 20 20 20 20 20  LITE_AUTH:      
2d40: 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54 45   zName = "SQLITE
2d50: 5f 41 55 54 48 22 3b 20 20 20 20 20 20 20 20 62  _AUTH";        b
2d60: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53  reak;.    case S
2d70: 51 4c 49 54 45 5f 46 4f 52 4d 41 54 3a 20 20 20  QLITE_FORMAT:   
2d80: 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49 54    zName = "SQLIT
2d90: 45 5f 46 4f 52 4d 41 54 22 3b 20 20 20 20 20 20  E_FORMAT";      
2da0: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
2db0: 53 51 4c 49 54 45 5f 52 41 4e 47 45 3a 20 20 20  SQLITE_RANGE:   
2dc0: 20 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c 49     zName = "SQLI
2dd0: 54 45 5f 52 41 4e 47 45 22 3b 20 20 20 20 20 20  TE_RANGE";      
2de0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
2df0: 20 53 51 4c 49 54 45 5f 52 4f 57 3a 20 20 20 20   SQLITE_ROW:    
2e00: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51 4c      zName = "SQL
2e10: 49 54 45 5f 52 4f 57 22 3b 20 20 20 20 20 20 20  ITE_ROW";       
2e20: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73    break;.    cas
2e30: 65 20 53 51 4c 49 54 45 5f 44 4f 4e 45 3a 20 20  e SQLITE_DONE:  
2e40: 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 22 53 51       zName = "SQ
2e50: 4c 49 54 45 5f 44 4f 4e 45 22 3b 20 20 20 20 20  LITE_DONE";     
2e60: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 64 65     break;.    de
2e70: 66 61 75 6c 74 3a 20 20 20 20 20 20 20 20 20 20  fault:          
2e80: 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 22 53        zName = "S
2e90: 51 4c 49 54 45 5f 55 6e 6b 6e 6f 77 6e 22 3b 20  QLITE_Unknown"; 
2ea0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20      break;.  }. 
2eb0: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
2ec0: 74 28 69 6e 74 65 72 70 2c 20 7a 4e 61 6d 65 2c  t(interp, zName,
2ed0: 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43   0);.  return TC
2ee0: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55  L_OK;.}../*.** U
2ef0: 73 61 67 65 3a 20 74 68 72 65 61 64 5f 65 72 72  sage: thread_err
2f00: 6f 72 20 20 49 44 0a 2a 2a 0a 2a 2a 20 57 61 69  or  ID.**.** Wai
2f10: 74 20 6f 6e 20 74 68 65 20 6d 6f 73 74 20 72 65  t on the most re
2f20: 63 65 6e 74 20 6f 70 65 72 61 74 69 6f 6e 20 74  cent operation t
2f30: 6f 20 63 6f 6d 70 6c 65 74 65 2c 20 74 68 65 6e  o complete, then
2f40: 20 72 65 74 75 72 6e 20 74 68 65 0a 2a 2a 20 65   return the.** e
2f50: 72 72 6f 72 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a  rror string..*/.
2f60: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 74  static int tcl_t
2f70: 68 72 65 61 64 5f 65 72 72 6f 72 28 0a 20 20 76  hread_error(.  v
2f80: 6f 69 64 20 2a 4e 6f 74 55 73 65 64 2c 0a 20 20  oid *NotUsed,.  
2f90: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
2fa0: 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43  rp,    /* The TC
2fb0: 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68  L interpreter th
2fc0: 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20  at invoked this 
2fd0: 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74  command */.  int
2fe0: 20 61 72 67 63 2c 20 20 20 20 20 20 20 20 20 20   argc,          
2ff0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
3000: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20   arguments */.  
3010: 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 72 67  const char **arg
3020: 76 20 20 20 20 20 20 2f 2a 20 54 65 78 74 20 6f  v      /* Text o
3030: 66 20 65 61 63 68 20 61 72 67 75 6d 65 6e 74 20  f each argument 
3040: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 0a  */.){.  int i;..
3050: 20 20 69 66 28 20 61 72 67 63 21 3d 32 20 29 7b    if( argc!=2 ){
3060: 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52  .    Tcl_AppendR
3070: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 77  esult(interp, "w
3080: 72 6f 6e 67 20 23 20 61 72 67 73 3a 20 73 68 6f  rong # args: sho
3090: 75 6c 64 20 62 65 20 5c 22 22 2c 20 61 72 67 76  uld be \"", argv
30a0: 5b 30 5d 2c 0a 20 20 20 20 20 20 20 22 20 49 44  [0],.       " ID
30b0: 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72  ", 0);.    retur
30c0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
30d0: 0a 20 20 69 20 3d 20 70 61 72 73 65 5f 74 68 72  .  i = parse_thr
30e0: 65 61 64 5f 69 64 28 69 6e 74 65 72 70 2c 20 61  ead_id(interp, a
30f0: 72 67 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20 69  rgv[1]);.  if( i
3100: 3c 30 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f  <0 ) return TCL_
3110: 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 21 74 68  ERROR;.  if( !th
3120: 72 65 61 64 73 65 74 5b 69 5d 2e 62 75 73 79 20  readset[i].busy 
3130: 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e  ){.    Tcl_Appen
3140: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
3150: 22 6e 6f 20 73 75 63 68 20 74 68 72 65 61 64 22  "no such thread"
3160: 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  , 0);.    return
3170: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
3180: 20 20 74 68 72 65 61 64 5f 77 61 69 74 28 26 74    thread_wait(&t
3190: 68 72 65 61 64 73 65 74 5b 69 5d 29 3b 0a 20 20  hreadset[i]);.  
31a0: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
31b0: 28 69 6e 74 65 72 70 2c 20 74 68 72 65 61 64 73  (interp, threads
31c0: 65 74 5b 69 5d 2e 7a 45 72 72 2c 20 30 29 3b 0a  et[i].zErr, 0);.
31d0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
31e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 70  .}../*.** This p
31f0: 72 6f 63 65 64 75 72 65 20 72 75 6e 73 20 69 6e  rocedure runs in
3200: 20 74 68 65 20 74 68 72 65 61 64 20 74 6f 20 63   the thread to c
3210: 6f 6d 70 69 6c 65 20 61 6e 20 53 51 4c 20 73 74  ompile an SQL st
3220: 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  atement..*/.stat
3230: 69 63 20 76 6f 69 64 20 64 6f 5f 63 6f 6d 70 69  ic void do_compi
3240: 6c 65 28 54 68 72 65 61 64 20 2a 70 29 7b 0a 20  le(Thread *p){. 
3250: 20 69 66 28 20 70 2d 3e 64 62 3d 3d 30 20 29 7b   if( p->db==0 ){
3260: 0a 20 20 20 20 70 2d 3e 7a 45 72 72 20 3d 20 70  .    p->zErr = p
3270: 2d 3e 7a 53 74 61 74 69 63 45 72 72 20 3d 20 22  ->zStaticErr = "
3280: 6e 6f 20 64 61 74 61 62 61 73 65 20 69 73 20 6f  no database is o
3290: 70 65 6e 22 3b 0a 20 20 20 20 70 2d 3e 72 63 20  pen";.    p->rc 
32a0: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
32b0: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
32c0: 20 20 69 66 28 20 70 2d 3e 70 53 74 6d 74 20 29    if( p->pStmt )
32d0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69  {.    sqlite3_fi
32e0: 6e 61 6c 69 7a 65 28 70 2d 3e 70 53 74 6d 74 29  nalize(p->pStmt)
32f0: 3b 0a 20 20 20 20 70 2d 3e 70 53 74 6d 74 20 3d  ;.    p->pStmt =
3300: 20 30 3b 0a 20 20 7d 0a 20 20 70 2d 3e 72 63 20   0;.  }.  p->rc 
3310: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
3320: 65 28 70 2d 3e 64 62 2c 20 70 2d 3e 7a 41 72 67  e(p->db, p->zArg
3330: 2c 20 2d 31 2c 20 26 70 2d 3e 70 53 74 6d 74 2c  , -1, &p->pStmt,
3340: 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73   0);.}../*.** Us
3350: 61 67 65 3a 20 74 68 72 65 61 64 5f 63 6f 6d 70  age: thread_comp
3360: 69 6c 65 20 49 44 20 53 51 4c 0a 2a 2a 0a 2a 2a  ile ID SQL.**.**
3370: 20 43 6f 6d 70 69 6c 65 20 61 20 6e 65 77 20 76   Compile a new v
3380: 69 72 74 75 61 6c 20 6d 61 63 68 69 6e 65 2e 0a  irtual machine..
3390: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  */.static int tc
33a0: 6c 5f 74 68 72 65 61 64 5f 63 6f 6d 70 69 6c 65  l_thread_compile
33b0: 28 0a 20 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65  (.  void *NotUse
33c0: 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  d,.  Tcl_Interp 
33d0: 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54  *interp,    /* T
33e0: 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  he TCL interpret
33f0: 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20  er that invoked 
3400: 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a  this command */.
3410: 20 20 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20    int argc,     
3420: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
3430: 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20  er of arguments 
3440: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
3450: 2a 2a 61 72 67 76 20 20 20 20 20 20 2f 2a 20 54  **argv      /* T
3460: 65 78 74 20 6f 66 20 65 61 63 68 20 61 72 67 75  ext of each argu
3470: 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ment */.){.  int
3480: 20 69 3b 0a 20 20 69 66 28 20 61 72 67 63 21 3d   i;.  if( argc!=
3490: 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70  3 ){.    Tcl_App
34a0: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
34b0: 2c 20 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a  , "wrong # args:
34c0: 20 73 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20   should be \"", 
34d0: 61 72 67 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20  argv[0],.       
34e0: 22 20 49 44 20 53 51 4c 22 2c 20 30 29 3b 0a 20  " ID SQL", 0);. 
34f0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
3500: 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d 20 70  ROR;.  }.  i = p
3510: 61 72 73 65 5f 74 68 72 65 61 64 5f 69 64 28 69  arse_thread_id(i
3520: 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d 29 3b  nterp, argv[1]);
3530: 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72 65 74  .  if( i<0 ) ret
3540: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
3550: 20 69 66 28 20 21 74 68 72 65 61 64 73 65 74 5b   if( !threadset[
3560: 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20 20 54  i].busy ){.    T
3570: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
3580: 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68  interp, "no such
3590: 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20   thread", 0);.  
35a0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
35b0: 4f 52 3b 0a 20 20 7d 0a 20 20 74 68 72 65 61 64  OR;.  }.  thread
35c0: 5f 77 61 69 74 28 26 74 68 72 65 61 64 73 65 74  _wait(&threadset
35d0: 5b 69 5d 29 3b 0a 20 20 74 68 72 65 61 64 73 65  [i]);.  threadse
35e0: 74 5b 69 5d 2e 78 4f 70 20 3d 20 64 6f 5f 63 6f  t[i].xOp = do_co
35f0: 6d 70 69 6c 65 3b 0a 20 20 73 71 6c 69 74 65 46  mpile;.  sqliteF
3600: 72 65 65 28 74 68 72 65 61 64 73 65 74 5b 69 5d  ree(threadset[i]
3610: 2e 7a 41 72 67 29 3b 0a 20 20 74 68 72 65 61 64  .zArg);.  thread
3620: 73 65 74 5b 69 5d 2e 7a 41 72 67 20 3d 20 73 71  set[i].zArg = sq
3630: 6c 69 74 65 53 74 72 44 75 70 28 61 72 67 76 5b  liteStrDup(argv[
3640: 32 5d 29 3b 0a 20 20 74 68 72 65 61 64 73 65 74  2]);.  threadset
3650: 5b 69 5d 2e 6f 70 6e 75 6d 2b 2b 3b 0a 20 20 72  [i].opnum++;.  r
3660: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
3670: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 70 72 6f 63  ./*.** This proc
3680: 65 64 75 72 65 20 72 75 6e 73 20 69 6e 20 74 68  edure runs in th
3690: 65 20 74 68 72 65 61 64 20 74 6f 20 73 74 65 70  e thread to step
36a0: 20 74 68 65 20 76 69 72 74 75 61 6c 20 6d 61 63   the virtual mac
36b0: 68 69 6e 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  hine..*/.static 
36c0: 76 6f 69 64 20 64 6f 5f 73 74 65 70 28 54 68 72  void do_step(Thr
36d0: 65 61 64 20 2a 70 29 7b 0a 20 20 69 6e 74 20 69  ead *p){.  int i
36e0: 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 74 6d 74  ;.  if( p->pStmt
36f0: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e 7a 45  ==0 ){.    p->zE
3700: 72 72 20 3d 20 70 2d 3e 7a 53 74 61 74 69 63 45  rr = p->zStaticE
3710: 72 72 20 3d 20 22 6e 6f 20 76 69 72 74 75 61 6c  rr = "no virtual
3720: 20 6d 61 63 68 69 6e 65 20 61 76 61 69 6c 61 62   machine availab
3730: 6c 65 22 3b 0a 20 20 20 20 70 2d 3e 72 63 20 3d  le";.    p->rc =
3740: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
3750: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20     return;.  }. 
3760: 20 70 2d 3e 72 63 20 3d 20 73 71 6c 69 74 65 33   p->rc = sqlite3
3770: 5f 73 74 65 70 28 70 2d 3e 70 53 74 6d 74 29 3b  _step(p->pStmt);
3780: 0a 20 20 69 66 28 20 70 2d 3e 72 63 3d 3d 53 51  .  if( p->rc==SQ
3790: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
37a0: 70 2d 3e 61 72 67 63 20 3d 20 73 71 6c 69 74 65  p->argc = sqlite
37b0: 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70  3_column_count(p
37c0: 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 66 6f  ->pStmt);.    fo
37d0: 72 28 69 3d 30 3b 20 69 3c 73 71 6c 69 74 65 33  r(i=0; i<sqlite3
37e0: 5f 64 61 74 61 5f 63 6f 75 6e 74 28 70 2d 3e 70  _data_count(p->p
37f0: 53 74 6d 74 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  Stmt); i++){.   
3800: 20 20 20 70 2d 3e 61 72 67 76 5b 69 5d 20 3d 20     p->argv[i] = 
3810: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
3820: 65 78 74 28 70 2d 3e 70 53 74 6d 74 2c 20 69 29  ext(p->pStmt, i)
3830: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
3840: 69 3d 30 3b 20 69 3c 70 2d 3e 61 72 67 63 3b 20  i=0; i<p->argc; 
3850: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 70 2d 3e 63  i++){.      p->c
3860: 6f 6c 76 5b 69 5d 20 3d 20 73 71 6c 69 74 65 33  olv[i] = sqlite3
3870: 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70 2d 3e  _column_name(p->
3880: 70 53 74 6d 74 2c 20 69 29 3b 0a 20 20 20 20 7d  pStmt, i);.    }
3890: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73  .  }.}../*.** Us
38a0: 61 67 65 3a 20 74 68 72 65 61 64 5f 73 74 65 70  age: thread_step
38b0: 20 49 44 0a 2a 2a 0a 2a 2a 20 41 64 76 61 6e 63   ID.**.** Advanc
38c0: 65 20 74 68 65 20 76 69 72 74 75 61 6c 20 6d 61  e the virtual ma
38d0: 63 68 69 6e 65 20 62 79 20 6f 6e 65 20 73 74 65  chine by one ste
38e0: 70 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  p.*/.static int 
38f0: 74 63 6c 5f 74 68 72 65 61 64 5f 73 74 65 70 28  tcl_thread_step(
3900: 0a 20 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64  .  void *NotUsed
3910: 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ,.  Tcl_Interp *
3920: 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68  interp,    /* Th
3930: 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65  e TCL interprete
3940: 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74  r that invoked t
3950: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20  his command */. 
3960: 20 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20   int argc,      
3970: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
3980: 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a  r of arguments *
3990: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
39a0: 2a 61 72 67 76 20 20 20 20 20 20 2f 2a 20 54 65  *argv      /* Te
39b0: 78 74 20 6f 66 20 65 61 63 68 20 61 72 67 75 6d  xt of each argum
39c0: 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ent */.){.  int 
39d0: 69 3b 0a 20 20 69 66 28 20 61 72 67 63 21 3d 32  i;.  if( argc!=2
39e0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65   ){.    Tcl_Appe
39f0: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
3a00: 20 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a 20   "wrong # args: 
3a10: 73 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20 61  should be \"", a
3a20: 72 67 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20 22  rgv[0],.       "
3a30: 20 49 44 4c 22 2c 20 30 29 3b 0a 20 20 20 20 72   IDL", 0);.    r
3a40: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
3a50: 0a 20 20 7d 0a 20 20 69 20 3d 20 70 61 72 73 65  .  }.  i = parse
3a60: 5f 74 68 72 65 61 64 5f 69 64 28 69 6e 74 65 72  _thread_id(inter
3a70: 70 2c 20 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69  p, argv[1]);.  i
3a80: 66 28 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20  f( i<0 ) return 
3a90: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28  TCL_ERROR;.  if(
3aa0: 20 21 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62   !threadset[i].b
3ab0: 75 73 79 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41  usy ){.    Tcl_A
3ac0: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
3ad0: 72 70 2c 20 22 6e 6f 20 73 75 63 68 20 74 68 72  rp, "no such thr
3ae0: 65 61 64 22 2c 20 30 29 3b 0a 20 20 20 20 72 65  ead", 0);.    re
3af0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
3b00: 20 20 7d 0a 20 20 74 68 72 65 61 64 5f 77 61 69    }.  thread_wai
3b10: 74 28 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29  t(&threadset[i])
3b20: 3b 0a 20 20 74 68 72 65 61 64 73 65 74 5b 69 5d  ;.  threadset[i]
3b30: 2e 78 4f 70 20 3d 20 64 6f 5f 73 74 65 70 3b 0a  .xOp = do_step;.
3b40: 20 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 6f    threadset[i].o
3b50: 70 6e 75 6d 2b 2b 3b 0a 20 20 72 65 74 75 72 6e  pnum++;.  return
3b60: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a   TCL_OK;.}../*.*
3b70: 2a 20 54 68 69 73 20 70 72 6f 63 65 64 75 72 65  * This procedure
3b80: 20 72 75 6e 73 20 69 6e 20 74 68 65 20 74 68 72   runs in the thr
3b90: 65 61 64 20 74 6f 20 66 69 6e 61 6c 69 7a 65 20  ead to finalize 
3ba0: 61 20 76 69 72 74 75 61 6c 20 6d 61 63 68 69 6e  a virtual machin
3bb0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  e..*/.static voi
3bc0: 64 20 64 6f 5f 66 69 6e 61 6c 69 7a 65 28 54 68  d do_finalize(Th
3bd0: 72 65 61 64 20 2a 70 29 7b 0a 20 20 69 66 28 20  read *p){.  if( 
3be0: 70 2d 3e 70 53 74 6d 74 3d 3d 30 20 29 7b 0a 20  p->pStmt==0 ){. 
3bf0: 20 20 20 70 2d 3e 7a 45 72 72 20 3d 20 70 2d 3e     p->zErr = p->
3c00: 7a 53 74 61 74 69 63 45 72 72 20 3d 20 22 6e 6f  zStaticErr = "no
3c10: 20 76 69 72 74 75 61 6c 20 6d 61 63 68 69 6e 65   virtual machine
3c20: 20 61 76 61 69 6c 61 62 6c 65 22 3b 0a 20 20 20   available";.   
3c30: 20 70 2d 3e 72 63 20 3d 20 53 51 4c 49 54 45 5f   p->rc = SQLITE_
3c40: 45 52 52 4f 52 3b 0a 20 20 20 20 72 65 74 75 72  ERROR;.    retur
3c50: 6e 3b 0a 20 20 7d 0a 20 20 70 2d 3e 72 63 20 3d  n;.  }.  p->rc =
3c60: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
3c70: 65 28 70 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 70  e(p->pStmt);.  p
3c80: 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 7d 0a 0a  ->pStmt = 0;.}..
3c90: 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 74 68 72  /*.** Usage: thr
3ca0: 65 61 64 5f 66 69 6e 61 6c 69 7a 65 20 49 44 0a  ead_finalize ID.
3cb0: 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 69 7a 65 20 74  **.** Finalize t
3cc0: 68 65 20 76 69 72 74 75 61 6c 20 6d 61 63 68 69  he virtual machi
3cd0: 6e 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ne..*/.static in
3ce0: 74 20 74 63 6c 5f 74 68 72 65 61 64 5f 66 69 6e  t tcl_thread_fin
3cf0: 61 6c 69 7a 65 28 0a 20 20 76 6f 69 64 20 2a 4e  alize(.  void *N
3d00: 6f 74 55 73 65 64 2c 0a 20 20 54 63 6c 5f 49 6e  otUsed,.  Tcl_In
3d10: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20  terp *interp,   
3d20: 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65   /* The TCL inte
3d30: 72 70 72 65 74 65 72 20 74 68 61 74 20 69 6e 76  rpreter that inv
3d40: 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e  oked this comman
3d50: 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c  d */.  int argc,
3d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3d70: 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d   Number of argum
3d80: 65 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ents */.  const 
3d90: 63 68 61 72 20 2a 2a 61 72 67 76 20 20 20 20 20  char **argv     
3da0: 20 2f 2a 20 54 65 78 74 20 6f 66 20 65 61 63 68   /* Text of each
3db0: 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b 0a   argument */.){.
3dc0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 61    int i;.  if( a
3dd0: 72 67 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  rgc!=2 ){.    Tc
3de0: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
3df0: 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67 20 23 20  nterp, "wrong # 
3e00: 61 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20  args: should be 
3e10: 5c 22 22 2c 20 61 72 67 76 5b 30 5d 2c 0a 20 20  \"", argv[0],.  
3e20: 20 20 20 20 20 22 20 49 44 4c 22 2c 20 30 29 3b       " IDL", 0);
3e30: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
3e40: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d  ERROR;.  }.  i =
3e50: 20 70 61 72 73 65 5f 74 68 72 65 61 64 5f 69 64   parse_thread_id
3e60: 28 69 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d  (interp, argv[1]
3e70: 29 3b 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72  );.  if( i<0 ) r
3e80: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
3e90: 0a 20 20 69 66 28 20 21 74 68 72 65 61 64 73 65  .  if( !threadse
3ea0: 74 5b 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20  t[i].busy ){.   
3eb0: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
3ec0: 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75  t(interp, "no su
3ed0: 63 68 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a  ch thread", 0);.
3ee0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
3ef0: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 74 68 72 65  RROR;.  }.  thre
3f00: 61 64 5f 77 61 69 74 28 26 74 68 72 65 61 64 73  ad_wait(&threads
3f10: 65 74 5b 69 5d 29 3b 0a 20 20 74 68 72 65 61 64  et[i]);.  thread
3f20: 73 65 74 5b 69 5d 2e 78 4f 70 20 3d 20 64 6f 5f  set[i].xOp = do_
3f30: 66 69 6e 61 6c 69 7a 65 3b 0a 20 20 73 71 6c 69  finalize;.  sqli
3f40: 74 65 46 72 65 65 28 74 68 72 65 61 64 73 65 74  teFree(threadset
3f50: 5b 69 5d 2e 7a 41 72 67 29 3b 0a 20 20 74 68 72  [i].zArg);.  thr
3f60: 65 61 64 73 65 74 5b 69 5d 2e 7a 41 72 67 20 3d  eadset[i].zArg =
3f70: 20 30 3b 0a 20 20 74 68 72 65 61 64 73 65 74 5b   0;.  threadset[
3f80: 69 5d 2e 6f 70 6e 75 6d 2b 2b 3b 0a 20 20 72 65  i].opnum++;.  re
3f90: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
3fa0: 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 74 68 72  /*.** Usage: thr
3fb0: 65 61 64 5f 73 77 61 70 20 49 44 20 49 44 0a 2a  ead_swap ID ID.*
3fc0: 2a 0a 2a 2a 20 49 6e 74 65 72 63 68 61 6e 67 65  *.** Interchange
3fd0: 20 74 68 65 20 73 71 6c 69 74 65 2a 20 70 6f 69   the sqlite* poi
3fe0: 6e 74 65 72 20 62 65 74 77 65 65 6e 20 74 77 6f  nter between two
3ff0: 20 74 68 72 65 61 64 73 2e 0a 2a 2f 0a 73 74 61   threads..*/.sta
4000: 74 69 63 20 69 6e 74 20 74 63 6c 5f 74 68 72 65  tic int tcl_thre
4010: 61 64 5f 73 77 61 70 28 0a 20 20 76 6f 69 64 20  ad_swap(.  void 
4020: 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54 63 6c 5f  *NotUsed,.  Tcl_
4030: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
4040: 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e     /* The TCL in
4050: 74 65 72 70 72 65 74 65 72 20 74 68 61 74 20 69  terpreter that i
4060: 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d  nvoked this comm
4070: 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67  and */.  int arg
4080: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
4090: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67  /* Number of arg
40a0: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e 73  uments */.  cons
40b0: 74 20 63 68 61 72 20 2a 2a 61 72 67 76 20 20 20  t char **argv   
40c0: 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 65 61     /* Text of ea
40d0: 63 68 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 29  ch argument */.)
40e0: 7b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20  {.  int i, j;.  
40f0: 73 71 6c 69 74 65 20 2a 74 65 6d 70 3b 0a 20 20  sqlite *temp;.  
4100: 69 66 28 20 61 72 67 63 21 3d 33 20 29 7b 0a 20  if( argc!=3 ){. 
4110: 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73     Tcl_AppendRes
4120: 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 77 72 6f  ult(interp, "wro
4130: 6e 67 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c  ng # args: shoul
4140: 64 20 62 65 20 5c 22 22 2c 20 61 72 67 76 5b 30  d be \"", argv[0
4150: 5d 2c 0a 20 20 20 20 20 20 20 22 20 49 44 31 20  ],.       " ID1 
4160: 49 44 32 22 2c 20 30 29 3b 0a 20 20 20 20 72 65  ID2", 0);.    re
4170: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
4180: 20 20 7d 0a 20 20 69 20 3d 20 70 61 72 73 65 5f    }.  i = parse_
4190: 74 68 72 65 61 64 5f 69 64 28 69 6e 74 65 72 70  thread_id(interp
41a0: 2c 20 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69 66  , argv[1]);.  if
41b0: 28 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20 54  ( i<0 ) return T
41c0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20  CL_ERROR;.  if( 
41d0: 21 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75  !threadset[i].bu
41e0: 73 79 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70  sy ){.    Tcl_Ap
41f0: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
4200: 70 2c 20 22 6e 6f 20 73 75 63 68 20 74 68 72 65  p, "no such thre
4210: 61 64 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  ad", 0);.    ret
4220: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
4230: 20 7d 0a 20 20 74 68 72 65 61 64 5f 77 61 69 74   }.  thread_wait
4240: 28 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29 3b  (&threadset[i]);
4250: 0a 20 20 6a 20 3d 20 70 61 72 73 65 5f 74 68 72  .  j = parse_thr
4260: 65 61 64 5f 69 64 28 69 6e 74 65 72 70 2c 20 61  ead_id(interp, a
4270: 72 67 76 5b 32 5d 29 3b 0a 20 20 69 66 28 20 6a  rgv[2]);.  if( j
4280: 3c 30 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f  <0 ) return TCL_
4290: 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 21 74 68  ERROR;.  if( !th
42a0: 72 65 61 64 73 65 74 5b 6a 5d 2e 62 75 73 79 20  readset[j].busy 
42b0: 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e  ){.    Tcl_Appen
42c0: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
42d0: 22 6e 6f 20 73 75 63 68 20 74 68 72 65 61 64 22  "no such thread"
42e0: 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  , 0);.    return
42f0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
4300: 20 20 74 68 72 65 61 64 5f 77 61 69 74 28 26 74    thread_wait(&t
4310: 68 72 65 61 64 73 65 74 5b 6a 5d 29 3b 0a 20 20  hreadset[j]);.  
4320: 74 65 6d 70 20 3d 20 74 68 72 65 61 64 73 65 74  temp = threadset
4330: 5b 69 5d 2e 64 62 3b 0a 20 20 74 68 72 65 61 64  [i].db;.  thread
4340: 73 65 74 5b 69 5d 2e 64 62 20 3d 20 74 68 72 65  set[i].db = thre
4350: 61 64 73 65 74 5b 6a 5d 2e 64 62 3b 0a 20 20 74  adset[j].db;.  t
4360: 68 72 65 61 64 73 65 74 5b 6a 5d 2e 64 62 20 3d  hreadset[j].db =
4370: 20 74 65 6d 70 3b 0a 20 20 72 65 74 75 72 6e 20   temp;.  return 
4380: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TCL_OK;.}../*.**
4390: 20 52 65 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e   Register comman
43a0: 64 73 20 77 69 74 68 20 74 68 65 20 54 43 4c 20  ds with the TCL 
43b0: 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a  interpreter..*/.
43c0: 69 6e 74 20 53 71 6c 69 74 65 74 65 73 74 34 5f  int Sqlitetest4_
43d0: 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20  Init(Tcl_Interp 
43e0: 2a 69 6e 74 65 72 70 29 7b 0a 20 20 73 74 61 74  *interp){.  stat
43f0: 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20  ic struct {.    
4400: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20   char *zName;.  
4410: 20 20 20 54 63 6c 5f 43 6d 64 50 72 6f 63 20 2a     Tcl_CmdProc *
4420: 78 50 72 6f 63 3b 0a 20 20 7d 20 61 43 6d 64 5b  xProc;.  } aCmd[
4430: 5d 20 3d 20 7b 0a 20 20 20 20 20 7b 20 22 74 68  ] = {.     { "th
4440: 72 65 61 64 5f 63 72 65 61 74 65 22 2c 20 20 20  read_create",   
4450: 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a 29    (Tcl_CmdProc*)
4460: 74 63 6c 5f 74 68 72 65 61 64 5f 63 72 65 61 74  tcl_thread_creat
4470: 65 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 7b 20  e     },.     { 
4480: 22 74 68 72 65 61 64 5f 77 61 69 74 22 2c 20 20  "thread_wait",  
4490: 20 20 20 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f       (Tcl_CmdPro
44a0: 63 2a 29 74 63 6c 5f 74 68 72 65 61 64 5f 77 61  c*)tcl_thread_wa
44b0: 69 74 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20  it       },.    
44c0: 20 7b 20 22 74 68 72 65 61 64 5f 68 61 6c 74 22   { "thread_halt"
44d0: 2c 20 20 20 20 20 20 20 28 54 63 6c 5f 43 6d 64  ,       (Tcl_Cmd
44e0: 50 72 6f 63 2a 29 74 63 6c 5f 74 68 72 65 61 64  Proc*)tcl_thread
44f0: 5f 68 61 6c 74 20 20 20 20 20 20 20 7d 2c 0a 20  _halt       },. 
4500: 20 20 20 20 7b 20 22 74 68 72 65 61 64 5f 61 72      { "thread_ar
4510: 67 63 22 2c 20 20 20 20 20 20 20 28 54 63 6c 5f  gc",       (Tcl_
4520: 43 6d 64 50 72 6f 63 2a 29 74 63 6c 5f 74 68 72  CmdProc*)tcl_thr
4530: 65 61 64 5f 61 72 67 63 20 20 20 20 20 20 20 7d  ead_argc       }
4540: 2c 0a 20 20 20 20 20 7b 20 22 74 68 72 65 61 64  ,.     { "thread
4550: 5f 61 72 67 76 22 2c 20 20 20 20 20 20 20 28 54  _argv",       (T
4560: 63 6c 5f 43 6d 64 50 72 6f 63 2a 29 74 63 6c 5f  cl_CmdProc*)tcl_
4570: 74 68 72 65 61 64 5f 61 72 67 76 20 20 20 20 20  thread_argv     
4580: 20 20 7d 2c 0a 20 20 20 20 20 7b 20 22 74 68 72    },.     { "thr
4590: 65 61 64 5f 63 6f 6c 6e 61 6d 65 22 2c 20 20 20  ead_colname",   
45a0: 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a 29 74   (Tcl_CmdProc*)t
45b0: 63 6c 5f 74 68 72 65 61 64 5f 63 6f 6c 6e 61 6d  cl_thread_colnam
45c0: 65 20 20 20 20 7d 2c 0a 20 20 20 20 20 7b 20 22  e    },.     { "
45d0: 74 68 72 65 61 64 5f 72 65 73 75 6c 74 22 2c 20  thread_result", 
45e0: 20 20 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63      (Tcl_CmdProc
45f0: 2a 29 74 63 6c 5f 74 68 72 65 61 64 5f 72 65 73  *)tcl_thread_res
4600: 75 6c 74 20 20 20 20 20 7d 2c 0a 20 20 20 20 20  ult     },.     
4610: 7b 20 22 74 68 72 65 61 64 5f 65 72 72 6f 72 22  { "thread_error"
4620: 2c 20 20 20 20 20 20 28 54 63 6c 5f 43 6d 64 50  ,      (Tcl_CmdP
4630: 72 6f 63 2a 29 74 63 6c 5f 74 68 72 65 61 64 5f  roc*)tcl_thread_
4640: 65 72 72 6f 72 20 20 20 20 20 20 7d 2c 0a 20 20  error      },.  
4650: 20 20 20 7b 20 22 74 68 72 65 61 64 5f 63 6f 6d     { "thread_com
4660: 70 69 6c 65 22 2c 20 20 20 20 28 54 63 6c 5f 43  pile",    (Tcl_C
4670: 6d 64 50 72 6f 63 2a 29 74 63 6c 5f 74 68 72 65  mdProc*)tcl_thre
4680: 61 64 5f 63 6f 6d 70 69 6c 65 20 20 20 20 7d 2c  ad_compile    },
4690: 0a 20 20 20 20 20 7b 20 22 74 68 72 65 61 64 5f  .     { "thread_
46a0: 73 74 65 70 22 2c 20 20 20 20 20 20 20 28 54 63  step",       (Tc
46b0: 6c 5f 43 6d 64 50 72 6f 63 2a 29 74 63 6c 5f 74  l_CmdProc*)tcl_t
46c0: 68 72 65 61 64 5f 73 74 65 70 20 20 20 20 20 20  hread_step      
46d0: 20 7d 2c 0a 20 20 20 20 20 7b 20 22 74 68 72 65   },.     { "thre
46e0: 61 64 5f 66 69 6e 61 6c 69 7a 65 22 2c 20 20 20  ad_finalize",   
46f0: 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a 29 74 63  (Tcl_CmdProc*)tc
4700: 6c 5f 74 68 72 65 61 64 5f 66 69 6e 61 6c 69 7a  l_thread_finaliz
4710: 65 20 20 20 7d 2c 0a 20 20 20 20 20 7b 20 22 74  e   },.     { "t
4720: 68 72 65 61 64 5f 73 77 61 70 22 2c 20 20 20 20  hread_swap",    
4730: 20 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a     (Tcl_CmdProc*
4740: 29 74 63 6c 5f 74 68 72 65 61 64 5f 73 77 61 70  )tcl_thread_swap
4750: 20 20 20 20 20 20 20 7d 2c 0a 20 20 7d 3b 0a 20         },.  };. 
4760: 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28 69   int i;..  for(i
4770: 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 43 6d  =0; i<sizeof(aCm
4780: 64 29 2f 73 69 7a 65 6f 66 28 61 43 6d 64 5b 30  d)/sizeof(aCmd[0
4790: 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63  ]); i++){.    Tc
47a0: 6c 5f 43 72 65 61 74 65 43 6f 6d 6d 61 6e 64 28  l_CreateCommand(
47b0: 69 6e 74 65 72 70 2c 20 61 43 6d 64 5b 69 5d 2e  interp, aCmd[i].
47c0: 7a 4e 61 6d 65 2c 20 61 43 6d 64 5b 69 5d 2e 78  zName, aCmd[i].x
47d0: 50 72 6f 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d  Proc, 0, 0);.  }
47e0: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
47f0: 3b 0a 7d 0a 23 65 6c 73 65 0a 69 6e 74 20 53 71  ;.}.#else.int Sq
4800: 6c 69 74 65 74 65 73 74 34 5f 49 6e 69 74 28 54  litetest4_Init(T
4810: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
4820: 70 29 7b 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  p){ return TCL_O
4830: 4b 3b 20 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 4f  K; }.#endif /* O
4840: 53 5f 55 4e 49 58 20 2a 2f 0a                    S_UNIX */.