/ Hex Artifact Content
Login

Artifact 6992f70cab8d5d8451a6b5641a9256d1749af87b:


0000: 2f 2a 0a 2a 2a 20 32 30 31 32 20 4a 75 6c 79 20  /*.** 2012 July 
0010: 32 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74  21.**.** The aut
0020: 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f  hor disclaims co
0030: 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20  pyright to this 
0040: 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e  source code.  In
0050: 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c   place of.** a l
0060: 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72  egal notice, her
0070: 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a  e is a blessing:
0080: 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f  .**.**    May yo
0090: 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f  u do good and no
00a0: 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61  t evil..**    Ma
00b0: 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69  y you find forgi
00c0: 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73  veness for yours
00d0: 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20  elf and forgive 
00e0: 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61  others..**    Ma
00f0: 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65  y you share free
0100: 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67  ly, never taking
0110: 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67   more than you g
0120: 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a  ive..**.********
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 2a 0a 2a 2a 0a 2a 2a 20 54 68 69  ******.**.** Thi
0180: 73 20 66 69 6c 65 20 70 72 65 73 65 6e 74 73 20  s file presents 
0190: 61 20 73 69 6d 70 6c 65 20 63 72 6f 73 73 2d 70  a simple cross-p
01a0: 6c 61 74 66 6f 72 6d 20 74 68 72 65 61 64 69 6e  latform threadin
01b0: 67 20 69 6e 74 65 72 66 61 63 65 20 66 6f 72 0a  g interface for.
01c0: 2a 2a 20 75 73 65 20 69 6e 74 65 72 6e 61 6c 6c  ** use internall
01d0: 79 20 62 79 20 53 51 4c 69 74 65 2e 0a 2a 2a 0a  y by SQLite..**.
01e0: 2a 2a 20 41 20 22 74 68 72 65 61 64 22 20 63 61  ** A "thread" ca
01f0: 6e 20 62 65 20 63 72 65 61 74 65 64 20 75 73 69  n be created usi
0200: 6e 67 20 73 71 6c 69 74 65 33 54 68 72 65 61 64  ng sqlite3Thread
0210: 43 72 65 61 74 65 28 29 2e 20 20 54 68 69 73 20  Create().  This 
0220: 74 68 72 65 61 64 0a 2a 2a 20 72 75 6e 73 20 69  thread.** runs i
0230: 6e 64 65 70 65 6e 64 65 6e 74 6c 79 20 6f 66 20  ndependently of 
0240: 69 74 73 20 63 72 65 61 74 6f 72 20 75 6e 74 69  its creator unti
0250: 6c 20 69 74 20 69 73 20 6a 6f 69 6e 65 64 20 75  l it is joined u
0260: 73 69 6e 67 0a 2a 2a 20 73 71 6c 69 74 65 33 54  sing.** sqlite3T
0270: 68 72 65 61 64 4a 6f 69 6e 28 29 2c 20 61 74 20  hreadJoin(), at 
0280: 77 68 69 63 68 20 70 6f 69 6e 74 20 69 74 20 74  which point it t
0290: 65 72 6d 69 6e 61 74 65 73 2e 0a 2a 2a 0a 2a 2a  erminates..**.**
02a0: 20 54 68 72 65 61 64 73 20 64 6f 20 6e 6f 74 20   Threads do not 
02b0: 68 61 76 65 20 74 6f 20 62 65 20 72 65 61 6c 2e  have to be real.
02c0: 20 20 49 74 20 63 6f 75 6c 64 20 62 65 20 74 68    It could be th
02d0: 61 74 20 74 68 65 20 77 6f 72 6b 20 6f 66 20 74  at the work of t
02e0: 68 65 0a 2a 2a 20 22 74 68 72 65 61 64 22 20 69  he.** "thread" i
02f0: 73 20 64 6f 6e 65 20 62 79 20 74 68 65 20 6d 61  s done by the ma
0300: 69 6e 20 74 68 72 65 61 64 20 61 74 20 65 69 74  in thread at eit
0310: 68 65 72 20 74 68 65 20 73 71 6c 69 74 65 33 54  her the sqlite3T
0320: 68 72 65 61 64 43 72 65 61 74 65 28 29 0a 2a 2a  hreadCreate().**
0330: 20 6f 72 20 73 71 6c 69 74 65 33 54 68 72 65 61   or sqlite3Threa
0340: 64 4a 6f 69 6e 28 29 20 63 61 6c 6c 2e 20 20 54  dJoin() call.  T
0350: 68 69 73 20 69 73 2c 20 69 6e 20 66 61 63 74 2c  his is, in fact,
0360: 20 77 68 61 74 20 68 61 70 70 65 6e 73 20 69 6e   what happens in
0370: 0a 2a 2a 20 73 69 6e 67 6c 65 20 74 68 72 65 61  .** single threa
0380: 64 65 64 20 73 79 73 74 65 6d 73 2e 20 20 4e 6f  ded systems.  No
0390: 74 68 69 6e 67 20 69 6e 20 53 51 4c 69 74 65 20  thing in SQLite 
03a0: 72 65 71 75 69 72 65 73 20 6d 75 6c 74 69 70 6c  requires multipl
03b0: 65 20 74 68 72 65 61 64 73 2e 0a 2a 2a 20 54 68  e threads..** Th
03c0: 69 73 20 69 6e 74 65 72 66 61 63 65 20 65 78 69  is interface exi
03d0: 73 74 73 20 73 6f 20 74 68 61 74 20 61 70 70 6c  sts so that appl
03e0: 69 63 61 74 69 6f 6e 73 20 74 68 61 74 20 77 61  ications that wa
03f0: 6e 74 20 74 6f 20 74 61 6b 65 20 61 64 76 61 6e  nt to take advan
0400: 74 61 67 65 0a 2a 2a 20 6f 66 20 6d 75 6c 74 69  tage.** of multi
0410: 70 6c 65 20 63 6f 72 65 73 20 63 61 6e 20 64 6f  ple cores can do
0420: 20 73 6f 2c 20 77 68 69 6c 65 20 61 6c 73 6f 20   so, while also 
0430: 61 6c 6c 6f 77 69 6e 67 20 61 70 70 6c 69 63 61  allowing applica
0440: 74 69 6f 6e 73 20 74 6f 20 73 74 61 79 0a 2a 2a  tions to stay.**
0450: 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64   single-threaded
0460: 20 69 66 20 64 65 73 69 72 65 64 2e 0a 2a 2f 0a   if desired..*/.
0470: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
0480: 49 6e 74 2e 68 22 0a 0a 23 69 66 20 53 51 4c 49  Int.h"..#if SQLI
0490: 54 45 5f 4d 41 58 5f 57 4f 52 4b 45 52 5f 54 48  TE_MAX_WORKER_TH
04a0: 52 45 41 44 53 3e 30 0a 0a 2f 2a 2a 2a 2a 2a 2a  READS>0../******
04b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
04c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 55 6e 69 78  *********** Unix
04d0: 20 50 74 68 72 65 61 64 73 20 2a 2a 2a 2a 2a 2a   Pthreads ******
04e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
04f0: 2a 2a 2a 2a 2a 2a 2f 0a 23 69 66 20 53 51 4c 49  ******/.#if SQLI
0500: 54 45 5f 4f 53 5f 55 4e 49 58 20 26 26 20 64 65  TE_OS_UNIX && de
0510: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 4d 55 54  fined(SQLITE_MUT
0520: 45 58 5f 50 54 48 52 45 41 44 53 29 20 26 26 20  EX_PTHREADS) && 
0530: 53 51 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46  SQLITE_THREADSAF
0540: 45 3e 30 0a 0a 23 64 65 66 69 6e 65 20 53 51 4c  E>0..#define SQL
0550: 49 54 45 5f 54 48 52 45 41 44 53 5f 49 4d 50 4c  ITE_THREADS_IMPL
0560: 45 4d 45 4e 54 45 44 20 31 20 20 2f 2a 20 50 72  EMENTED 1  /* Pr
0570: 65 76 65 6e 74 20 74 68 65 20 73 69 6e 67 6c 65  event the single
0580: 2d 74 68 72 65 61 64 20 63 6f 64 65 20 62 65 6c  -thread code bel
0590: 6f 77 20 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 3c  ow */.#include <
05a0: 70 74 68 72 65 61 64 2e 68 3e 0a 0a 2f 2a 20 41  pthread.h>../* A
05b0: 20 72 75 6e 6e 69 6e 67 20 74 68 72 65 61 64 20   running thread 
05c0: 2a 2f 0a 73 74 72 75 63 74 20 53 51 4c 69 74 65  */.struct SQLite
05d0: 54 68 72 65 61 64 20 7b 0a 20 20 70 74 68 72 65  Thread {.  pthre
05e0: 61 64 5f 74 20 74 69 64 3b 0a 20 20 69 6e 74 20  ad_t tid;.  int 
05f0: 64 6f 6e 65 3b 0a 20 20 76 6f 69 64 20 2a 70 4f  done;.  void *pO
0600: 75 74 3b 0a 7d 3b 0a 0a 2f 2a 20 43 72 65 61 74  ut;.};../* Creat
0610: 65 20 61 20 6e 65 77 20 74 68 72 65 61 64 20 2a  e a new thread *
0620: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 54 68 72  /.int sqlite3Thr
0630: 65 61 64 43 72 65 61 74 65 28 0a 20 20 53 51 4c  eadCreate(.  SQL
0640: 69 74 65 54 68 72 65 61 64 20 2a 2a 70 70 54 68  iteThread **ppTh
0650: 72 65 61 64 2c 20 20 2f 2a 20 4f 55 54 3a 20 57  read,  /* OUT: W
0660: 72 69 74 65 20 74 68 65 20 74 68 72 65 61 64 20  rite the thread 
0670: 6f 62 6a 65 63 74 20 68 65 72 65 20 2a 2f 0a 20  object here */. 
0680: 20 76 6f 69 64 20 2a 28 2a 78 54 61 73 6b 29 28   void *(*xTask)(
0690: 76 6f 69 64 2a 29 2c 20 20 20 20 2f 2a 20 52 6f  void*),    /* Ro
06a0: 75 74 69 6e 65 20 74 6f 20 72 75 6e 20 69 6e 20  utine to run in 
06b0: 61 20 73 65 70 61 72 61 74 65 20 74 68 72 65 61  a separate threa
06c0: 64 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 49 6e  d */.  void *pIn
06d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06e0: 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 70 61 73   /* Argument pas
06f0: 73 65 64 20 69 6e 74 6f 20 78 54 61 73 6b 28 29  sed into xTask()
0700: 20 2a 2f 0a 29 7b 0a 20 20 53 51 4c 69 74 65 54   */.){.  SQLiteT
0710: 68 72 65 61 64 20 2a 70 3b 0a 0a 20 20 61 73 73  hread *p;..  ass
0720: 65 72 74 28 20 70 70 54 68 72 65 61 64 21 3d 30  ert( ppThread!=0
0730: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 78 54   );.  assert( xT
0740: 61 73 6b 21 3d 30 20 29 3b 0a 20 20 2a 70 70 54  ask!=0 );.  *ppT
0750: 68 72 65 61 64 20 3d 20 30 3b 0a 20 20 70 20 3d  hread = 0;.  p =
0760: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 73   sqlite3Malloc(s
0770: 69 7a 65 6f 66 28 2a 70 29 29 3b 0a 20 20 69 66  izeof(*p));.  if
0780: 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ( p==0 ) return 
0790: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
07a0: 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a  memset(p, 0, siz
07b0: 65 6f 66 28 2a 70 29 29 3b 0a 20 20 69 66 28 20  eof(*p));.  if( 
07c0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
07d0: 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 3d 3d  fig.bCoreMutex==
07e0: 30 0a 20 20 20 20 7c 7c 20 70 74 68 72 65 61 64  0.    || pthread
07f0: 5f 63 72 65 61 74 65 28 26 70 2d 3e 74 69 64 2c  _create(&p->tid,
0800: 20 30 2c 20 78 54 61 73 6b 2c 20 70 49 6e 29 21   0, xTask, pIn)!
0810: 3d 30 20 0a 20 20 29 7b 0a 20 20 20 20 70 2d 3e  =0 .  ){.    p->
0820: 64 6f 6e 65 20 3d 20 31 3b 0a 20 20 20 20 70 2d  done = 1;.    p-
0830: 3e 70 4f 75 74 20 3d 20 78 54 61 73 6b 28 70 49  >pOut = xTask(pI
0840: 6e 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 54 68 72  n);.  }.  *ppThr
0850: 65 61 64 20 3d 20 70 3b 0a 20 20 72 65 74 75 72  ead = p;.  retur
0860: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
0870: 2f 2a 20 47 65 74 20 74 68 65 20 72 65 73 75 6c  /* Get the resul
0880: 74 73 20 6f 66 20 74 68 65 20 74 68 72 65 61 64  ts of the thread
0890: 20 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 54   */.int sqlite3T
08a0: 68 72 65 61 64 4a 6f 69 6e 28 53 51 4c 69 74 65  hreadJoin(SQLite
08b0: 54 68 72 65 61 64 20 2a 70 2c 20 76 6f 69 64 20  Thread *p, void 
08c0: 2a 2a 70 70 4f 75 74 29 7b 0a 20 20 69 6e 74 20  **ppOut){.  int 
08d0: 72 63 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  rc;..  assert( p
08e0: 70 4f 75 74 21 3d 30 20 29 3b 0a 20 20 69 66 28  pOut!=0 );.  if(
08f0: 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53   p==0 ) return S
0900: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 69  QLITE_NOMEM;.  i
0910: 66 28 20 70 2d 3e 64 6f 6e 65 20 29 7b 0a 20 20  f( p->done ){.  
0920: 20 20 2a 70 70 4f 75 74 20 3d 20 70 2d 3e 70 4f    *ppOut = p->pO
0930: 75 74 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c  ut;.    rc = SQL
0940: 49 54 45 5f 4f 4b 3b 0a 20 20 7d 65 6c 73 65 7b  ITE_OK;.  }else{
0950: 0a 20 20 20 20 72 63 20 3d 20 70 74 68 72 65 61  .    rc = pthrea
0960: 64 5f 6a 6f 69 6e 28 70 2d 3e 74 69 64 2c 20 70  d_join(p->tid, p
0970: 70 4f 75 74 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  pOut);.  }.  sql
0980: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
0990: 72 65 74 75 72 6e 20 72 63 20 3f 20 53 51 4c 49  return rc ? SQLI
09a0: 54 45 5f 45 52 52 4f 52 20 3a 20 53 51 4c 49 54  TE_ERROR : SQLIT
09b0: 45 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20  E_OK;.}..#endif 
09c0: 2f 2a 20 53 51 4c 49 54 45 5f 4f 53 5f 55 4e 49  /* SQLITE_OS_UNI
09d0: 58 20 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c  X && defined(SQL
09e0: 49 54 45 5f 4d 55 54 45 58 5f 50 54 48 52 45 41  ITE_MUTEX_PTHREA
09f0: 44 53 29 20 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  DS) */./********
0a00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0a10: 2a 2a 2a 2a 2a 2a 2a 2a 20 45 6e 64 20 55 6e 69  ******** End Uni
0a20: 78 20 50 74 68 72 65 61 64 73 20 2a 2a 2a 2a 2a  x Pthreads *****
0a30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0a40: 2a 2a 2a 2a 2f 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  ****/.../*******
0a50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0a60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 57 69 6e 33 32  ********** Win32
0a70: 20 54 68 72 65 61 64 73 20 2a 2a 2a 2a 2a 2a 2a   Threads *******
0a80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0a90: 2a 2a 2a 2a 2a 2f 0a 23 69 66 20 53 51 4c 49 54  *****/.#if SQLIT
0aa0: 45 5f 4f 53 5f 57 49 4e 20 26 26 20 21 53 51 4c  E_OS_WIN && !SQL
0ab0: 49 54 45 5f 4f 53 5f 57 49 4e 52 54 20 26 26 20  ITE_OS_WINRT && 
0ac0: 53 51 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46  SQLITE_THREADSAF
0ad0: 45 3e 30 0a 0a 23 64 65 66 69 6e 65 20 53 51 4c  E>0..#define SQL
0ae0: 49 54 45 5f 54 48 52 45 41 44 53 5f 49 4d 50 4c  ITE_THREADS_IMPL
0af0: 45 4d 45 4e 54 45 44 20 31 20 20 2f 2a 20 50 72  EMENTED 1  /* Pr
0b00: 65 76 65 6e 74 20 74 68 65 20 73 69 6e 67 6c 65  event the single
0b10: 2d 74 68 72 65 61 64 20 63 6f 64 65 20 62 65 6c  -thread code bel
0b20: 6f 77 20 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 3c  ow */.#include <
0b30: 70 72 6f 63 65 73 73 2e 68 3e 0a 0a 2f 2a 20 41  process.h>../* A
0b40: 20 72 75 6e 6e 69 6e 67 20 74 68 72 65 61 64 20   running thread 
0b50: 2a 2f 0a 73 74 72 75 63 74 20 53 51 4c 69 74 65  */.struct SQLite
0b60: 54 68 72 65 61 64 20 7b 0a 20 20 75 69 6e 74 70  Thread {.  uintp
0b70: 74 72 5f 74 20 74 69 64 3b 20 20 20 20 20 20 20  tr_t tid;       
0b80: 20 20 20 20 2f 2a 20 54 68 65 20 74 68 72 65 61      /* The threa
0b90: 64 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 76 6f  d handle */.  vo
0ba0: 69 64 20 2a 28 2a 78 54 61 73 6b 29 28 76 6f 69  id *(*xTask)(voi
0bb0: 64 2a 29 3b 20 20 20 2f 2a 20 54 68 65 20 72 6f  d*);   /* The ro
0bc0: 75 74 69 6e 65 20 74 6f 20 72 75 6e 20 61 73 20  utine to run as 
0bd0: 61 20 74 68 72 65 61 64 20 2a 2f 0a 20 20 76 6f  a thread */.  vo
0be0: 69 64 20 2a 70 49 6e 3b 20 20 20 20 20 20 20 20  id *pIn;        
0bf0: 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65         /* Argume
0c00: 6e 74 20 74 6f 20 78 54 61 73 6b 20 2a 2f 0a 20  nt to xTask */. 
0c10: 20 76 6f 69 64 20 2a 70 52 65 73 75 6c 74 3b 20   void *pResult; 
0c20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73            /* Res
0c30: 75 6c 74 20 6f 66 20 78 54 61 73 6b 20 2a 2f 0a  ult of xTask */.
0c40: 7d 3b 0a 0a 2f 2a 20 54 68 72 65 61 64 20 70 72  };../* Thread pr
0c50: 6f 63 65 64 75 72 65 20 57 69 6e 33 32 20 63 6f  ocedure Win32 co
0c60: 6d 70 61 74 69 62 69 6c 69 74 79 20 73 68 69 6d  mpatibility shim
0c70: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
0c80: 73 71 6c 69 74 65 33 54 68 72 65 61 64 50 72 6f  sqlite3ThreadPro
0c90: 63 28 0a 20 20 76 6f 69 64 20 2a 70 41 72 67 20  c(.  void *pArg 
0ca0: 20 2f 2a 20 49 4e 3a 20 50 6f 69 6e 74 65 72 20   /* IN: Pointer 
0cb0: 74 6f 20 74 68 65 20 53 51 4c 69 74 65 54 68 72  to the SQLiteThr
0cc0: 65 61 64 20 73 74 72 75 63 74 75 72 65 20 2a 2f  ead structure */
0cd0: 0a 29 7b 0a 20 20 53 51 4c 69 74 65 54 68 72 65  .){.  SQLiteThre
0ce0: 61 64 20 2a 70 20 3d 20 28 53 51 4c 69 74 65 54  ad *p = (SQLiteT
0cf0: 68 72 65 61 64 20 2a 29 70 41 72 67 3b 0a 0a 20  hread *)pArg;.. 
0d00: 20 61 73 73 65 72 74 28 20 70 21 3d 30 20 29 3b   assert( p!=0 );
0d10: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 78 54  .  assert( p->xT
0d20: 61 73 6b 21 3d 30 20 29 3b 0a 20 20 70 2d 3e 70  ask!=0 );.  p->p
0d30: 52 65 73 75 6c 74 20 3d 20 70 2d 3e 78 54 61 73  Result = p->xTas
0d40: 6b 28 70 2d 3e 70 49 6e 29 3b 0a 20 20 5f 65 6e  k(p->pIn);.  _en
0d50: 64 74 68 72 65 61 64 28 29 3b 0a 7d 0a 0a 2f 2a  dthread();.}../*
0d60: 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 74 68   Create a new th
0d70: 72 65 61 64 20 2a 2f 0a 69 6e 74 20 73 71 6c 69  read */.int sqli
0d80: 74 65 33 54 68 72 65 61 64 43 72 65 61 74 65 28  te3ThreadCreate(
0d90: 0a 20 20 53 51 4c 69 74 65 54 68 72 65 61 64 20  .  SQLiteThread 
0da0: 2a 2a 70 70 54 68 72 65 61 64 2c 20 20 2f 2a 20  **ppThread,  /* 
0db0: 4f 55 54 3a 20 57 72 69 74 65 20 74 68 65 20 74  OUT: Write the t
0dc0: 68 72 65 61 64 20 6f 62 6a 65 63 74 20 68 65 72  hread object her
0dd0: 65 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 28 2a 78  e */.  void *(*x
0de0: 54 61 73 6b 29 28 76 6f 69 64 2a 29 2c 20 20 20  Task)(void*),   
0df0: 20 2f 2a 20 52 6f 75 74 69 6e 65 20 74 6f 20 72   /* Routine to r
0e00: 75 6e 20 69 6e 20 61 20 73 65 70 61 72 61 74 65  un in a separate
0e10: 20 74 68 72 65 61 64 20 2a 2f 0a 20 20 76 6f 69   thread */.  voi
0e20: 64 20 2a 70 49 6e 20 20 20 20 20 20 20 20 20 20  d *pIn          
0e30: 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65         /* Argume
0e40: 6e 74 20 70 61 73 73 65 64 20 69 6e 74 6f 20 78  nt passed into x
0e50: 54 61 73 6b 28 29 20 2a 2f 0a 29 7b 0a 20 20 53  Task() */.){.  S
0e60: 51 4c 69 74 65 54 68 72 65 61 64 20 2a 70 3b 0a  QLiteThread *p;.
0e70: 0a 20 20 61 73 73 65 72 74 28 20 70 70 54 68 72  .  assert( ppThr
0e80: 65 61 64 21 3d 30 20 29 3b 0a 20 20 61 73 73 65  ead!=0 );.  asse
0e90: 72 74 28 20 78 54 61 73 6b 21 3d 30 20 29 3b 0a  rt( xTask!=0 );.
0ea0: 20 20 2a 70 70 54 68 72 65 61 64 20 3d 20 30 3b    *ppThread = 0;
0eb0: 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4d 61  .  p = sqlite3Ma
0ec0: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 70 29 29  lloc(sizeof(*p))
0ed0: 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 20 72  ;.  if( p==0 ) r
0ee0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
0ef0: 45 4d 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65  EM;.  if( sqlite
0f00: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43  3GlobalConfig.bC
0f10: 6f 72 65 4d 75 74 65 78 3d 3d 30 20 29 7b 0a 20  oreMutex==0 ){. 
0f20: 20 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20     memset(p, 0, 
0f30: 73 69 7a 65 6f 66 28 2a 70 29 29 3b 0a 20 20 7d  sizeof(*p));.  }
0f40: 65 6c 73 65 7b 0a 20 20 20 20 70 2d 3e 78 54 61  else{.    p->xTa
0f50: 73 6b 20 3d 20 78 54 61 73 6b 3b 0a 20 20 20 20  sk = xTask;.    
0f60: 70 2d 3e 70 49 6e 20 3d 20 70 49 6e 3b 0a 20 20  p->pIn = pIn;.  
0f70: 20 20 70 2d 3e 74 69 64 20 3d 20 5f 62 65 67 69    p->tid = _begi
0f80: 6e 74 68 72 65 61 64 28 73 71 6c 69 74 65 33 54  nthread(sqlite3T
0f90: 68 72 65 61 64 50 72 6f 63 2c 20 30 2c 20 70 29  hreadProc, 0, p)
0fa0: 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 74 69 64  ;.    if( p->tid
0fb0: 3d 3d 28 75 69 6e 74 70 74 72 5f 74 29 2d 31 20  ==(uintptr_t)-1 
0fc0: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28  ){.      memset(
0fd0: 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 70 29  p, 0, sizeof(*p)
0fe0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  );.    }.  }.  i
0ff0: 66 28 20 70 2d 3e 78 54 61 73 6b 3d 3d 30 20 29  f( p->xTask==0 )
1000: 7b 0a 20 20 20 20 70 2d 3e 70 52 65 73 75 6c 74  {.    p->pResult
1010: 20 3d 20 78 54 61 73 6b 28 70 49 6e 29 3b 0a 20   = xTask(pIn);. 
1020: 20 7d 0a 20 20 2a 70 70 54 68 72 65 61 64 20 3d   }.  *ppThread =
1030: 20 70 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   p;.  return SQL
1040: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 47 65  ITE_OK;.}../* Ge
1050: 74 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66  t the results of
1060: 20 74 68 65 20 74 68 72 65 61 64 20 2a 2f 0a 69   the thread */.i
1070: 6e 74 20 73 71 6c 69 74 65 33 54 68 72 65 61 64  nt sqlite3Thread
1080: 4a 6f 69 6e 28 53 51 4c 69 74 65 54 68 72 65 61  Join(SQLiteThrea
1090: 64 20 2a 70 2c 20 76 6f 69 64 20 2a 2a 70 70 4f  d *p, void **ppO
10a0: 75 74 29 7b 0a 20 20 44 57 4f 52 44 20 72 63 3b  ut){.  DWORD rc;
10b0: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 70 4f 75  ..  assert( ppOu
10c0: 74 21 3d 30 20 29 3b 0a 20 20 69 66 28 20 70 3d  t!=0 );.  if( p=
10d0: 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
10e0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 69 66 28 20  TE_NOMEM;.  if( 
10f0: 70 2d 3e 78 54 61 73 6b 3d 3d 30 20 29 7b 0a 20  p->xTask==0 ){. 
1100: 20 20 20 72 63 20 3d 20 57 41 49 54 5f 4f 42 4a     rc = WAIT_OBJ
1110: 45 43 54 5f 4f 3b 0a 20 20 7d 65 6c 73 65 7b 0a  ECT_O;.  }else{.
1120: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1130: 57 69 6e 33 32 57 61 69 74 28 28 48 41 4e 44 4c  Win32Wait((HANDL
1140: 45 29 70 2d 3e 74 69 64 29 3b 0a 20 20 20 20 61  E)p->tid);.    a
1150: 73 73 65 72 74 28 20 72 63 21 3d 57 41 49 54 5f  ssert( rc!=WAIT_
1160: 49 4f 5f 43 4f 4d 50 4c 45 54 49 4f 4e 20 29 3b  IO_COMPLETION );
1170: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 57  .  }.  if( rc==W
1180: 41 49 54 5f 4f 42 4a 45 43 54 5f 30 20 29 20 2a  AIT_OBJECT_0 ) *
1190: 70 70 4f 75 74 20 3d 20 70 2d 3e 70 52 65 73 75  ppOut = p->pResu
11a0: 6c 74 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  lt;.  sqlite3_fr
11b0: 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 20  ee(p);.  return 
11c0: 28 72 63 3d 3d 57 41 49 54 5f 4f 42 4a 45 43 54  (rc==WAIT_OBJECT
11d0: 5f 30 29 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20  _0) ? SQLITE_OK 
11e0: 3a 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  : SQLITE_ERROR;.
11f0: 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c  }..#endif /* SQL
1200: 49 54 45 5f 4f 53 5f 57 49 4e 20 26 26 20 21 53  ITE_OS_WIN && !S
1210: 51 4c 49 54 45 5f 4f 53 5f 57 49 4e 52 54 20 2a  QLITE_OS_WINRT *
1220: 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /./*************
1230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1240: 2a 2a 2a 20 45 6e 64 20 57 69 6e 33 32 20 54 68  *** End Win32 Th
1250: 72 65 61 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  reads **********
1260: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
1270: 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .../************
1280: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1290: 2a 2a 2a 2a 2a 20 53 69 6e 67 6c 65 2d 54 68 72  ***** Single-Thr
12a0: 65 61 64 65 64 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  eaded **********
12b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
12c0: 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  /.#ifndef SQLITE
12d0: 5f 54 48 52 45 41 44 53 5f 49 4d 50 4c 45 4d 45  _THREADS_IMPLEME
12e0: 4e 54 45 44 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  NTED./*.** This 
12f0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 64  implementation d
1300: 6f 65 73 20 6e 6f 74 20 61 63 74 75 61 6c 6c 79  oes not actually
1310: 20 63 72 65 61 74 65 20 61 20 6e 65 77 20 74 68   create a new th
1320: 72 65 61 64 2e 20 20 49 74 20 64 6f 65 73 20 74  read.  It does t
1330: 68 65 0a 2a 2a 20 77 6f 72 6b 20 6f 66 20 74 68  he.** work of th
1340: 65 20 74 68 72 65 61 64 20 69 6e 20 74 68 65 20  e thread in the 
1350: 6d 61 69 6e 20 74 68 72 65 61 64 2c 20 77 68 65  main thread, whe
1360: 6e 20 65 69 74 68 65 72 20 74 68 65 20 74 68 72  n either the thr
1370: 65 61 64 20 69 73 20 63 72 65 61 74 65 64 0a 2a  ead is created.*
1380: 2a 20 6f 72 20 77 68 65 6e 20 69 74 20 69 73 20  * or when it is 
1390: 6a 6f 69 6e 65 64 0a 2a 2f 0a 0a 2f 2a 20 41 20  joined.*/../* A 
13a0: 72 75 6e 6e 69 6e 67 20 74 68 72 65 61 64 20 2a  running thread *
13b0: 2f 0a 73 74 72 75 63 74 20 53 51 4c 69 74 65 54  /.struct SQLiteT
13c0: 68 72 65 61 64 20 7b 0a 20 20 76 6f 69 64 20 2a  hread {.  void *
13d0: 28 2a 78 54 61 73 6b 29 28 76 6f 69 64 2a 29 3b  (*xTask)(void*);
13e0: 20 20 20 2f 2a 20 54 68 65 20 72 6f 75 74 69 6e     /* The routin
13f0: 65 20 74 6f 20 72 75 6e 20 61 73 20 61 20 74 68  e to run as a th
1400: 72 65 61 64 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  read */.  void *
1410: 70 49 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20  pIn;            
1420: 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 74     /* Argument t
1430: 6f 20 78 54 61 73 6b 20 2a 2f 0a 20 20 76 6f 69  o xTask */.  voi
1440: 64 20 2a 70 52 65 73 75 6c 74 3b 20 20 20 20 20  d *pResult;     
1450: 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20        /* Result 
1460: 6f 66 20 78 54 61 73 6b 20 2a 2f 0a 7d 3b 0a 0a  of xTask */.};..
1470: 2f 2a 20 43 72 65 61 74 65 20 61 20 6e 65 77 20  /* Create a new 
1480: 74 68 72 65 61 64 20 2a 2f 0a 69 6e 74 20 73 71  thread */.int sq
1490: 6c 69 74 65 33 54 68 72 65 61 64 43 72 65 61 74  lite3ThreadCreat
14a0: 65 28 0a 20 20 53 51 4c 69 74 65 54 68 72 65 61  e(.  SQLiteThrea
14b0: 64 20 2a 2a 70 70 54 68 72 65 61 64 2c 20 20 2f  d **ppThread,  /
14c0: 2a 20 4f 55 54 3a 20 57 72 69 74 65 20 74 68 65  * OUT: Write the
14d0: 20 74 68 72 65 61 64 20 6f 62 6a 65 63 74 20 68   thread object h
14e0: 65 72 65 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 28  ere */.  void *(
14f0: 2a 78 54 61 73 6b 29 28 76 6f 69 64 2a 29 2c 20  *xTask)(void*), 
1500: 20 20 20 2f 2a 20 52 6f 75 74 69 6e 65 20 74 6f     /* Routine to
1510: 20 72 75 6e 20 69 6e 20 61 20 73 65 70 61 72 61   run in a separa
1520: 74 65 20 74 68 72 65 61 64 20 2a 2f 0a 20 20 76  te thread */.  v
1530: 6f 69 64 20 2a 70 49 6e 20 20 20 20 20 20 20 20  oid *pIn        
1540: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75           /* Argu
1550: 6d 65 6e 74 20 70 61 73 73 65 64 20 69 6e 74 6f  ment passed into
1560: 20 78 54 61 73 6b 28 29 20 2a 2f 0a 29 7b 0a 20   xTask() */.){. 
1570: 20 53 51 4c 69 74 65 54 68 72 65 61 64 20 2a 70   SQLiteThread *p
1580: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 70 54  ;..  assert( ppT
1590: 68 72 65 61 64 21 3d 30 20 29 3b 0a 20 20 61 73  hread!=0 );.  as
15a0: 73 65 72 74 28 20 78 54 61 73 6b 21 3d 30 20 29  sert( xTask!=0 )
15b0: 3b 0a 20 20 2a 70 70 54 68 72 65 61 64 20 3d 20  ;.  *ppThread = 
15c0: 30 3b 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33  0;.  p = sqlite3
15d0: 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 70  Malloc(sizeof(*p
15e0: 29 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29  ));.  if( p==0 )
15f0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
1600: 4f 4d 45 4d 3b 0a 20 20 69 66 28 20 28 53 51 4c  OMEM;.  if( (SQL
1610: 49 54 45 5f 50 54 52 5f 54 4f 5f 49 4e 54 28 70  ITE_PTR_TO_INT(p
1620: 29 2f 31 37 29 26 31 20 29 7b 0a 20 20 20 20 70  )/17)&1 ){.    p
1630: 2d 3e 78 54 61 73 6b 20 3d 20 78 54 61 73 6b 3b  ->xTask = xTask;
1640: 0a 20 20 20 20 70 2d 3e 70 49 6e 20 3d 20 70 49  .    p->pIn = pI
1650: 6e 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  n;.  }else{.    
1660: 70 2d 3e 78 54 61 73 6b 20 3d 20 30 3b 0a 20 20  p->xTask = 0;.  
1670: 20 20 70 2d 3e 70 52 65 73 75 6c 74 20 3d 20 78    p->pResult = x
1680: 54 61 73 6b 28 70 49 6e 29 3b 0a 20 20 7d 0a 20  Task(pIn);.  }. 
1690: 20 2a 70 70 54 68 72 65 61 64 20 3d 20 70 3b 0a   *ppThread = p;.
16a0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
16b0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20 74 68  OK;.}../* Get th
16c0: 65 20 72 65 73 75 6c 74 73 20 6f 66 20 74 68 65  e results of the
16d0: 20 74 68 72 65 61 64 20 2a 2f 0a 69 6e 74 20 73   thread */.int s
16e0: 71 6c 69 74 65 33 54 68 72 65 61 64 4a 6f 69 6e  qlite3ThreadJoin
16f0: 28 53 51 4c 69 74 65 54 68 72 65 61 64 20 2a 70  (SQLiteThread *p
1700: 2c 20 76 6f 69 64 20 2a 2a 70 70 4f 75 74 29 7b  , void **ppOut){
1710: 0a 20 20 61 73 73 65 72 74 28 20 70 70 4f 75 74  .  assert( ppOut
1720: 21 3d 30 20 29 3b 0a 20 20 69 66 28 20 70 3d 3d  !=0 );.  if( p==
1730: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
1740: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 69 66 28 20 70  E_NOMEM;.  if( p
1750: 2d 3e 78 54 61 73 6b 20 29 7b 0a 20 20 20 20 2a  ->xTask ){.    *
1760: 70 70 4f 75 74 20 3d 20 70 2d 3e 78 54 61 73 6b  ppOut = p->xTask
1770: 28 70 2d 3e 70 49 6e 29 3b 0a 20 20 7d 65 6c 73  (p->pIn);.  }els
1780: 65 7b 0a 20 20 20 20 2a 70 70 4f 75 74 20 3d 20  e{.    *ppOut = 
1790: 70 2d 3e 70 52 65 73 75 6c 74 3b 0a 20 20 7d 0a  p->pResult;.  }.
17a0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
17b0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
17c0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66  TE_OK;.}..#endif
17d0: 20 2f 2a 20 21 64 65 66 69 6e 65 64 28 53 51 4c   /* !defined(SQL
17e0: 49 54 45 5f 54 48 52 45 41 44 53 5f 49 4d 50 4c  ITE_THREADS_IMPL
17f0: 45 4d 45 4e 54 45 44 29 20 2a 2f 0a 2f 2a 2a 2a  EMENTED) */./***
1800: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1810: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 45 6e 64 20  *********** End 
1820: 53 69 6e 67 6c 65 2d 54 68 72 65 61 64 65 64 20  Single-Threaded 
1830: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1840: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 23 65 6e 64 69  *********/.#endi
1850: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f  f /* SQLITE_MAX_
1860: 57 4f 52 4b 45 52 5f 54 48 52 45 41 44 53 3e 30  WORKER_THREADS>0
1870: 20 2a 2f 0a                                       */.