/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact 326fc8dcced899473fca2d877a05e446c1c92fef:


0000: 2f 2a 0a 2a 2a 20 32 30 30 35 20 44 65 63 65 6d  /*.** 2005 Decem
0010: 62 65 72 20 31 34 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 14.**.** 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 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61   file contains a
0190: 6e 20 65 78 61 6d 70 6c 65 20 69 6d 70 6c 65 6d  n example implem
01a0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 61 6e 20 61  entation of an a
01b0: 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49 4f 20 0a  synchronous IO .
01c0: 2a 2a 20 62 61 63 6b 65 6e 64 20 66 6f 72 20 53  ** backend for S
01d0: 51 4c 69 74 65 2e 0a 2a 2a 0a 2a 2a 20 57 48 41  QLite..**.** WHA
01e0: 54 20 49 53 20 41 53 59 4e 43 48 52 4f 4e 4f 55  T IS ASYNCHRONOU
01f0: 53 20 49 2f 4f 3f 0a 2a 2a 0a 2a 2a 20 57 69 74  S I/O?.**.** Wit
0200: 68 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49  h asynchronous I
0210: 2f 4f 2c 20 77 72 69 74 65 20 72 65 71 75 65 73  /O, write reques
0220: 74 73 20 61 72 65 20 68 61 6e 64 6c 65 64 20 62  ts are handled b
0230: 79 20 61 20 73 65 70 61 72 61 74 65 20 74 68 72  y a separate thr
0240: 65 61 64 0a 2a 2a 20 72 75 6e 6e 69 6e 67 20 69  ead.** running i
0250: 6e 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e 64  n the background
0260: 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68  .  This means th
0270: 61 74 20 74 68 65 20 74 68 72 65 61 64 20 74 68  at the thread th
0280: 61 74 20 69 6e 69 74 69 61 74 65 73 0a 2a 2a 20  at initiates.** 
0290: 61 20 64 61 74 61 62 61 73 65 20 77 72 69 74 65  a database write
02a0: 20 64 6f 65 73 20 6e 6f 74 20 68 61 76 65 20 74   does not have t
02b0: 6f 20 77 61 69 74 20 66 6f 72 20 28 73 6f 6d 65  o wait for (some
02c0: 74 69 6d 65 73 20 73 6c 6f 77 29 20 64 69 73 6b  times slow) disk
02d0: 20 49 2f 4f 0a 2a 2a 20 74 6f 20 6f 63 63 75 72   I/O.** to occur
02e0: 2e 20 20 54 68 65 20 77 72 69 74 65 20 73 65 65  .  The write see
02f0: 6d 73 20 74 6f 20 68 61 70 70 65 6e 20 76 65 72  ms to happen ver
0300: 79 20 71 75 69 63 6b 6c 79 2c 20 74 68 6f 75 67  y quickly, thoug
0310: 68 20 69 6e 20 72 65 61 6c 69 74 79 0a 2a 2a 20  h in reality.** 
0320: 69 74 20 69 73 20 68 61 70 70 65 6e 69 6e 67 20  it is happening 
0330: 61 74 20 69 74 73 20 75 73 75 61 6c 20 73 6c 6f  at its usual slo
0340: 77 20 70 61 63 65 20 69 6e 20 74 68 65 20 62 61  w pace in the ba
0350: 63 6b 67 72 6f 75 6e 64 2e 0a 2a 2a 0a 2a 2a 20  ckground..**.** 
0360: 41 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49 2f 4f  Asynchronous I/O
0370: 20 61 70 70 65 61 72 73 20 74 6f 20 67 69 76 65   appears to give
0380: 20 62 65 74 74 65 72 20 72 65 73 70 6f 6e 73 69   better responsi
0390: 76 65 6e 65 73 73 2c 20 62 75 74 20 61 74 20 61  veness, but at a
03a0: 20 70 72 69 63 65 2e 0a 2a 2a 20 59 6f 75 20 6c   price..** You l
03b0: 6f 73 65 20 74 68 65 20 44 75 72 61 62 6c 65 20  ose the Durable 
03c0: 70 72 6f 70 65 72 74 79 2e 20 20 57 69 74 68 20  property.  With 
03d0: 74 68 65 20 64 65 66 61 75 6c 74 20 49 2f 4f 20  the default I/O 
03e0: 62 61 63 6b 65 6e 64 20 6f 66 20 53 51 4c 69 74  backend of SQLit
03f0: 65 2c 0a 2a 2a 20 6f 6e 63 65 20 61 20 77 72 69  e,.** once a wri
0400: 74 65 20 63 6f 6d 70 6c 65 74 65 73 2c 20 79 6f  te completes, yo
0410: 75 20 6b 6e 6f 77 20 74 68 61 74 20 74 68 65 20  u know that the 
0420: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 79 6f 75 20  information you 
0430: 77 72 6f 74 65 20 69 73 0a 2a 2a 20 73 61 66 65  wrote is.** safe
0440: 6c 79 20 6f 6e 20 64 69 73 6b 2e 20 20 57 69 74  ly on disk.  Wit
0450: 68 20 74 68 65 20 61 73 79 6e 63 68 72 6f 6e 6f  h the asynchrono
0460: 75 73 20 49 2f 4f 2c 20 74 68 69 73 20 69 73 20  us I/O, this is 
0470: 6e 6f 20 74 68 65 20 63 61 73 65 2e 20 20 49 66  no the case.  If
0480: 0a 2a 2a 20 79 6f 75 72 20 70 72 6f 67 72 61 6d  .** your program
0490: 20 63 72 61 73 68 65 73 20 6f 72 20 69 66 20 79   crashes or if y
04a0: 6f 75 20 74 61 6b 65 20 61 20 70 6f 77 65 72 20  ou take a power 
04b0: 6c 6f 73 65 20 61 66 74 65 72 20 74 68 65 20 64  lose after the d
04c0: 61 74 61 62 61 73 65 0a 2a 2a 20 77 72 69 74 65  atabase.** write
04d0: 20 62 75 74 20 62 65 66 6f 72 65 20 74 68 65 20   but before the 
04e0: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 77 72 69  asynchronous wri
04f0: 74 65 20 74 68 72 65 61 64 20 68 61 73 20 63 6f  te thread has co
0500: 6d 70 6c 65 74 65 64 2c 20 74 68 65 6e 20 74 68  mpleted, then th
0510: 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20 63 68  e.** database ch
0520: 61 6e 67 65 20 6d 69 67 68 74 20 6e 65 76 65 72  ange might never
0530: 20 6d 61 6b 65 20 69 74 20 74 6f 20 64 69 73 6b   make it to disk
0540: 20 61 6e 64 20 74 68 65 20 6e 65 78 74 20 75 73   and the next us
0550: 65 72 20 6f 66 20 74 68 65 0a 2a 2a 20 64 61 74  er of the.** dat
0560: 61 62 61 73 65 20 6d 69 67 68 74 20 6e 6f 74 20  abase might not 
0570: 73 65 65 20 79 6f 75 72 20 63 68 61 6e 67 65 2e  see your change.
0580: 0a 2a 2a 0a 2a 2a 20 59 6f 75 20 6c 6f 73 65 20  .**.** You lose 
0590: 44 75 72 61 62 69 6c 69 74 79 20 77 69 74 68 20  Durability with 
05a0: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49 2f 4f  asynchronous I/O
05b0: 2c 20 62 75 74 20 79 6f 75 20 73 74 69 6c 6c 20  , but you still 
05c0: 72 65 74 61 69 6e 20 74 68 65 0a 2a 2a 20 6f 74  retain the.** ot
05d0: 68 65 72 20 70 61 72 74 73 20 6f 66 20 41 43 49  her parts of ACI
05e0: 44 3a 20 20 41 74 6f 6d 69 63 2c 20 20 43 6f 6e  D:  Atomic,  Con
05f0: 73 69 73 74 65 6e 74 2c 20 61 6e 64 20 49 73 6f  sistent, and Iso
0600: 6c 61 74 65 64 2e 20 20 4d 61 6e 79 0a 2a 2a 20  lated.  Many.** 
0610: 61 70 70 6c 69 61 74 69 6f 6e 73 20 67 65 74 20  appliations get 
0620: 61 6c 6f 6e 67 20 66 69 6e 65 20 77 69 74 68 6f  along fine witho
0630: 75 74 20 74 68 65 20 44 75 72 61 62 6c 69 74 79  ut the Durablity
0640: 2e 0a 2a 2a 0a 2a 2a 20 48 4f 57 20 49 54 20 57  ..**.** HOW IT W
0650: 4f 52 4b 53 0a 2a 2a 0a 2a 2a 20 41 73 79 6e 63  ORKS.**.** Async
0660: 68 72 6f 6e 6f 75 73 20 49 2f 4f 20 77 6f 72 6b  hronous I/O work
0670: 73 20 62 79 20 6f 76 65 72 6c 6f 61 64 69 6e 67  s by overloading
0680: 20 74 68 65 20 4f 53 2d 6c 61 79 65 72 20 64 69   the OS-layer di
0690: 73 6b 20 49 2f 4f 20 72 6f 75 74 69 6e 65 73 0a  sk I/O routines.
06a0: 2a 2a 20 77 69 74 68 20 6d 6f 64 69 66 69 65 64  ** with modified
06b0: 20 76 65 72 73 69 6f 6e 73 20 74 68 61 74 20 73   versions that s
06c0: 74 6f 72 65 20 74 68 65 20 64 61 74 61 20 74 6f  tore the data to
06d0: 20 62 65 20 77 72 69 74 74 65 6e 20 69 6e 20 71   be written in q
06e0: 75 65 75 65 20 6f 66 0a 2a 2a 20 70 65 6e 64 69  ueue of.** pendi
06f0: 6e 67 20 77 72 69 74 65 20 6f 70 65 72 61 74 69  ng write operati
0700: 6f 6e 73 2e 20 20 4c 6f 6f 6b 20 61 74 20 74 68  ons.  Look at th
0710: 65 20 61 73 79 6e 63 45 6e 61 62 6c 65 28 29 20  e asyncEnable() 
0720: 73 75 62 72 6f 75 74 69 6e 65 20 74 6f 20 73 65  subroutine to se
0730: 65 0a 2a 2a 20 68 6f 77 20 6f 76 65 72 6c 6f 61  e.** how overloa
0740: 64 69 6e 67 20 77 6f 72 6b 73 2e 20 20 53 69 78  ding works.  Six
0750: 20 6f 73 2d 6c 61 79 65 72 20 72 6f 75 74 69 6e   os-layer routin
0760: 65 73 20 61 72 65 20 6f 76 65 72 6c 6f 61 64 65  es are overloade
0770: 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 73 71 6c  d:.**.**     sql
0780: 69 74 65 33 4f 73 4f 70 65 6e 52 65 61 64 57 72  ite3OsOpenReadWr
0790: 69 74 65 3b 0a 2a 2a 20 20 20 20 20 73 71 6c 69  ite;.**     sqli
07a0: 74 65 33 4f 73 4f 70 65 6e 52 65 61 64 4f 6e 6c  te3OsOpenReadOnl
07b0: 79 3b 0a 2a 2a 20 20 20 20 20 73 71 6c 69 74 65  y;.**     sqlite
07c0: 33 4f 73 4f 70 65 6e 45 78 63 6c 75 73 69 76 65  3OsOpenExclusive
07d0: 3b 0a 2a 2a 20 20 20 20 20 73 71 6c 69 74 65 33  ;.**     sqlite3
07e0: 4f 73 44 65 6c 65 74 65 3b 0a 2a 2a 20 20 20 20  OsDelete;.**    
07f0: 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 45 78   sqlite3OsFileEx
0800: 69 73 74 73 3b 0a 2a 2a 20 20 20 20 20 73 71 6c  ists;.**     sql
0810: 69 74 65 33 4f 73 53 79 6e 63 44 69 72 65 63 74  ite3OsSyncDirect
0820: 6f 72 79 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6f  ory;.**.** The o
0830: 72 69 67 69 6e 61 6c 20 69 6d 70 6c 65 6d 65 6e  riginal implemen
0840: 74 61 74 69 6f 6e 73 20 6f 66 20 74 68 65 73 65  tations of these
0850: 20 72 6f 75 74 69 6e 65 73 20 61 72 65 20 73 61   routines are sa
0860: 76 65 64 20 61 6e 64 20 61 72 65 0a 2a 2a 20 75  ved and are.** u
0870: 73 65 64 20 62 79 20 74 68 65 20 77 72 69 74 65  sed by the write
0880: 72 20 74 68 72 65 61 64 20 74 6f 20 64 6f 20 74  r thread to do t
0890: 68 65 20 72 65 61 6c 20 49 2f 4f 2e 20 20 54 68  he real I/O.  Th
08a0: 65 20 73 75 62 73 74 69 74 75 74 65 0a 2a 2a 20  e substitute.** 
08b0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 20  implementations 
08c0: 74 79 70 69 63 61 6c 6c 79 20 70 75 74 20 74 68  typically put th
08d0: 65 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e 20  e I/O operation 
08e0: 6f 6e 20 61 20 71 75 65 75 65 0a 2a 2a 20 74 6f  on a queue.** to
08f0: 20 62 65 20 68 61 6e 64 6c 65 64 20 6c 61 74 65   be handled late
0900: 72 20 62 79 20 74 68 65 20 77 72 69 74 65 72 20  r by the writer 
0910: 74 68 72 65 61 64 2c 20 74 68 6f 75 67 68 20 72  thread, though r
0920: 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 73 0a 2a  ead operations.*
0930: 2a 20 6d 75 73 74 20 62 65 20 68 61 6e 64 6c 65  * must be handle
0940: 64 20 72 69 67 68 74 20 61 77 61 79 2c 20 6f 62  d right away, ob
0950: 76 69 6f 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 41  viously..**.** A
0960: 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49 2f 4f 20  synchronous I/O 
0970: 69 73 20 64 69 73 61 62 6c 65 64 20 62 79 20 73  is disabled by s
0980: 65 74 74 69 6e 67 20 74 68 65 20 6f 73 2d 6c 61  etting the os-la
0990: 79 65 72 20 69 6e 74 65 72 66 61 63 65 20 72 6f  yer interface ro
09a0: 75 74 69 6e 65 73 0a 2a 2a 20 62 61 63 6b 20 74  utines.** back t
09b0: 6f 20 74 68 65 69 72 20 6f 72 69 67 69 6e 61 6c  o their original
09c0: 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 4c   values..**.** L
09d0: 49 4d 49 54 41 54 49 4f 4e 53 0a 2a 2a 0a 2a 2a  IMITATIONS.**.**
09e0: 20 54 68 69 73 20 64 65 6d 6f 6e 73 74 72 61 74   This demonstrat
09f0: 69 6f 6e 20 63 6f 64 65 20 69 73 20 64 65 6c 69  ion code is deli
0a00: 62 65 72 61 74 65 6c 79 20 6b 65 70 74 20 73 69  berately kept si
0a10: 6d 70 6c 65 20 69 6e 20 6f 72 64 65 72 20 74 6f  mple in order to
0a20: 20 6b 65 65 70 0a 2a 2a 20 74 68 65 20 6d 61 69   keep.** the mai
0a30: 6e 20 69 64 65 61 73 20 63 6c 65 61 72 20 61 6e  n ideas clear an
0a40: 64 20 65 61 73 79 20 74 6f 20 75 6e 64 65 72 73  d easy to unders
0a50: 74 61 6e 64 2e 20 20 52 65 61 6c 20 61 70 70 6c  tand.  Real appl
0a60: 69 63 61 74 69 6f 6e 73 20 74 68 61 74 0a 2a 2a  ications that.**
0a70: 20 77 61 6e 74 20 74 6f 20 64 6f 20 61 73 79 6e   want to do asyn
0a80: 63 68 72 6f 6e 6f 75 73 20 49 2f 4f 20 6d 69 67  chronous I/O mig
0a90: 68 74 20 77 61 6e 74 20 74 6f 20 61 64 64 20 61  ht want to add a
0aa0: 64 64 69 74 69 6f 6e 61 6c 20 63 61 70 61 62 69  dditional capabi
0ab0: 6c 69 74 69 65 73 2e 0a 2a 2a 20 46 6f 72 20 65  lities..** For e
0ac0: 78 61 6d 70 6c 65 2c 20 69 6e 20 74 68 69 73 20  xample, in this 
0ad0: 64 65 6d 6f 6e 73 74 72 61 74 69 6f 6e 20 69 66  demonstration if
0ae0: 20 77 72 69 74 65 73 20 61 72 65 20 68 61 70 70   writes are happ
0af0: 65 6e 69 6e 67 20 61 74 20 61 20 73 74 65 61 64  ening at a stead
0b00: 79 0a 2a 2a 20 73 74 72 65 61 6d 20 74 68 61 74  y.** stream that
0b10: 20 65 78 63 65 65 64 73 20 74 68 65 20 49 2f 4f   exceeds the I/O
0b20: 20 63 61 70 61 62 69 6c 69 74 79 20 6f 66 20 74   capability of t
0b30: 68 65 20 62 61 63 6b 67 72 6f 75 6e 64 20 77 72  he background wr
0b40: 69 74 65 72 20 74 68 72 65 61 64 2c 0a 2a 2a 20  iter thread,.** 
0b50: 74 68 65 20 71 75 65 75 65 20 6f 66 20 70 65 6e  the queue of pen
0b60: 64 69 6e 67 20 77 72 69 74 65 20 6f 70 65 72 61  ding write opera
0b70: 74 69 6f 6e 73 20 77 69 6c 6c 20 67 72 6f 77 20  tions will grow 
0b80: 77 69 74 68 6f 75 74 20 62 6f 75 6e 64 20 75 6e  without bound un
0b90: 74 69 6c 20 77 65 0a 2a 2a 20 72 75 6e 20 6f 75  til we.** run ou
0ba0: 74 20 6f 66 20 6d 65 6d 6f 72 79 2e 20 20 55 73  t of memory.  Us
0bb0: 65 72 73 20 6f 66 20 74 68 69 73 20 74 65 63 68  ers of this tech
0bc0: 6e 69 71 75 65 20 6d 61 79 20 77 61 6e 74 20 74  nique may want t
0bd0: 6f 20 6b 65 65 70 20 74 72 61 63 6b 20 6f 66 0a  o keep track of.
0be0: 2a 2a 20 74 68 65 20 71 75 61 6e 74 69 74 79 20  ** the quantity 
0bf0: 6f 66 20 70 65 6e 64 69 6e 67 20 77 72 69 74 65  of pending write
0c00: 73 20 61 6e 64 20 73 74 6f 70 20 61 63 63 65 70  s and stop accep
0c10: 74 69 6e 67 20 6e 65 77 20 77 72 69 74 65 20 72  ting new write r
0c20: 65 71 75 65 73 74 73 0a 2a 2a 20 77 68 65 6e 20  equests.** when 
0c30: 74 68 65 20 62 75 66 66 65 72 20 67 65 74 73 20  the buffer gets 
0c40: 74 6f 20 62 65 20 74 6f 6f 20 62 69 67 2e 0a 2a  to be too big..*
0c50: 2f 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c  /..#include "sql
0c60: 69 74 65 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75  iteInt.h".#inclu
0c70: 64 65 20 22 6f 73 2e 68 22 0a 23 69 6e 63 6c 75  de "os.h".#inclu
0c80: 64 65 20 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a 20 49  de <tcl.h>../* I
0c90: 66 20 74 68 65 20 54 48 52 45 41 44 53 41 46 45  f the THREADSAFE
0ca0: 20 6d 61 63 72 6f 20 69 73 20 6e 6f 74 20 73 65   macro is not se
0cb0: 74 2c 20 61 73 73 75 6d 65 20 74 68 61 74 20 69  t, assume that i
0cc0: 74 20 69 73 20 74 75 72 6e 65 64 20 6f 66 66 2e  t is turned off.
0cd0: 20 2a 2f 0a 23 69 66 6e 64 65 66 20 54 48 52 45   */.#ifndef THRE
0ce0: 41 44 53 41 46 45 0a 23 20 64 65 66 69 6e 65 20  ADSAFE.# define 
0cf0: 54 48 52 45 41 44 53 41 46 45 20 30 0a 23 65 6e  THREADSAFE 0.#en
0d00: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  dif../*.** This 
0d10: 74 65 73 74 20 75 73 65 73 20 70 74 68 72 65 61  test uses pthrea
0d20: 64 73 20 61 6e 64 20 68 65 6e 63 65 20 6f 6e 6c  ds and hence onl
0d30: 79 20 77 6f 72 6b 73 20 6f 6e 20 75 6e 69 78 20  y works on unix 
0d40: 61 6e 64 20 77 69 74 68 0a 2a 2a 20 61 20 74 68  and with.** a th
0d50: 72 65 61 64 73 61 66 65 20 62 75 69 6c 64 20 6f  readsafe build o
0d60: 66 20 53 51 4c 69 74 65 2e 20 20 49 74 20 61 6c  f SQLite.  It al
0d70: 73 6f 20 72 65 71 75 69 72 65 73 20 74 68 61 74  so requires that
0d80: 20 74 68 65 20 72 65 64 65 66 69 6e 61 62 6c 65   the redefinable
0d90: 0a 2a 2a 20 49 2f 4f 20 66 65 61 74 75 72 65 20  .** I/O feature 
0da0: 6f 66 20 53 51 4c 69 74 65 20 62 65 20 74 75 72  of SQLite be tur
0db0: 6e 65 64 20 6f 6e 2e 20 20 54 68 69 73 20 66 65  ned on.  This fe
0dc0: 61 74 75 72 65 20 69 73 20 74 75 72 6e 65 64 20  ature is turned 
0dd0: 6f 66 66 20 62 79 0a 2a 2a 20 64 65 66 61 75 6c  off by.** defaul
0de0: 74 2e 20 20 49 66 20 61 20 72 65 71 75 69 72 65  t.  If a require
0df0: 64 20 65 6c 65 6d 65 6e 74 20 69 73 20 6d 69 73  d element is mis
0e00: 73 69 6e 67 2c 20 61 6c 6d 6f 73 74 20 61 6c 6c  sing, almost all
0e10: 20 6f 66 20 74 68 65 20 63 6f 64 65 0a 2a 2a 20   of the code.** 
0e20: 69 6e 20 74 68 69 73 20 66 69 6c 65 20 69 73 20  in this file is 
0e30: 63 6f 6d 6d 65 6e 74 65 64 20 6f 75 74 2e 0a 2a  commented out..*
0e40: 2f 0a 23 69 66 20 4f 53 5f 55 4e 49 58 20 26 26  /.#if OS_UNIX &&
0e50: 20 54 48 52 45 41 44 53 41 46 45 20 26 26 20 64   THREADSAFE && d
0e60: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e  efined(SQLITE_EN
0e70: 41 42 4c 45 5f 52 45 44 45 46 5f 49 4f 29 0a 0a  ABLE_REDEF_IO)..
0e80: 2f 2a 0a 2a 2a 20 54 68 69 73 20 64 65 6d 6f 20  /*.** This demo 
0e90: 75 73 65 73 20 70 74 68 72 65 61 64 73 2e 20 20  uses pthreads.  
0ea0: 49 66 20 79 6f 75 20 64 6f 20 6e 6f 74 20 68 61  If you do not ha
0eb0: 76 65 20 61 20 70 74 68 72 65 61 64 73 20 69 6d  ve a pthreads im
0ec0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 0a 2a 2a 20  plementation.** 
0ed0: 66 6f 72 20 79 6f 75 72 20 6f 70 65 72 61 74 69  for your operati
0ee0: 6e 67 20 73 79 73 74 65 6d 2c 20 79 6f 75 20 77  ng system, you w
0ef0: 69 6c 6c 20 6e 65 65 64 20 74 6f 20 72 65 63 6f  ill need to reco
0f00: 64 65 20 74 68 65 20 74 68 72 65 61 64 69 6e 67  de the threading
0f10: 20 0a 2a 2a 20 6c 6f 67 69 63 2e 0a 2a 2f 0a 23   .** logic..*/.#
0f20: 69 6e 63 6c 75 64 65 20 3c 70 74 68 72 65 61 64  include <pthread
0f30: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 63  .h>.#include <sc
0f40: 68 65 64 2e 68 3e 0a 0a 2f 2a 20 55 73 65 66 75  hed.h>../* Usefu
0f50: 6c 20 6d 61 63 72 6f 73 20 75 73 65 64 20 69 6e  l macros used in
0f60: 20 73 65 76 65 72 61 6c 20 70 6c 61 63 65 73 20   several places 
0f70: 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 49 4e 28 78  */.#define MIN(x
0f80: 2c 79 29 20 28 28 78 29 3c 28 79 29 3f 28 78 29  ,y) ((x)<(y)?(x)
0f90: 3a 28 79 29 29 0a 23 64 65 66 69 6e 65 20 4d 41  :(y)).#define MA
0fa0: 58 28 78 2c 79 29 20 28 28 78 29 3e 28 79 29 3f  X(x,y) ((x)>(y)?
0fb0: 28 78 29 3a 28 79 29 29 0a 0a 2f 2a 20 46 6f 72  (x):(y))../* For
0fc0: 77 61 72 64 20 72 65 66 65 72 65 6e 63 65 73 20  ward references 
0fd0: 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
0fe0: 74 20 41 73 79 6e 63 57 72 69 74 65 20 41 73 79  t AsyncWrite Asy
0ff0: 6e 63 57 72 69 74 65 3b 0a 74 79 70 65 64 65 66  ncWrite;.typedef
1000: 20 73 74 72 75 63 74 20 41 73 79 6e 63 46 69 6c   struct AsyncFil
1010: 65 20 41 73 79 6e 63 46 69 6c 65 3b 0a 0a 2f 2a  e AsyncFile;../*
1020: 20 45 6e 61 62 6c 65 20 66 6f 72 20 64 65 62 75   Enable for debu
1030: 67 67 69 6e 67 20 2a 2f 0a 73 74 61 74 69 63 20  gging */.static 
1040: 69 6e 74 20 73 71 6c 69 74 65 33 61 73 79 6e 63  int sqlite3async
1050: 5f 74 72 61 63 65 20 3d 20 30 3b 0a 23 20 64 65  _trace = 0;.# de
1060: 66 69 6e 65 20 54 52 41 43 45 28 58 29 20 69 66  fine TRACE(X) if
1070: 28 20 73 71 6c 69 74 65 33 61 73 79 6e 63 5f 74  ( sqlite3async_t
1080: 72 61 63 65 20 29 20 61 73 79 6e 63 54 72 61 63  race ) asyncTrac
1090: 65 20 58 0a 73 74 61 74 69 63 20 76 6f 69 64 20  e X.static void 
10a0: 61 73 79 6e 63 54 72 61 63 65 28 63 6f 6e 73 74  asyncTrace(const
10b0: 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20   char *zFormat, 
10c0: 2e 2e 2e 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b  ...){.  char *z;
10d0: 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20  .  va_list ap;. 
10e0: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46   va_start(ap, zF
10f0: 6f 72 6d 61 74 29 3b 0a 20 20 7a 20 3d 20 73 71  ormat);.  z = sq
1100: 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66 28 7a  lite3_vmprintf(z
1110: 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 20 20 76  Format, ap);.  v
1120: 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 66 70 72  a_end(ap);.  fpr
1130: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b 25  intf(stderr, "[%
1140: 64 5d 20 25 73 22 2c 20 28 69 6e 74 29 70 74 68  d] %s", (int)pth
1150: 72 65 61 64 5f 73 65 6c 66 28 29 2c 20 7a 29 3b  read_self(), z);
1160: 0a 20 20 66 72 65 65 28 7a 29 3b 0a 7d 0a 0a 2f  .  free(z);.}../
1170: 2a 0a 2a 2a 20 54 48 52 45 41 44 20 53 41 46 45  *.** THREAD SAFE
1180: 54 59 20 4e 4f 54 45 53 0a 2a 2a 0a 2a 2a 20 42  TY NOTES.**.** B
1190: 61 73 69 63 20 72 75 6c 65 73 3a 0a 2a 2a 0a 2a  asic rules:.**.*
11a0: 2a 20 20 20 20 20 2a 20 42 6f 74 68 20 72 65 61  *     * Both rea
11b0: 64 20 61 6e 64 20 77 72 69 74 65 20 61 63 63 65  d and write acce
11c0: 73 73 20 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c  ss to the global
11d0: 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75 65 20   write-op queue 
11e0: 6d 75 73 74 20 62 65 20 0a 2a 2a 20 20 20 20 20  must be .**     
11f0: 20 20 70 72 6f 74 65 63 74 65 64 20 62 79 20 74    protected by t
1200: 68 65 20 61 73 79 6e 63 2e 71 75 65 75 65 4d 75  he async.queueMu
1210: 74 65 78 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a  tex..**.**     *
1220: 20 54 68 65 20 66 69 6c 65 20 68 61 6e 64 6c 65   The file handle
1230: 73 20 66 72 6f 6d 20 74 68 65 20 75 6e 64 65 72  s from the under
1240: 6c 79 69 6e 67 20 73 79 73 74 65 6d 20 61 72 65  lying system are
1250: 20 61 73 73 75 6d 65 64 20 6e 6f 74 20 74 6f 20   assumed not to 
1260: 0a 2a 2a 20 20 20 20 20 20 20 62 65 20 74 68 72  .**       be thr
1270: 65 61 64 20 73 61 66 65 2e 0a 2a 2a 0a 2a 2a 20  ead safe..**.** 
1280: 20 20 20 20 2a 20 53 65 65 20 74 68 65 20 6c 61      * See the la
1290: 73 74 20 74 77 6f 20 70 61 72 61 67 72 61 70 68  st two paragraph
12a0: 73 20 75 6e 64 65 72 20 22 54 68 65 20 57 72 69  s under "The Wri
12b0: 74 65 72 20 54 68 72 65 61 64 22 20 66 6f 72 0a  ter Thread" for.
12c0: 2a 2a 20 20 20 20 20 20 20 61 6e 20 61 73 73 75  **       an assu
12d0: 6d 70 74 69 6f 6e 20 74 6f 20 64 6f 20 77 69 74  mption to do wit
12e0: 68 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 73 79  h file-handle sy
12f0: 6e 63 68 72 6f 6e 69 7a 61 74 69 6f 6e 20 62 79  nchronization by
1300: 20 74 68 65 20 4f 73 2e 0a 2a 2a 0a 2a 2a 20 46   the Os..**.** F
1310: 69 6c 65 20 73 79 73 74 65 6d 20 6f 70 65 72 61  ile system opera
1320: 74 69 6f 6e 73 20 28 69 6e 76 6f 6b 65 64 20 62  tions (invoked b
1330: 79 20 53 51 4c 69 74 65 20 74 68 72 65 61 64 29  y SQLite thread)
1340: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 78 4f 70 65  :.**.**     xOpe
1350: 6e 58 58 58 20 28 74 68 72 65 65 20 76 65 72 73  nXXX (three vers
1360: 69 6f 6e 73 29 0a 2a 2a 20 20 20 20 20 78 44 65  ions).**     xDe
1370: 6c 65 74 65 0a 2a 2a 20 20 20 20 20 78 46 69 6c  lete.**     xFil
1380: 65 45 78 69 73 74 73 0a 2a 2a 20 20 20 20 20 78  eExists.**     x
1390: 53 79 6e 63 44 69 72 65 63 74 6f 72 79 0a 2a 2a  SyncDirectory.**
13a0: 0a 2a 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20  .** File handle 
13b0: 6f 70 65 72 61 74 69 6f 6e 73 20 28 69 6e 76 6f  operations (invo
13c0: 6b 65 64 20 62 79 20 53 51 4c 69 74 65 20 74 68  ked by SQLite th
13d0: 72 65 61 64 29 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  read):.**.**    
13e0: 20 20 20 20 20 61 73 79 6e 63 57 72 69 74 65 2c       asyncWrite,
13f0: 20 61 73 79 6e 63 43 6c 6f 73 65 2c 20 61 73 79   asyncClose, asy
1400: 6e 63 54 72 75 6e 63 61 74 65 2c 20 61 73 79 6e  ncTruncate, asyn
1410: 63 53 79 6e 63 2c 20 0a 2a 2a 20 20 20 20 20 20  cSync, .**      
1420: 20 20 20 61 73 79 6e 63 53 65 74 46 75 6c 6c 53     asyncSetFullS
1430: 79 6e 63 2c 20 61 73 79 6e 63 4f 70 65 6e 44 69  ync, asyncOpenDi
1440: 72 65 63 74 6f 72 79 2e 0a 2a 2a 20 20 20 20 0a  rectory..**    .
1450: 2a 2a 20 20 20 20 20 54 68 65 20 6f 70 65 72 61  **     The opera
1460: 74 69 6f 6e 73 20 61 62 6f 76 65 20 61 64 64 20  tions above add 
1470: 61 6e 20 65 6e 74 72 79 20 74 6f 20 74 68 65 20  an entry to the 
1480: 67 6c 6f 62 61 6c 20 77 72 69 74 65 2d 6f 70 20  global write-op 
1490: 6c 69 73 74 2e 20 54 68 65 79 0a 2a 2a 20 20 20  list. They.**   
14a0: 20 20 70 72 65 70 61 72 65 20 74 68 65 20 65 6e    prepare the en
14b0: 74 72 79 2c 20 61 63 71 75 69 72 65 20 74 68 65  try, acquire the
14c0: 20 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65   async.queueMute
14d0: 78 20 6d 6f 6d 65 6e 74 61 72 69 6c 79 20 77 68  x momentarily wh
14e0: 69 6c 65 0a 2a 2a 20 20 20 20 20 6c 69 73 74 20  ile.**     list 
14f0: 70 6f 69 6e 74 65 72 73 20 61 72 65 20 20 6d 61  pointers are  ma
1500: 6e 69 70 75 6c 61 74 65 64 20 74 6f 20 69 6e 73  nipulated to ins
1510: 65 72 74 20 74 68 65 20 6e 65 77 20 65 6e 74 72  ert the new entr
1520: 79 2c 20 74 68 65 6e 20 72 65 6c 65 61 73 65 0a  y, then release.
1530: 2a 2a 20 20 20 20 20 74 68 65 20 6d 75 74 65 78  **     the mutex
1540: 20 61 6e 64 20 73 69 67 6e 61 6c 20 74 68 65 20   and signal the 
1550: 77 72 69 74 65 72 20 74 68 72 65 61 64 20 74 6f  writer thread to
1560: 20 77 61 6b 65 20 75 70 20 69 6e 20 63 61 73 65   wake up in case
1570: 20 69 74 20 68 61 70 70 65 6e 73 0a 2a 2a 20 20   it happens.**  
1580: 20 20 20 74 6f 20 62 65 20 61 73 6c 65 65 70 2e     to be asleep.
1590: 0a 2a 2a 0a 2a 2a 20 20 20 20 0a 2a 2a 20 20 20  .**.**    .**   
15a0: 20 20 20 20 20 20 61 73 79 6e 63 52 65 61 64 2c        asyncRead,
15b0: 20 61 73 79 6e 63 46 69 6c 65 53 69 7a 65 2e 0a   asyncFileSize..
15c0: 2a 2a 0a 2a 2a 20 20 20 20 20 52 65 61 64 20 6f  **.**     Read o
15d0: 70 65 72 61 74 69 6f 6e 73 2e 20 42 6f 74 68 20  perations. Both 
15e0: 6f 66 20 74 68 65 73 65 20 72 65 61 64 20 66 72  of these read fr
15f0: 6f 6d 20 62 6f 74 68 20 74 68 65 20 75 6e 64 65  om both the unde
1600: 72 6c 79 69 6e 67 20 66 69 6c 65 0a 2a 2a 20 20  rlying file.**  
1610: 20 20 20 66 69 72 73 74 20 74 68 65 6e 20 61 64     first then ad
1620: 6a 75 73 74 20 74 68 65 69 72 20 72 65 73 75 6c  just their resul
1630: 74 20 62 61 73 65 64 20 6f 6e 20 70 65 6e 64 69  t based on pendi
1640: 6e 67 20 77 72 69 74 65 73 20 69 6e 20 74 68 65  ng writes in the
1650: 20 0a 2a 2a 20 20 20 20 20 77 72 69 74 65 2d 6f   .**     write-o
1660: 70 20 71 75 65 75 65 2e 20 20 20 53 6f 20 61 73  p queue.   So as
1670: 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 20 69  ync.queueMutex i
1680: 73 20 68 65 6c 64 20 66 6f 72 20 74 68 65 20 64  s held for the d
1690: 75 72 61 74 69 6f 6e 0a 2a 2a 20 20 20 20 20 6f  uration.**     o
16a0: 66 20 74 68 65 73 65 20 6f 70 65 72 61 74 69 6f  f these operatio
16b0: 6e 73 20 74 6f 20 70 72 65 76 65 6e 74 20 6f 74  ns to prevent ot
16c0: 68 65 72 20 74 68 72 65 61 64 73 20 66 72 6f 6d  her threads from
16d0: 20 63 68 61 6e 67 69 6e 67 20 74 68 65 0a 2a 2a   changing the.**
16e0: 20 20 20 20 20 71 75 65 75 65 20 69 6e 20 6d 69       queue in mi
16f0: 64 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a 20  d operation..** 
1700: 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20     .**.**       
1710: 20 20 61 73 79 6e 63 4c 6f 63 6b 2c 20 61 73 79    asyncLock, asy
1720: 6e 63 55 6e 6c 6f 63 6b 2c 20 61 73 79 6e 63 4c  ncUnlock, asyncL
1730: 6f 63 6b 53 74 61 74 65 2c 20 61 73 79 6e 63 43  ockState, asyncC
1740: 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b  heckReservedLock
1750: 0a 2a 2a 20 20 20 20 0a 2a 2a 20 20 20 20 20 54  .**    .**     T
1760: 68 65 73 65 20 70 72 69 6d 69 74 69 76 65 73 20  hese primitives 
1770: 69 6d 70 6c 65 6d 65 6e 74 20 69 6e 2d 70 72 6f  implement in-pro
1780: 63 65 73 73 20 6c 6f 63 6b 69 6e 67 20 75 73 69  cess locking usi
1790: 6e 67 20 61 20 68 61 73 68 20 74 61 62 6c 65 0a  ng a hash table.
17a0: 2a 2a 20 20 20 20 20 6f 6e 20 74 68 65 20 66 69  **     on the fi
17b0: 6c 65 20 6e 61 6d 65 2e 20 20 46 69 6c 65 73 20  le name.  Files 
17c0: 61 72 65 20 6c 6f 63 6b 65 64 20 63 6f 72 72 65  are locked corre
17d0: 63 74 6c 79 20 66 6f 72 20 63 6f 6e 6e 65 63 74  ctly for connect
17e0: 69 6f 6e 73 20 63 6f 6d 69 6e 67 0a 2a 2a 20 20  ions coming.**  
17f0: 20 20 20 66 72 6f 6d 20 74 68 65 20 73 61 6d 65     from the same
1800: 20 70 72 6f 63 65 73 73 2e 20 20 42 75 74 20 6f   process.  But o
1810: 74 68 65 72 20 70 72 6f 63 65 73 73 65 73 20 63  ther processes c
1820: 61 6e 6e 6f 74 20 73 65 65 20 74 68 65 73 65 20  annot see these 
1830: 6c 6f 63 6b 73 0a 2a 2a 20 20 20 20 20 61 6e 64  locks.**     and
1840: 20 77 69 6c 6c 20 74 68 65 72 65 66 6f 72 65 20   will therefore 
1850: 6e 6f 74 20 68 6f 6e 6f 72 20 74 68 65 6d 2e 0a  not honor them..
1860: 2a 2a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20  **.**.**        
1870: 20 61 73 79 6e 63 46 69 6c 65 48 61 6e 64 6c 65   asyncFileHandle
1880: 2e 0a 2a 2a 20 20 20 20 0a 2a 2a 20 20 20 20 20  ..**    .**     
1890: 54 68 65 20 73 71 6c 69 74 65 33 4f 73 46 69 6c  The sqlite3OsFil
18a0: 65 48 61 6e 64 6c 65 28 29 20 66 75 6e 63 74 69  eHandle() functi
18b0: 6f 6e 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20  on is currently 
18c0: 6f 6e 6c 79 20 75 73 65 64 20 77 68 65 6e 20 0a  only used when .
18d0: 2a 2a 20 20 20 20 20 64 65 62 75 67 67 69 6e 67  **     debugging
18e0: 20 74 68 65 20 70 61 67 65 72 20 6d 6f 64 75 6c   the pager modul
18f0: 65 2e 20 55 6e 6c 65 73 73 20 73 71 6c 69 74 65  e. Unless sqlite
1900: 33 4f 73 43 6c 6f 73 65 28 29 20 69 73 20 63 61  3OsClose() is ca
1910: 6c 6c 65 64 20 6f 6e 20 74 68 65 0a 2a 2a 20 20  lled on the.**  
1920: 20 20 20 66 69 6c 65 20 28 73 68 6f 75 6c 64 6e     file (shouldn
1930: 27 74 20 62 65 20 70 6f 73 73 69 62 6c 65 20 66  't be possible f
1940: 6f 72 20 6f 74 68 65 72 20 72 65 61 73 6f 6e 73  or other reasons
1950: 29 2c 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e  ), the underlyin
1960: 67 20 0a 2a 2a 20 20 20 20 20 69 6d 70 6c 65 6d  g .**     implem
1970: 65 6e 74 61 74 69 6f 6e 73 20 61 72 65 20 73 61  entations are sa
1980: 66 65 20 74 6f 20 63 61 6c 6c 20 77 69 74 68 6f  fe to call witho
1990: 75 74 20 67 72 61 62 62 69 6e 67 20 61 6e 79 20  ut grabbing any 
19a0: 6d 75 74 65 78 2e 20 53 6f 20 77 65 20 6a 75 73  mutex. So we jus
19b0: 74 0a 2a 2a 20 20 20 20 20 67 6f 20 61 68 65 61  t.**     go ahea
19c0: 64 20 61 6e 64 20 63 61 6c 6c 20 69 74 20 6e 6f  d and call it no
19d0: 20 6d 61 74 74 65 72 20 77 68 61 74 20 61 6e 79   matter what any
19e0: 20 6f 74 68 65 72 20 74 68 72 65 61 64 73 20 61   other threads a
19f0: 72 65 20 64 6f 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20  re doing..**.** 
1a00: 20 20 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 61     .**         a
1a10: 73 79 6e 63 53 65 65 6b 2e 0a 2a 2a 0a 2a 2a 20  syncSeek..**.** 
1a20: 20 20 20 20 43 61 6c 6c 69 6e 67 20 74 68 69 73      Calling this
1a30: 20 6d 65 74 68 6f 64 20 6a 75 73 74 20 6d 61 6e   method just man
1a40: 69 70 75 6c 61 74 65 73 20 74 68 65 20 41 73 79  ipulates the Asy
1a50: 6e 63 46 69 6c 65 2e 69 4f 66 66 73 65 74 20 76  ncFile.iOffset v
1a60: 61 72 69 61 62 6c 65 2e 20 0a 2a 2a 20 20 20 20  ariable. .**    
1a70: 20 53 69 6e 63 65 20 74 68 69 73 20 76 61 72 69   Since this vari
1a80: 61 62 6c 65 20 69 73 20 6e 65 76 65 72 20 61 63  able is never ac
1a90: 63 65 73 73 65 64 20 62 79 20 77 72 69 74 65 72  cessed by writer
1aa0: 20 74 68 72 65 61 64 2c 20 74 68 69 73 0a 2a 2a   thread, this.**
1ab0: 20 20 20 20 20 66 75 6e 63 74 69 6f 6e 20 64 6f       function do
1ac0: 65 73 20 6e 6f 74 20 72 65 71 75 69 72 65 20 74  es not require t
1ad0: 68 65 20 6d 75 74 65 78 2e 20 20 41 63 74 75 61  he mutex.  Actua
1ae0: 6c 20 63 61 6c 6c 73 20 74 6f 20 4f 73 53 65 65  l calls to OsSee
1af0: 6b 28 29 20 74 61 6b 65 20 0a 2a 2a 20 20 20 20  k() take .**    
1b00: 20 70 6c 61 63 65 20 6a 75 73 74 20 62 65 66 6f   place just befo
1b10: 72 65 20 4f 73 57 72 69 74 65 28 29 20 6f 72 20  re OsWrite() or 
1b20: 4f 73 52 65 61 64 28 29 2c 20 77 68 69 63 68 20  OsRead(), which 
1b30: 61 72 65 20 61 6c 77 61 79 73 20 70 72 6f 74 65  are always prote
1b40: 63 74 65 64 20 62 79 20 0a 2a 2a 20 20 20 20 20  cted by .**     
1b50: 74 68 65 20 6d 75 74 65 78 2e 0a 2a 2a 0a 2a 2a  the mutex..**.**
1b60: 20 54 68 65 20 77 72 69 74 65 72 20 74 68 72 65   The writer thre
1b70: 61 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 54 68  ad:.**.**     Th
1b80: 65 20 61 73 79 6e 63 2e 77 72 69 74 65 72 4d 75  e async.writerMu
1b90: 74 65 78 20 69 73 20 75 73 65 64 20 74 6f 20 6d  tex is used to m
1ba0: 61 6b 65 20 73 75 72 65 20 6f 6e 6c 79 20 74 68  ake sure only th
1bb0: 65 72 65 20 69 73 20 6f 6e 6c 79 0a 2a 2a 20 20  ere is only.**  
1bc0: 20 20 20 61 20 73 69 6e 67 6c 65 20 77 72 69 74     a single writ
1bd0: 65 72 20 74 68 72 65 61 64 20 72 75 6e 6e 69 6e  er thread runnin
1be0: 67 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2a 0a  g at a time..**.
1bf0: 2a 2a 20 20 20 20 20 49 6e 73 69 64 65 20 74 68  **     Inside th
1c00: 65 20 77 72 69 74 65 72 20 74 68 72 65 61 64 20  e writer thread 
1c10: 69 73 20 61 20 6c 6f 6f 70 20 74 68 61 74 20 77  is a loop that w
1c20: 6f 72 6b 73 20 6c 69 6b 65 20 74 68 69 73 3a 0a  orks like this:.
1c30: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 20 57 48  **.**         WH
1c40: 49 4c 45 20 28 77 72 69 74 65 2d 6f 70 20 6c 69  ILE (write-op li
1c50: 73 74 20 69 73 20 6e 6f 74 20 65 6d 70 74 79 29  st is not empty)
1c60: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
1c70: 44 6f 20 49 4f 20 6f 70 65 72 61 74 69 6f 6e 20  Do IO operation 
1c80: 61 74 20 68 65 61 64 20 6f 66 20 77 72 69 74 65  at head of write
1c90: 2d 6f 70 20 6c 69 73 74 0a 2a 2a 20 20 20 20 20  -op list.**     
1ca0: 20 20 20 20 20 20 20 20 52 65 6d 6f 76 65 20 65          Remove e
1cb0: 6e 74 72 79 20 66 72 6f 6d 20 68 65 61 64 20 6f  ntry from head o
1cc0: 66 20 77 72 69 74 65 2d 6f 70 20 6c 69 73 74 0a  f write-op list.
1cd0: 2a 2a 20 20 20 20 20 20 20 20 20 45 4e 44 20 57  **         END W
1ce0: 48 49 4c 45 0a 2a 2a 0a 2a 2a 20 20 20 20 20 54  HILE.**.**     T
1cf0: 68 65 20 61 73 79 6e 63 2e 71 75 65 75 65 4d 75  he async.queueMu
1d00: 74 65 78 20 69 73 20 61 6c 77 61 79 73 20 68 65  tex is always he
1d10: 6c 64 20 64 75 72 69 6e 67 20 74 68 65 20 3c 77  ld during the <w
1d20: 72 69 74 65 2d 6f 70 20 6c 69 73 74 20 69 73 20  rite-op list is 
1d30: 0a 2a 2a 20 20 20 20 20 6e 6f 74 20 65 6d 70 74  .**     not empt
1d40: 79 3e 20 74 65 73 74 2c 20 61 6e 64 20 77 68 65  y> test, and whe
1d50: 6e 20 74 68 65 20 65 6e 74 72 79 20 69 73 20 72  n the entry is r
1d60: 65 6d 6f 76 65 64 20 66 72 6f 6d 20 74 68 65 20  emoved from the 
1d70: 68 65 61 64 0a 2a 2a 20 20 20 20 20 6f 66 20 74  head.**     of t
1d80: 68 65 20 77 72 69 74 65 2d 6f 70 20 6c 69 73 74  he write-op list
1d90: 2e 20 53 6f 6d 65 74 69 6d 65 73 20 69 74 20 69  . Sometimes it i
1da0: 73 20 68 65 6c 64 20 66 6f 72 20 74 68 65 20 69  s held for the i
1db0: 6e 74 65 72 69 6d 0a 2a 2a 20 20 20 20 20 70 65  nterim.**     pe
1dc0: 72 69 6f 64 20 28 77 68 69 6c 65 20 74 68 65 20  riod (while the 
1dd0: 49 4f 20 69 73 20 70 65 72 66 6f 72 6d 65 64 29  IO is performed)
1de0: 2c 20 61 6e 64 20 73 6f 6d 65 74 69 6d 65 73 20  , and sometimes 
1df0: 69 74 20 69 73 0a 2a 2a 20 20 20 20 20 72 65 6c  it is.**     rel
1e00: 69 6e 71 75 69 73 68 65 64 2e 20 49 74 20 69 73  inquished. It is
1e10: 20 72 65 6c 69 6e 71 75 69 73 68 65 64 20 69 66   relinquished if
1e20: 20 28 61 29 20 74 68 65 20 49 4f 20 6f 70 20 69   (a) the IO op i
1e30: 73 20 61 6e 0a 2a 2a 20 20 20 20 20 41 53 59 4e  s an.**     ASYN
1e40: 43 5f 43 4c 4f 53 45 20 6f 72 20 28 62 29 20 77  C_CLOSE or (b) w
1e50: 68 65 6e 20 74 68 65 20 66 69 6c 65 20 68 61 6e  hen the file han
1e60: 64 6c 65 20 77 61 73 20 6f 70 65 6e 65 64 2c 20  dle was opened, 
1e70: 74 77 6f 20 6f 66 0a 2a 2a 20 20 20 20 20 74 68  two of.**     th
1e80: 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 73 79 73  e underlying sys
1e90: 74 65 6d 73 20 68 61 6e 64 6c 65 73 20 77 65 72  tems handles wer
1ea0: 65 20 6f 70 65 6e 65 64 20 6f 6e 20 74 68 65 20  e opened on the 
1eb0: 73 61 6d 65 0a 2a 2a 20 20 20 20 20 66 69 6c 65  same.**     file
1ec0: 2d 73 79 73 74 65 6d 20 65 6e 74 72 79 2e 0a 2a  -system entry..*
1ed0: 2a 0a 2a 2a 20 20 20 20 20 49 66 20 63 6f 6e 64  *.**     If cond
1ee0: 69 74 69 6f 6e 20 28 62 29 20 61 62 6f 76 65 20  ition (b) above 
1ef0: 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20 6f 6e  is true, then on
1f00: 65 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 0a 2a  e file-handle .*
1f10: 2a 20 20 20 20 20 28 41 73 79 6e 63 46 69 6c 65  *     (AsyncFile
1f20: 2e 70 42 61 73 65 52 65 61 64 29 20 69 73 20 75  .pBaseRead) is u
1f30: 73 65 64 20 65 78 63 6c 75 73 69 76 65 6c 79 20  sed exclusively 
1f40: 62 79 20 73 71 6c 69 74 65 20 74 68 72 65 61 64  by sqlite thread
1f50: 73 20 74 6f 20 72 65 61 64 20 74 68 65 0a 2a 2a  s to read the.**
1f60: 20 20 20 20 20 66 69 6c 65 2c 20 74 68 65 20 6f       file, the o
1f70: 74 68 65 72 20 28 41 73 79 6e 63 46 69 6c 65 2e  ther (AsyncFile.
1f80: 70 42 61 73 65 57 72 69 74 65 29 20 62 79 20 73  pBaseWrite) by s
1f90: 71 6c 69 74 65 33 5f 61 73 79 6e 63 5f 66 6c 75  qlite3_async_flu
1fa0: 73 68 28 29 20 0a 2a 2a 20 20 20 20 20 74 68 72  sh() .**     thr
1fb0: 65 61 64 73 20 74 6f 20 70 65 72 66 6f 72 6d 20  eads to perform 
1fc0: 77 72 69 74 65 28 29 20 6f 70 65 72 61 74 69 6f  write() operatio
1fd0: 6e 73 2e 20 54 68 69 73 20 6d 65 61 6e 73 20 74  ns. This means t
1fe0: 68 61 74 20 72 65 61 64 20 0a 2a 2a 20 20 20 20  hat read .**    
1ff0: 20 6f 70 65 72 61 74 69 6f 6e 73 20 61 72 65 20   operations are 
2000: 6e 6f 74 20 62 6c 6f 63 6b 65 64 20 62 79 20 61  not blocked by a
2010: 73 79 6e 63 68 72 6f 6e 6f 75 73 20 77 72 69 74  synchronous writ
2020: 65 73 20 28 61 6c 74 68 6f 75 67 68 20 0a 2a 2a  es (although .**
2030: 20 20 20 20 20 61 73 79 6e 63 68 72 6f 6e 6f 75       asynchronou
2040: 73 20 77 72 69 74 65 73 20 6d 61 79 20 73 74 69  s writes may sti
2050: 6c 6c 20 62 65 20 62 6c 6f 63 6b 65 64 20 62 79  ll be blocked by
2060: 20 72 65 61 64 73 29 2e 0a 2a 2a 0a 2a 2a 20 20   reads)..**.**  
2070: 20 20 20 54 68 69 73 20 61 73 73 75 6d 65 73 20     This assumes 
2080: 74 68 61 74 20 74 68 65 20 4f 53 20 6b 65 65 70  that the OS keep
2090: 73 20 74 77 6f 20 68 61 6e 64 6c 65 73 20 6f 70  s two handles op
20a0: 65 6e 20 6f 6e 20 74 68 65 20 73 61 6d 65 20 66  en on the same f
20b0: 69 6c 65 0a 2a 2a 20 20 20 20 20 70 72 6f 70 65  ile.**     prope
20c0: 72 6c 79 20 69 6e 20 73 79 6e 63 2e 20 54 68 61  rly in sync. Tha
20d0: 74 20 69 73 2c 20 61 6e 79 20 72 65 61 64 20 6f  t is, any read o
20e0: 70 65 72 61 74 69 6f 6e 20 74 68 61 74 20 73 74  peration that st
20f0: 61 72 74 73 20 61 66 74 65 72 20 61 0a 2a 2a 20  arts after a.** 
2100: 20 20 20 20 77 72 69 74 65 20 6f 70 65 72 61 74      write operat
2110: 69 6f 6e 20 6f 6e 20 74 68 65 20 73 61 6d 65 20  ion on the same 
2120: 66 69 6c 65 20 73 79 73 74 65 6d 20 65 6e 74 72  file system entr
2130: 79 20 68 61 73 20 63 6f 6d 70 6c 65 74 65 64 20  y has completed 
2140: 72 65 74 75 72 6e 73 0a 2a 2a 20 20 20 20 20 64  returns.**     d
2150: 61 74 61 20 63 6f 6e 73 69 73 74 65 6e 74 20 77  ata consistent w
2160: 69 74 68 20 74 68 65 20 77 72 69 74 65 2e 20 57  ith the write. W
2170: 65 20 61 6c 73 6f 20 61 73 73 75 6d 65 20 74 68  e also assume th
2180: 61 74 20 69 66 20 6f 6e 65 20 74 68 72 65 61 64  at if one thread
2190: 20 0a 2a 2a 20 20 20 20 20 72 65 61 64 73 20 61   .**     reads a
21a0: 20 66 69 6c 65 20 77 68 69 6c 65 20 61 6e 6f 74   file while anot
21b0: 68 65 72 20 69 73 20 77 72 69 74 69 6e 67 20 69  her is writing i
21c0: 74 20 61 6c 6c 20 62 79 74 65 73 20 6f 74 68 65  t all bytes othe
21d0: 72 20 74 68 61 6e 20 74 68 65 0a 2a 2a 20 20 20  r than the.**   
21e0: 20 20 6f 6e 65 73 20 61 63 74 75 61 6c 6c 79 20    ones actually 
21f0: 62 65 69 6e 67 20 77 72 69 74 74 65 6e 20 63 6f  being written co
2200: 6e 74 61 69 6e 20 76 61 6c 69 64 20 64 61 74 61  ntain valid data
2210: 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 49 66 20 74  ..**.**     If t
2220: 68 65 20 61 62 6f 76 65 20 61 73 73 75 6d 70 74  he above assumpt
2230: 69 6f 6e 73 20 61 72 65 20 6e 6f 74 20 74 72 75  ions are not tru
2240: 65 2c 20 73 65 74 20 74 68 65 20 70 72 65 70 72  e, set the prepr
2250: 6f 63 65 73 73 6f 72 20 73 79 6d 62 6f 6c 0a 2a  ocessor symbol.*
2260: 2a 20 20 20 20 20 53 51 4c 49 54 45 5f 41 53 59  *     SQLITE_ASY
2270: 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e 44 4c  NC_TWO_FILEHANDL
2280: 45 53 20 74 6f 20 30 2e 0a 2a 2f 0a 0a 23 69 66  ES to 0..*/..#if
2290: 6e 64 65 66 20 53 51 4c 49 54 45 5f 41 53 59 4e  ndef SQLITE_ASYN
22a0: 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e 44 4c 45  C_TWO_FILEHANDLE
22b0: 53 0a 2f 2a 20 23 64 65 66 69 6e 65 20 53 51 4c  S./* #define SQL
22c0: 49 54 45 5f 41 53 59 4e 43 5f 54 57 4f 5f 46 49  ITE_ASYNC_TWO_FI
22d0: 4c 45 48 41 4e 44 4c 45 53 20 30 20 2a 2f 0a 23  LEHANDLES 0 */.#
22e0: 64 65 66 69 6e 65 20 53 51 4c 49 54 45 5f 41 53  define SQLITE_AS
22f0: 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e 44  YNC_TWO_FILEHAND
2300: 4c 45 53 20 31 0a 23 65 6e 64 69 66 0a 0a 2f 2a  LES 1.#endif../*
2310: 0a 2a 2a 20 53 74 61 74 65 20 69 6e 66 6f 72 6d  .** State inform
2320: 61 74 69 6f 6e 20 69 73 20 68 65 6c 64 20 69 6e  ation is held in
2330: 20 74 68 65 20 73 74 61 74 69 63 20 76 61 72 69   the static vari
2340: 61 62 6c 65 20 22 61 73 79 6e 63 22 20 64 65 66  able "async" def
2350: 69 6e 65 64 0a 2a 2a 20 61 73 20 66 6f 6c 6c 6f  ined.** as follo
2360: 77 73 3a 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74  ws:.*/.static st
2370: 72 75 63 74 20 54 65 73 74 41 73 79 6e 63 53 74  ruct TestAsyncSt
2380: 61 74 69 63 44 61 74 61 20 7b 0a 20 20 70 74 68  aticData {.  pth
2390: 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 71 75 65  read_mutex_t que
23a0: 75 65 4d 75 74 65 78 3b 20 20 2f 2a 20 4d 75 74  ueMutex;  /* Mut
23b0: 65 78 20 66 6f 72 20 61 63 63 65 73 73 20 74 6f  ex for access to
23c0: 20 77 72 69 74 65 20 6f 70 65 72 61 74 69 6f 6e   write operation
23d0: 20 71 75 65 75 65 20 2a 2f 0a 20 20 70 74 68 72   queue */.  pthr
23e0: 65 61 64 5f 6d 75 74 65 78 5f 74 20 77 72 69 74  ead_mutex_t writ
23f0: 65 72 4d 75 74 65 78 3b 20 2f 2a 20 50 72 65 76  erMutex; /* Prev
2400: 65 6e 74 73 20 6d 75 6c 74 69 70 6c 65 20 77 72  ents multiple wr
2410: 69 74 65 72 20 74 68 72 65 61 64 73 20 2a 2f 0a  iter threads */.
2420: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
2430: 74 20 6c 6f 63 6b 4d 75 74 65 78 3b 20 20 20 2f  t lockMutex;   /
2440: 2a 20 46 6f 72 20 61 63 63 65 73 73 20 74 6f 20  * For access to 
2450: 61 4c 6f 63 6b 20 68 61 73 68 20 74 61 62 6c 65  aLock hash table
2460: 20 2a 2f 0a 20 20 70 74 68 72 65 61 64 5f 63 6f   */.  pthread_co
2470: 6e 64 5f 74 20 71 75 65 75 65 53 69 67 6e 61 6c  nd_t queueSignal
2480: 3b 20 20 2f 2a 20 46 6f 72 20 77 61 6b 69 6e 67  ;  /* For waking
2490: 20 75 70 20 73 6c 65 65 70 69 6e 67 20 77 72 69   up sleeping wri
24a0: 74 65 72 20 74 68 72 65 61 64 20 2a 2f 0a 20 20  ter thread */.  
24b0: 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f 74 20 65  pthread_cond_t e
24c0: 6d 70 74 79 53 69 67 6e 61 6c 3b 20 20 2f 2a 20  mptySignal;  /* 
24d0: 4e 6f 74 69 66 79 20 77 68 65 6e 20 74 68 65 20  Notify when the 
24e0: 77 72 69 74 65 20 71 75 65 75 65 20 69 73 20 65  write queue is e
24f0: 6d 70 74 79 20 2a 2f 0a 20 20 41 73 79 6e 63 57  mpty */.  AsyncW
2500: 72 69 74 65 20 2a 70 51 75 65 75 65 46 69 72 73  rite *pQueueFirs
2510: 74 3b 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 77  t;     /* Next w
2520: 72 69 74 65 20 6f 70 65 72 61 74 69 6f 6e 20 74  rite operation t
2530: 6f 20 62 65 20 70 72 6f 63 65 73 73 65 64 20 2a  o be processed *
2540: 2f 0a 20 20 41 73 79 6e 63 57 72 69 74 65 20 2a  /.  AsyncWrite *
2550: 70 51 75 65 75 65 4c 61 73 74 3b 20 20 20 20 20  pQueueLast;     
2560: 20 2f 2a 20 4c 61 73 74 20 77 72 69 74 65 20 6f   /* Last write o
2570: 70 65 72 61 74 69 6f 6e 20 6f 6e 20 74 68 65 20  peration on the 
2580: 6c 69 73 74 20 2a 2f 0a 20 20 48 61 73 68 20 61  list */.  Hash a
2590: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
25a0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 73 20         /* Files 
25b0: 6c 6f 63 6b 65 64 20 2a 2f 0a 20 20 76 6f 6c 61  locked */.  vola
25c0: 74 69 6c 65 20 69 6e 74 20 69 6f 44 65 6c 61 79  tile int ioDelay
25d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
25e0: 20 45 78 74 72 61 20 64 65 6c 61 79 20 62 65 74   Extra delay bet
25f0: 77 65 65 6e 20 77 72 69 74 65 20 6f 70 65 72 61  ween write opera
2600: 74 69 6f 6e 73 20 2a 2f 0a 20 20 76 6f 6c 61 74  tions */.  volat
2610: 69 6c 65 20 69 6e 74 20 77 72 69 74 65 72 48 61  ile int writerHa
2620: 6c 74 57 68 65 6e 49 64 6c 65 3b 20 20 2f 2a 20  ltWhenIdle;  /* 
2630: 57 72 69 74 65 72 20 74 68 72 65 61 64 20 68 61  Writer thread ha
2640: 6c 74 73 20 77 68 65 6e 20 71 75 65 75 65 20 65  lts when queue e
2650: 6d 70 74 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  mpty */.  volati
2660: 6c 65 20 69 6e 74 20 77 72 69 74 65 72 48 61 6c  le int writerHal
2670: 74 4e 6f 77 3b 20 20 20 20 20 20 20 2f 2a 20 57  tNow;       /* W
2680: 72 69 74 65 72 20 74 68 72 65 61 64 20 68 61 6c  riter thread hal
2690: 74 73 20 61 66 74 65 72 20 6e 65 78 74 20 6f 70  ts after next op
26a0: 20 2a 2f 0a 20 20 69 6e 74 20 69 6f 45 72 72 6f   */.  int ioErro
26b0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
26c0: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 6e     /* True if an
26d0: 20 49 4f 20 65 72 72 6f 72 20 68 61 73 20 6f 63   IO error has oc
26e0: 63 75 72 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e  cured */.  int n
26f0: 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  File;           
2700: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
2710: 72 20 6f 66 20 6f 70 65 6e 20 66 69 6c 65 73 20  r of open files 
2720: 28 66 72 6f 6d 20 73 71 6c 69 74 65 20 70 6f 76  (from sqlite pov
2730: 29 20 2a 2f 0a 7d 20 61 73 79 6e 63 20 3d 20 7b  ) */.} async = {
2740: 0a 20 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58  .  PTHREAD_MUTEX
2750: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 2c 0a 20 20  _INITIALIZER,.  
2760: 50 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49 4e  PTHREAD_MUTEX_IN
2770: 49 54 49 41 4c 49 5a 45 52 2c 0a 20 20 50 54 48  ITIALIZER,.  PTH
2780: 52 45 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49  READ_MUTEX_INITI
2790: 41 4c 49 5a 45 52 2c 0a 20 20 50 54 48 52 45 41  ALIZER,.  PTHREA
27a0: 44 5f 43 4f 4e 44 5f 49 4e 49 54 49 41 4c 49 5a  D_COND_INITIALIZ
27b0: 45 52 2c 0a 20 20 50 54 48 52 45 41 44 5f 43 4f  ER,.  PTHREAD_CO
27c0: 4e 44 5f 49 4e 49 54 49 41 4c 49 5a 45 52 2c 0a  ND_INITIALIZER,.
27d0: 7d 3b 0a 0a 2f 2a 20 50 6f 73 73 69 62 6c 65 20  };../* Possible 
27e0: 76 61 6c 75 65 73 20 6f 66 20 41 73 79 6e 63 57  values of AsyncW
27f0: 72 69 74 65 2e 6f 70 20 2a 2f 0a 23 64 65 66 69  rite.op */.#defi
2800: 6e 65 20 41 53 59 4e 43 5f 4e 4f 4f 50 20 20 20  ne ASYNC_NOOP   
2810: 20 20 20 20 20 20 20 30 0a 23 64 65 66 69 6e 65         0.#define
2820: 20 41 53 59 4e 43 5f 57 52 49 54 45 20 20 20 20   ASYNC_WRITE    
2830: 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 41       1.#define A
2840: 53 59 4e 43 5f 53 59 4e 43 20 20 20 20 20 20 20  SYNC_SYNC       
2850: 20 20 20 32 0a 23 64 65 66 69 6e 65 20 41 53 59     2.#define ASY
2860: 4e 43 5f 54 52 55 4e 43 41 54 45 20 20 20 20 20  NC_TRUNCATE     
2870: 20 33 0a 23 64 65 66 69 6e 65 20 41 53 59 4e 43   3.#define ASYNC
2880: 5f 43 4c 4f 53 45 20 20 20 20 20 20 20 20 20 34  _CLOSE         4
2890: 0a 23 64 65 66 69 6e 65 20 41 53 59 4e 43 5f 4f  .#define ASYNC_O
28a0: 50 45 4e 44 49 52 45 43 54 4f 52 59 20 35 0a 23  PENDIRECTORY 5.#
28b0: 64 65 66 69 6e 65 20 41 53 59 4e 43 5f 53 45 54  define ASYNC_SET
28c0: 46 55 4c 4c 53 59 4e 43 20 20 20 36 0a 23 64 65  FULLSYNC   6.#de
28d0: 66 69 6e 65 20 41 53 59 4e 43 5f 44 45 4c 45 54  fine ASYNC_DELET
28e0: 45 20 20 20 20 20 20 20 20 37 0a 23 64 65 66 69  E        7.#defi
28f0: 6e 65 20 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43  ne ASYNC_OPENEXC
2900: 4c 55 53 49 56 45 20 38 0a 23 64 65 66 69 6e 65  LUSIVE 8.#define
2910: 20 41 53 59 4e 43 5f 53 59 4e 43 44 49 52 45 43   ASYNC_SYNCDIREC
2920: 54 4f 52 59 20 39 0a 0a 2f 2a 20 4e 61 6d 65 73  TORY 9../* Names
2930: 20 6f 66 20 6f 70 63 6f 64 65 73 2e 20 20 55 73   of opcodes.  Us
2940: 65 64 20 66 6f 72 20 64 65 62 75 67 67 69 6e 67  ed for debugging
2950: 20 6f 6e 6c 79 2e 0a 2a 2a 20 4d 61 6b 65 20 73   only..** Make s
2960: 75 72 65 20 74 68 65 73 65 20 73 74 61 79 20 69  ure these stay i
2970: 6e 20 73 79 6e 63 20 77 69 74 68 20 74 68 65 20  n sync with the 
2980: 6d 61 63 72 6f 73 20 61 62 6f 76 65 21 0a 2a 2f  macros above!.*/
2990: 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68  .static const ch
29a0: 61 72 20 2a 61 7a 4f 70 63 6f 64 65 4e 61 6d 65  ar *azOpcodeName
29b0: 5b 5d 20 3d 20 7b 0a 20 20 22 4e 4f 4f 50 22 2c  [] = {.  "NOOP",
29c0: 20 22 57 52 49 54 45 22 2c 20 22 53 59 4e 43 22   "WRITE", "SYNC"
29d0: 2c 20 22 54 52 55 4e 43 41 54 45 22 2c 20 22 43  , "TRUNCATE", "C
29e0: 4c 4f 53 45 22 2c 0a 20 20 22 4f 50 45 4e 44 49  LOSE",.  "OPENDI
29f0: 52 22 2c 20 22 53 45 54 46 55 4c 4c 53 59 4e 43  R", "SETFULLSYNC
2a00: 22 2c 20 22 44 45 4c 45 54 45 22 2c 20 22 4f 50  ", "DELETE", "OP
2a10: 45 4e 45 58 22 2c 20 22 53 59 4e 43 44 49 52 22  ENEX", "SYNCDIR"
2a20: 2c 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45 6e 74 72  ,.};../*.** Entr
2a30: 69 65 73 20 6f 6e 20 74 68 65 20 77 72 69 74 65  ies on the write
2a40: 2d 6f 70 20 71 75 65 75 65 20 61 72 65 20 69 6e  -op queue are in
2a50: 73 74 61 6e 63 65 73 20 6f 66 20 74 68 65 20 41  stances of the A
2a60: 73 79 6e 63 57 72 69 74 65 0a 2a 2a 20 73 74 72  syncWrite.** str
2a70: 75 63 74 75 72 65 2c 20 64 65 66 69 6e 65 64 20  ucture, defined 
2a80: 68 65 72 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  here..**.** The 
2a90: 69 6e 74 65 72 70 72 65 74 61 74 69 6f 6e 20 6f  interpretation o
2aa0: 66 20 74 68 65 20 69 4f 66 66 73 65 74 20 61 6e  f the iOffset an
2ab0: 64 20 6e 42 79 74 65 20 76 61 72 69 61 62 6c 65  d nByte variable
2ac0: 73 20 76 61 72 69 65 73 20 64 65 70 65 6e 64 69  s varies dependi
2ad0: 6e 67 20 0a 2a 2a 20 6f 6e 20 74 68 65 20 76 61  ng .** on the va
2ae0: 6c 75 65 20 6f 66 20 41 73 79 6e 63 57 72 69 74  lue of AsyncWrit
2af0: 65 2e 6f 70 3a 0a 2a 2a 0a 2a 2a 20 41 53 59 4e  e.op:.**.** ASYN
2b00: 43 5f 57 52 49 54 45 3a 0a 2a 2a 20 20 20 20 20  C_WRITE:.**     
2b10: 69 4f 66 66 73 65 74 20 2d 3e 20 4f 66 66 73 65  iOffset -> Offse
2b20: 74 20 69 6e 20 66 69 6c 65 20 74 6f 20 77 72 69  t in file to wri
2b30: 74 65 20 74 6f 2e 0a 2a 2a 20 20 20 20 20 6e 42  te to..**     nB
2b40: 79 74 65 20 20 20 2d 3e 20 4e 75 6d 62 65 72 20  yte   -> Number 
2b50: 6f 66 20 62 79 74 65 73 20 6f 66 20 64 61 74 61  of bytes of data
2b60: 20 74 6f 20 77 72 69 74 65 20 28 70 6f 69 6e 74   to write (point
2b70: 65 64 20 74 6f 20 62 79 20 7a 42 75 66 29 2e 0a  ed to by zBuf)..
2b80: 2a 2a 0a 2a 2a 20 41 53 59 4e 43 5f 53 59 4e 43  **.** ASYNC_SYNC
2b90: 3a 0a 2a 2a 20 20 20 20 20 69 4f 66 66 73 65 74  :.**     iOffset
2ba0: 20 2d 3e 20 55 6e 75 73 65 64 2e 0a 2a 2a 20 20   -> Unused..**  
2bb0: 20 20 20 6e 42 79 74 65 20 20 20 2d 3e 20 56 61     nByte   -> Va
2bc0: 6c 75 65 20 6f 66 20 22 66 75 6c 6c 73 79 6e 63  lue of "fullsync
2bd0: 22 20 66 6c 61 67 20 74 6f 20 70 61 73 73 20 74  " flag to pass t
2be0: 6f 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28  o sqlite3OsSync(
2bf0: 29 2e 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43 5f 54  )..**.** ASYNC_T
2c00: 52 55 4e 43 41 54 45 3a 0a 2a 2a 20 20 20 20 20  RUNCATE:.**     
2c10: 69 4f 66 66 73 65 74 20 2d 3e 20 53 69 7a 65 20  iOffset -> Size 
2c20: 74 6f 20 74 72 75 6e 63 61 74 65 20 66 69 6c 65  to truncate file
2c30: 20 74 6f 2e 0a 2a 2a 20 20 20 20 20 6e 42 79 74   to..**     nByt
2c40: 65 20 20 20 2d 3e 20 55 6e 75 73 65 64 2e 0a 2a  e   -> Unused..*
2c50: 2a 0a 2a 2a 20 41 53 59 4e 43 5f 43 4c 4f 53 45  *.** ASYNC_CLOSE
2c60: 3a 0a 2a 2a 20 20 20 20 20 69 4f 66 66 73 65 74  :.**     iOffset
2c70: 20 2d 3e 20 55 6e 75 73 65 64 2e 0a 2a 2a 20 20   -> Unused..**  
2c80: 20 20 20 6e 42 79 74 65 20 20 20 2d 3e 20 55 6e     nByte   -> Un
2c90: 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 41 53 59 4e  used..**.** ASYN
2ca0: 43 5f 4f 50 45 4e 44 49 52 45 43 54 4f 52 59 3a  C_OPENDIRECTORY:
2cb0: 0a 2a 2a 20 20 20 20 20 69 4f 66 66 73 65 74 20  .**     iOffset 
2cc0: 2d 3e 20 55 6e 75 73 65 64 2e 0a 2a 2a 20 20 20  -> Unused..**   
2cd0: 20 20 6e 42 79 74 65 20 20 20 2d 3e 20 4e 75 6d    nByte   -> Num
2ce0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20  ber of bytes of 
2cf0: 7a 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 28  zBuf points to (
2d00: 64 69 72 65 63 74 6f 72 79 20 6e 61 6d 65 29 2e  directory name).
2d10: 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43 5f 53 45 54  .**.** ASYNC_SET
2d20: 46 55 4c 4c 53 59 4e 43 3a 0a 2a 2a 20 20 20 20  FULLSYNC:.**    
2d30: 20 69 4f 66 66 73 65 74 20 2d 3e 20 55 6e 75 73   iOffset -> Unus
2d40: 65 64 2e 0a 2a 2a 20 20 20 20 20 6e 42 79 74 65  ed..**     nByte
2d50: 20 20 20 2d 3e 20 4e 65 77 20 76 61 6c 75 65 20     -> New value 
2d60: 66 6f 72 20 74 68 65 20 66 75 6c 6c 2d 73 79 6e  for the full-syn
2d70: 63 20 66 6c 61 67 2e 0a 2a 2a 0a 2a 2a 0a 2a 2a  c flag..**.**.**
2d80: 20 41 53 59 4e 43 5f 44 45 4c 45 54 45 3a 0a 2a   ASYNC_DELETE:.*
2d90: 2a 20 20 20 20 20 69 4f 66 66 73 65 74 20 2d 3e  *     iOffset ->
2da0: 20 55 6e 75 73 65 64 2e 0a 2a 2a 20 20 20 20 20   Unused..**     
2db0: 6e 42 79 74 65 20 20 20 2d 3e 20 4e 75 6d 62 65  nByte   -> Numbe
2dc0: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 7a 42  r of bytes of zB
2dd0: 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 28 66 69  uf points to (fi
2de0: 6c 65 20 6e 61 6d 65 29 2e 0a 2a 2a 0a 2a 2a 20  le name)..**.** 
2df0: 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53  ASYNC_OPENEXCLUS
2e00: 49 56 45 3a 0a 2a 2a 20 20 20 20 20 69 4f 66 66  IVE:.**     iOff
2e10: 73 65 74 20 2d 3e 20 56 61 6c 75 65 20 6f 66 20  set -> Value of 
2e20: 22 64 65 6c 66 6c 61 67 22 2e 0a 2a 2a 20 20 20  "delflag"..**   
2e30: 20 20 6e 42 79 74 65 20 20 20 2d 3e 20 4e 75 6d    nByte   -> Num
2e40: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20  ber of bytes of 
2e50: 7a 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 28  zBuf points to (
2e60: 66 69 6c 65 20 6e 61 6d 65 29 2e 0a 2a 2a 0a 2a  file name)..**.*
2e70: 2a 0a 2a 2a 20 46 6f 72 20 61 6e 20 41 53 59 4e  *.** For an ASYN
2e80: 43 5f 57 52 49 54 45 20 6f 70 65 72 61 74 69 6f  C_WRITE operatio
2e90: 6e 2c 20 7a 42 75 66 20 70 6f 69 6e 74 73 20 74  n, zBuf points t
2ea0: 6f 20 74 68 65 20 64 61 74 61 20 74 6f 20 77 72  o the data to wr
2eb0: 69 74 65 20 74 6f 20 74 68 65 20 66 69 6c 65 2e  ite to the file.
2ec0: 20 0a 2a 2a 20 54 68 69 73 20 73 70 61 63 65 20   .** This space 
2ed0: 69 73 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28  is sqliteMalloc(
2ee0: 29 64 20 61 6c 6f 6e 67 20 77 69 74 68 20 74 68  )d along with th
2ef0: 65 20 41 73 79 6e 63 57 72 69 74 65 20 73 74 72  e AsyncWrite str
2f00: 75 63 74 75 72 65 20 69 6e 20 61 0a 2a 2a 20 73  ucture in a.** s
2f10: 69 6e 67 6c 65 20 62 6c 6f 62 2c 20 73 6f 20 69  ingle blob, so i
2f20: 73 20 64 65 6c 65 74 65 64 20 77 68 65 6e 20 73  s deleted when s
2f30: 71 6c 69 74 65 46 72 65 65 28 29 20 69 73 20 63  qliteFree() is c
2f40: 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 70 61 72  alled on the par
2f50: 65 6e 74 20 0a 2a 2a 20 73 74 72 75 63 74 75 72  ent .** structur
2f60: 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 41 73 79  e..*/.struct Asy
2f70: 6e 63 57 72 69 74 65 20 7b 0a 20 20 41 73 79 6e  ncWrite {.  Asyn
2f80: 63 46 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20  cFile *pFile;   
2f90: 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74 65  /* File to write
2fa0: 20 64 61 74 61 20 74 6f 20 6f 72 20 73 79 6e 63   data to or sync
2fb0: 20 2a 2f 0a 20 20 69 6e 74 20 6f 70 3b 20 20 20   */.  int op;   
2fc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65            /* One
2fd0: 20 6f 66 20 41 53 59 4e 43 5f 78 78 78 20 65 74   of ASYNC_xxx et
2fe0: 63 2e 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66  c. */.  i64 iOff
2ff0: 73 65 74 3b 20 20 20 20 20 20 20 20 2f 2a 20 53  set;        /* S
3000: 65 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20 69 6e  ee above */.  in
3010: 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
3020: 20 20 2f 2a 20 53 65 65 20 61 62 6f 76 65 20 2a    /* See above *
3030: 2f 0a 20 20 63 68 61 72 20 2a 7a 42 75 66 3b 20  /.  char *zBuf; 
3040: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 20          /* Data 
3050: 74 6f 20 77 72 69 74 65 20 74 6f 20 66 69 6c 65  to write to file
3060: 20 28 6f 72 20 4e 55 4c 4c 20 69 66 20 6f 70 21   (or NULL if op!
3070: 3d 41 53 59 4e 43 5f 57 52 49 54 45 29 20 2a 2f  =ASYNC_WRITE) */
3080: 0a 20 20 41 73 79 6e 63 57 72 69 74 65 20 2a 70  .  AsyncWrite *p
3090: 4e 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 77  Next;  /* Next w
30a0: 72 69 74 65 20 6f 70 65 72 61 74 69 6f 6e 20 28  rite operation (
30b0: 74 6f 20 61 6e 79 20 66 69 6c 65 29 20 2a 2f 0a  to any file) */.
30c0: 7d 3b 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 65 20 41  };../* .** The A
30d0: 73 79 6e 63 46 69 6c 65 20 73 74 72 75 63 74 75  syncFile structu
30e0: 72 65 20 69 73 20 61 20 73 75 62 63 6c 61 73 73  re is a subclass
30f0: 20 6f 66 20 4f 73 46 69 6c 65 20 75 73 65 64 20   of OsFile used 
3100: 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73  for asynchronous
3110: 20 49 4f 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 41   IO..*/.struct A
3120: 73 79 6e 63 46 69 6c 65 20 7b 0a 20 20 49 6f 4d  syncFile {.  IoM
3130: 65 74 68 6f 64 20 2a 70 4d 65 74 68 6f 64 3b 20  ethod *pMethod; 
3140: 20 20 2f 2a 20 4d 75 73 74 20 62 65 20 66 69 72    /* Must be fir
3150: 73 74 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66  st */.  i64 iOff
3160: 73 65 74 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  set;         /* 
3170: 43 75 72 72 65 6e 74 20 73 65 65 6b 28 29 20 6f  Current seek() o
3180: 66 66 73 65 74 20 69 6e 20 66 69 6c 65 20 2a 2f  ffset in file */
3190: 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20  .  char *zName; 
31a0: 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 64 65 72          /* Under
31b0: 6c 79 69 6e 67 20 4f 53 20 66 69 6c 65 6e 61 6d  lying OS filenam
31c0: 65 20 2d 20 75 73 65 64 20 66 6f 72 20 64 65 62  e - used for deb
31d0: 75 67 67 69 6e 67 20 2a 2f 0a 20 20 69 6e 74 20  ugging */.  int 
31e0: 6e 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  nName;          
31f0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 68   /* Number of ch
3200: 61 72 61 63 74 65 72 73 20 69 6e 20 7a 4e 61 6d  aracters in zNam
3210: 65 20 2a 2f 0a 20 20 4f 73 46 69 6c 65 20 2a 70  e */.  OsFile *p
3220: 42 61 73 65 52 65 61 64 3b 20 20 20 2f 2a 20 52  BaseRead;   /* R
3230: 65 61 64 20 68 61 6e 64 6c 65 20 74 6f 20 74 68  ead handle to th
3240: 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 4f 73 20  e underlying Os 
3250: 66 69 6c 65 20 2a 2f 0a 20 20 4f 73 46 69 6c 65  file */.  OsFile
3260: 20 2a 70 42 61 73 65 57 72 69 74 65 3b 20 20 2f   *pBaseWrite;  /
3270: 2a 20 57 72 69 74 65 20 68 61 6e 64 6c 65 20 74  * Write handle t
3280: 6f 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  o the underlying
3290: 20 4f 73 20 66 69 6c 65 20 2a 2f 0a 7d 3b 0a 0a   Os file */.};..
32a0: 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 20 65 6e 74  /*.** Add an ent
32b0: 72 79 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66  ry to the end of
32c0: 20 74 68 65 20 67 6c 6f 62 61 6c 20 77 72 69 74   the global writ
32d0: 65 2d 6f 70 20 6c 69 73 74 2e 20 70 57 72 69 74  e-op list. pWrit
32e0: 65 20 73 68 6f 75 6c 64 20 70 6f 69 6e 74 20 0a  e should point .
32f0: 2a 2a 20 74 6f 20 61 6e 20 41 73 79 6e 63 57 72  ** to an AsyncWr
3300: 69 74 65 20 73 74 72 75 63 74 75 72 65 20 61 6c  ite structure al
3310: 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20 73 71  located using sq
3320: 6c 69 74 65 33 4f 73 4d 61 6c 6c 6f 63 28 29 2e  lite3OsMalloc().
3330: 20 20 54 68 65 20 77 72 69 74 65 72 0a 2a 2a 20    The writer.** 
3340: 74 68 72 65 61 64 20 77 69 6c 6c 20 63 61 6c 6c  thread will call
3350: 20 73 71 6c 69 74 65 33 4f 73 46 72 65 65 28 29   sqlite3OsFree()
3360: 20 74 6f 20 66 72 65 65 20 74 68 65 20 73 74 72   to free the str
3370: 75 63 74 75 72 65 20 61 66 74 65 72 20 74 68 65  ucture after the
3380: 20 73 70 65 63 69 66 69 65 64 0a 2a 2a 20 6f 70   specified.** op
3390: 65 72 61 74 69 6f 6e 20 68 61 73 20 62 65 65 6e  eration has been
33a0: 20 63 6f 6d 70 6c 65 74 65 64 2e 0a 2a 2a 0a 2a   completed..**.*
33b0: 2a 20 4f 6e 63 65 20 61 6e 20 41 73 79 6e 63 57  * Once an AsyncW
33c0: 72 69 74 65 20 73 74 72 75 63 74 75 72 65 20 68  rite structure h
33d0: 61 73 20 62 65 65 6e 20 61 64 64 65 64 20 74 6f  as been added to
33e0: 20 74 68 65 20 6c 69 73 74 2c 20 69 74 20 62 65   the list, it be
33f0: 63 6f 6d 65 73 20 74 68 65 0a 2a 2a 20 70 72 6f  comes the.** pro
3400: 70 65 72 74 79 20 6f 66 20 74 68 65 20 77 72 69  perty of the wri
3410: 74 65 72 20 74 68 72 65 61 64 20 61 6e 64 20 6d  ter thread and m
3420: 75 73 74 20 6e 6f 74 20 62 65 20 72 65 61 64 20  ust not be read 
3430: 6f 72 20 6d 6f 64 69 66 69 65 64 20 62 79 20 74  or modified by t
3440: 68 65 0a 2a 2a 20 63 61 6c 6c 65 72 2e 20 20 0a  he.** caller.  .
3450: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
3460: 64 64 41 73 79 6e 63 57 72 69 74 65 28 41 73 79  ddAsyncWrite(Asy
3470: 6e 63 57 72 69 74 65 20 2a 70 57 72 69 74 65 29  ncWrite *pWrite)
3480: 7b 0a 20 20 2f 2a 20 57 65 20 6d 75 73 74 20 68  {.  /* We must h
3490: 6f 6c 64 20 74 68 65 20 71 75 65 75 65 20 6d 75  old the queue mu
34a0: 74 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f 20  tex in order to 
34b0: 6d 6f 64 69 66 79 20 74 68 65 20 71 75 65 75 65  modify the queue
34c0: 20 70 6f 69 6e 74 65 72 73 20 2a 2f 0a 20 20 70   pointers */.  p
34d0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63  thread_mutex_loc
34e0: 6b 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75  k(&async.queueMu
34f0: 74 65 78 29 3b 0a 0a 20 20 2f 2a 20 41 64 64 20  tex);..  /* Add 
3500: 74 68 65 20 72 65 63 6f 72 64 20 74 6f 20 74 68  the record to th
3510: 65 20 65 6e 64 20 6f 66 20 74 68 65 20 77 72 69  e end of the wri
3520: 74 65 2d 6f 70 20 71 75 65 75 65 20 2a 2f 0a 20  te-op queue */. 
3530: 20 61 73 73 65 72 74 28 20 21 70 57 72 69 74 65   assert( !pWrite
3540: 2d 3e 70 4e 65 78 74 20 29 3b 0a 20 20 69 66 28  ->pNext );.  if(
3550: 20 61 73 79 6e 63 2e 70 51 75 65 75 65 4c 61 73   async.pQueueLas
3560: 74 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  t ){.    assert(
3570: 20 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72   async.pQueueFir
3580: 73 74 20 29 3b 0a 20 20 20 20 61 73 79 6e 63 2e  st );.    async.
3590: 70 51 75 65 75 65 4c 61 73 74 2d 3e 70 4e 65 78  pQueueLast->pNex
35a0: 74 20 3d 20 70 57 72 69 74 65 3b 0a 20 20 7d 65  t = pWrite;.  }e
35b0: 6c 73 65 7b 0a 20 20 20 20 61 73 79 6e 63 2e 70  lse{.    async.p
35c0: 51 75 65 75 65 46 69 72 73 74 20 3d 20 70 57 72  QueueFirst = pWr
35d0: 69 74 65 3b 0a 20 20 7d 0a 20 20 61 73 79 6e 63  ite;.  }.  async
35e0: 2e 70 51 75 65 75 65 4c 61 73 74 20 3d 20 70 57  .pQueueLast = pW
35f0: 72 69 74 65 3b 0a 20 20 54 52 41 43 45 28 28 22  rite;.  TRACE(("
3600: 50 55 53 48 20 25 70 20 28 25 73 20 25 73 29 5c  PUSH %p (%s %s)\
3610: 6e 22 2c 20 70 57 72 69 74 65 2c 20 61 7a 4f 70  n", pWrite, azOp
3620: 63 6f 64 65 4e 61 6d 65 5b 70 57 72 69 74 65 2d  codeName[pWrite-
3630: 3e 6f 70 5d 2c 0a 20 20 20 20 20 20 20 20 20 70  >op],.         p
3640: 57 72 69 74 65 2d 3e 70 46 69 6c 65 20 3f 20 70  Write->pFile ? p
3650: 57 72 69 74 65 2d 3e 70 46 69 6c 65 2d 3e 7a 4e  Write->pFile->zN
3660: 61 6d 65 20 3a 20 22 2d 22 29 29 3b 0a 0a 20 20  ame : "-"));..  
3670: 69 66 28 20 70 57 72 69 74 65 2d 3e 6f 70 3d 3d  if( pWrite->op==
3680: 41 53 59 4e 43 5f 43 4c 4f 53 45 20 29 7b 0a 20  ASYNC_CLOSE ){. 
3690: 20 20 20 61 73 79 6e 63 2e 6e 46 69 6c 65 2d 2d     async.nFile--
36a0: 3b 0a 20 20 20 20 69 66 28 20 61 73 79 6e 63 2e  ;.    if( async.
36b0: 6e 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  nFile==0 ){.    
36c0: 20 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 20    async.ioError 
36d0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20  = SQLITE_OK;.   
36e0: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 72 6f   }.  }..  /* Dro
36f0: 70 20 74 68 65 20 71 75 65 75 65 20 6d 75 74 65  p the queue mute
3700: 78 20 2a 2f 0a 20 20 70 74 68 72 65 61 64 5f 6d  x */.  pthread_m
3710: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79  utex_unlock(&asy
3720: 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a  nc.queueMutex);.
3730: 0a 20 20 2f 2a 20 54 68 65 20 77 72 69 74 65 72  .  /* The writer
3740: 20 74 68 72 65 61 64 20 6d 69 67 68 74 20 68 61   thread might ha
3750: 76 65 20 62 65 65 6e 20 69 64 6c 65 20 62 65 63  ve been idle bec
3760: 61 75 73 65 20 74 68 65 72 65 20 77 61 73 20 6e  ause there was n
3770: 6f 74 68 69 6e 67 0a 20 20 2a 2a 20 6f 6e 20 74  othing.  ** on t
3780: 68 65 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75  he write-op queu
3790: 65 20 66 6f 72 20 69 74 20 74 6f 20 64 6f 2e 20  e for it to do. 
37a0: 20 53 6f 20 77 61 6b 65 20 69 74 20 75 70 2e 20   So wake it up. 
37b0: 2a 2f 0a 20 20 70 74 68 72 65 61 64 5f 63 6f 6e  */.  pthread_con
37c0: 64 5f 73 69 67 6e 61 6c 28 26 61 73 79 6e 63 2e  d_signal(&async.
37d0: 71 75 65 75 65 53 69 67 6e 61 6c 29 3b 0a 7d 0a  queueSignal);.}.
37e0: 0a 2f 2a 0a 2a 2a 20 49 6e 63 72 65 6d 65 6e 74  ./*.** Increment
37f0: 20 61 73 79 6e 63 2e 6e 46 69 6c 65 20 69 6e 20   async.nFile in 
3800: 61 20 74 68 72 65 61 64 2d 73 61 66 65 20 6d 61  a thread-safe ma
3810: 6e 6e 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nner..*/.static 
3820: 76 6f 69 64 20 69 6e 63 72 4f 70 65 6e 46 69 6c  void incrOpenFil
3830: 65 43 6f 75 6e 74 28 29 7b 0a 20 20 2f 2a 20 57  eCount(){.  /* W
3840: 65 20 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20  e must hold the 
3850: 71 75 65 75 65 20 6d 75 74 65 78 20 69 6e 20 6f  queue mutex in o
3860: 72 64 65 72 20 74 6f 20 6d 6f 64 69 66 79 20 61  rder to modify a
3870: 73 79 6e 63 2e 6e 46 69 6c 65 20 2a 2f 0a 20 20  sync.nFile */.  
3880: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f  pthread_mutex_lo
3890: 63 6b 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d  ck(&async.queueM
38a0: 75 74 65 78 29 3b 0a 20 20 69 66 28 20 61 73 79  utex);.  if( asy
38b0: 6e 63 2e 6e 46 69 6c 65 3d 3d 30 20 29 7b 0a 20  nc.nFile==0 ){. 
38c0: 20 20 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72     async.ioError
38d0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
38e0: 7d 0a 20 20 61 73 79 6e 63 2e 6e 46 69 6c 65 2b  }.  async.nFile+
38f0: 2b 3b 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74  +;.  pthread_mut
3900: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63  ex_unlock(&async
3910: 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a 7d 0a  .queueMutex);.}.
3920: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 61  ./*.** This is a
3930: 20 75 74 69 6c 69 74 79 20 66 75 6e 63 74 69 6f   utility functio
3940: 6e 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 6e  n to allocate an
3950: 64 20 70 6f 70 75 6c 61 74 65 20 61 20 6e 65 77  d populate a new
3960: 20 41 73 79 6e 63 57 72 69 74 65 0a 2a 2a 20 73   AsyncWrite.** s
3970: 74 72 75 63 74 75 72 65 20 61 6e 64 20 69 6e 73  tructure and ins
3980: 65 72 74 20 69 74 20 28 76 69 61 20 61 64 64 41  ert it (via addA
3990: 73 79 6e 63 57 72 69 74 65 28 29 20 29 20 69 6e  syncWrite() ) in
39a0: 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c 20 6c 69  to the global li
39b0: 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  st..*/.static in
39c0: 74 20 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69  t addNewAsyncWri
39d0: 74 65 28 0a 20 20 41 73 79 6e 63 46 69 6c 65 20  te(.  AsyncFile 
39e0: 2a 70 46 69 6c 65 2c 20 0a 20 20 69 6e 74 20 6f  *pFile, .  int o
39f0: 70 2c 20 0a 20 20 69 36 34 20 69 4f 66 66 73 65  p, .  i64 iOffse
3a00: 74 2c 20 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c  t, .  int nByte,
3a10: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
3a20: 42 79 74 65 0a 29 7b 0a 20 20 41 73 79 6e 63 57  Byte.){.  AsyncW
3a30: 72 69 74 65 20 2a 70 3b 0a 20 20 69 66 28 20 6f  rite *p;.  if( o
3a40: 70 21 3d 41 53 59 4e 43 5f 43 4c 4f 53 45 20 26  p!=ASYNC_CLOSE &
3a50: 26 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 20  & async.ioError 
3a60: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 61 73  ){.    return as
3a70: 79 6e 63 2e 69 6f 45 72 72 6f 72 3b 0a 20 20 7d  ync.ioError;.  }
3a80: 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4f 73  .  p = sqlite3Os
3a90: 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 41 73  Malloc(sizeof(As
3aa0: 79 6e 63 57 72 69 74 65 29 20 2b 20 28 7a 42 79  yncWrite) + (zBy
3ab0: 74 65 3f 6e 42 79 74 65 3a 30 29 29 3b 0a 20 20  te?nByte:0));.  
3ac0: 69 66 28 20 21 70 20 29 7b 0a 20 20 20 20 72 65  if( !p ){.    re
3ad0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
3ae0: 4d 3b 0a 20 20 7d 0a 20 20 70 2d 3e 6f 70 20 3d  M;.  }.  p->op =
3af0: 20 6f 70 3b 0a 20 20 70 2d 3e 69 4f 66 66 73 65   op;.  p->iOffse
3b00: 74 20 3d 20 69 4f 66 66 73 65 74 3b 0a 20 20 70  t = iOffset;.  p
3b10: 2d 3e 6e 42 79 74 65 20 3d 20 6e 42 79 74 65 3b  ->nByte = nByte;
3b20: 0a 20 20 70 2d 3e 70 46 69 6c 65 20 3d 20 70 46  .  p->pFile = pF
3b30: 69 6c 65 3b 0a 20 20 70 2d 3e 70 4e 65 78 74 20  ile;.  p->pNext 
3b40: 3d 20 30 3b 0a 20 20 69 66 28 20 7a 42 79 74 65  = 0;.  if( zByte
3b50: 20 29 7b 0a 20 20 20 20 70 2d 3e 7a 42 75 66 20   ){.    p->zBuf 
3b60: 3d 20 28 63 68 61 72 20 2a 29 26 70 5b 31 5d 3b  = (char *)&p[1];
3b70: 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 2d 3e 7a  .    memcpy(p->z
3b80: 42 75 66 2c 20 7a 42 79 74 65 2c 20 6e 42 79 74  Buf, zByte, nByt
3b90: 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  e);.  }else{.   
3ba0: 20 70 2d 3e 7a 42 75 66 20 3d 20 30 3b 0a 20 20   p->zBuf = 0;.  
3bb0: 7d 0a 20 20 61 64 64 41 73 79 6e 63 57 72 69 74  }.  addAsyncWrit
3bc0: 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  e(p);.  return S
3bd0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
3be0: 2a 2a 20 43 6c 6f 73 65 20 74 68 65 20 66 69 6c  ** Close the fil
3bf0: 65 2e 20 54 68 69 73 20 6a 75 73 74 20 61 64 64  e. This just add
3c00: 73 20 61 6e 20 65 6e 74 72 79 20 74 6f 20 74 68  s an entry to th
3c10: 65 20 77 72 69 74 65 2d 6f 70 20 6c 69 73 74 2c  e write-op list,
3c20: 20 74 68 65 20 66 69 6c 65 20 69 73 0a 2a 2a 20   the file is.** 
3c30: 6e 6f 74 20 61 63 74 75 61 6c 6c 79 20 63 6c 6f  not actually clo
3c40: 73 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  sed..*/.static i
3c50: 6e 74 20 61 73 79 6e 63 43 6c 6f 73 65 28 4f 73  nt asyncClose(Os
3c60: 46 69 6c 65 20 2a 2a 70 49 64 29 7b 0a 20 20 72  File **pId){.  r
3c70: 65 74 75 72 6e 20 61 64 64 4e 65 77 41 73 79 6e  eturn addNewAsyn
3c80: 63 57 72 69 74 65 28 28 41 73 79 6e 63 46 69 6c  cWrite((AsyncFil
3c90: 65 20 2a 29 2a 70 49 64 2c 20 41 53 59 4e 43 5f  e *)*pId, ASYNC_
3ca0: 43 4c 4f 53 45 2c 20 30 2c 20 30 2c 20 30 29 3b  CLOSE, 0, 0, 0);
3cb0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
3cc0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 71 6c 69  entation of sqli
3cd0: 74 65 33 4f 73 57 72 69 74 65 28 29 20 66 6f 72  te3OsWrite() for
3ce0: 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 66 69   asynchronous fi
3cf0: 6c 65 73 2e 20 49 6e 73 74 65 61 64 20 6f 66 20  les. Instead of 
3d00: 0a 2a 2a 20 77 72 69 74 69 6e 67 20 74 6f 20 74  .** writing to t
3d10: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 66 69  he underlying fi
3d20: 6c 65 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  le, this functio
3d30: 6e 20 61 64 64 73 20 61 6e 20 65 6e 74 72 79 20  n adds an entry 
3d40: 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 0a 2a 2a  to the end of.**
3d50: 20 74 68 65 20 67 6c 6f 62 61 6c 20 41 73 79 6e   the global Asyn
3d60: 63 57 72 69 74 65 20 6c 69 73 74 2e 20 45 69 74  cWrite list. Eit
3d70: 68 65 72 20 53 51 4c 49 54 45 5f 4f 4b 20 6f 72  her SQLITE_OK or
3d80: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 6d 61   SQLITE_NOMEM ma
3d90: 79 20 62 65 0a 2a 2a 20 72 65 74 75 72 6e 65 64  y be.** returned
3da0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3db0: 61 73 79 6e 63 57 72 69 74 65 28 4f 73 46 69 6c  asyncWrite(OsFil
3dc0: 65 20 2a 69 64 2c 20 63 6f 6e 73 74 20 76 6f 69  e *id, const voi
3dd0: 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 61 6d 74  d *pBuf, int amt
3de0: 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 20 2a  ){.  AsyncFile *
3df0: 70 46 69 6c 65 20 3d 20 28 41 73 79 6e 63 46 69  pFile = (AsyncFi
3e00: 6c 65 20 2a 29 69 64 3b 0a 20 20 69 6e 74 20 72  le *)id;.  int r
3e10: 63 20 3d 20 61 64 64 4e 65 77 41 73 79 6e 63 57  c = addNewAsyncW
3e20: 72 69 74 65 28 70 46 69 6c 65 2c 20 41 53 59 4e  rite(pFile, ASYN
3e30: 43 5f 57 52 49 54 45 2c 20 70 46 69 6c 65 2d 3e  C_WRITE, pFile->
3e40: 69 4f 66 66 73 65 74 2c 20 61 6d 74 2c 20 70 42  iOffset, amt, pB
3e50: 75 66 29 3b 0a 20 20 70 46 69 6c 65 2d 3e 69 4f  uf);.  pFile->iO
3e60: 66 66 73 65 74 20 2b 3d 20 28 69 36 34 29 61 6d  ffset += (i64)am
3e70: 74 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  t;.  return rc;.
3e80: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63 61 74  }../*.** Truncat
3e90: 65 20 74 68 65 20 66 69 6c 65 20 74 6f 20 6e 42  e the file to nB
3ea0: 79 74 65 20 62 79 74 65 73 20 69 6e 20 6c 65 6e  yte bytes in len
3eb0: 67 74 68 2e 20 54 68 69 73 20 6a 75 73 74 20 61  gth. This just a
3ec0: 64 64 73 20 61 6e 20 65 6e 74 72 79 20 74 6f 20  dds an entry to 
3ed0: 0a 2a 2a 20 74 68 65 20 77 72 69 74 65 2d 6f 70  .** the write-op
3ee0: 20 6c 69 73 74 2c 20 6e 6f 20 49 4f 20 61 63 74   list, no IO act
3ef0: 75 61 6c 6c 79 20 74 61 6b 65 73 20 70 6c 61 63  ually takes plac
3f00: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
3f10: 20 61 73 79 6e 63 54 72 75 6e 63 61 74 65 28 4f   asyncTruncate(O
3f20: 73 46 69 6c 65 20 2a 69 64 2c 20 69 36 34 20 6e  sFile *id, i64 n
3f30: 42 79 74 65 29 7b 0a 20 20 72 65 74 75 72 6e 20  Byte){.  return 
3f40: 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69 74 65  addNewAsyncWrite
3f50: 28 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 69 64  ((AsyncFile *)id
3f60: 2c 20 41 53 59 4e 43 5f 54 52 55 4e 43 41 54 45  , ASYNC_TRUNCATE
3f70: 2c 20 6e 42 79 74 65 2c 20 30 2c 20 30 29 3b 0a  , nByte, 0, 0);.
3f80: 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 74 68  }../*.** Open th
3f90: 65 20 64 69 72 65 63 74 6f 72 79 20 69 64 65 6e  e directory iden
3fa0: 74 69 66 69 65 64 20 62 79 20 7a 4e 61 6d 65 20  tified by zName 
3fb0: 61 6e 64 20 61 73 73 6f 63 69 61 74 65 20 69 74  and associate it
3fc0: 20 77 69 74 68 20 74 68 65 20 0a 2a 2a 20 73 70   with the .** sp
3fd0: 65 63 69 66 69 65 64 20 66 69 6c 65 2e 20 54 68  ecified file. Th
3fe0: 69 73 20 6a 75 73 74 20 61 64 64 73 20 61 6e 20  is just adds an 
3ff0: 65 6e 74 72 79 20 74 6f 20 74 68 65 20 77 72 69  entry to the wri
4000: 74 65 2d 6f 70 20 6c 69 73 74 2c 20 74 68 65 20  te-op list, the 
4010: 0a 2a 2a 20 64 69 72 65 63 74 6f 72 79 20 69 73  .** directory is
4020: 20 6f 70 65 6e 65 64 20 6c 61 74 65 72 20 62 79   opened later by
4030: 20 73 71 6c 69 74 65 33 5f 61 73 79 6e 63 5f 66   sqlite3_async_f
4040: 6c 75 73 68 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  lush()..*/.stati
4050: 63 20 69 6e 74 20 61 73 79 6e 63 4f 70 65 6e 44  c int asyncOpenD
4060: 69 72 65 63 74 6f 72 79 28 4f 73 46 69 6c 65 20  irectory(OsFile 
4070: 2a 69 64 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  *id, const char 
4080: 2a 7a 4e 61 6d 65 29 7b 0a 20 20 41 73 79 6e 63  *zName){.  Async
4090: 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 28 41  File *pFile = (A
40a0: 73 79 6e 63 46 69 6c 65 20 2a 29 69 64 3b 0a 20  syncFile *)id;. 
40b0: 20 72 65 74 75 72 6e 20 61 64 64 4e 65 77 41 73   return addNewAs
40c0: 79 6e 63 57 72 69 74 65 28 70 46 69 6c 65 2c 20  yncWrite(pFile, 
40d0: 41 53 59 4e 43 5f 4f 50 45 4e 44 49 52 45 43 54  ASYNC_OPENDIRECT
40e0: 4f 52 59 2c 20 30 2c 20 73 74 72 6c 65 6e 28 7a  ORY, 0, strlen(z
40f0: 4e 61 6d 65 29 2b 31 2c 7a 4e 61 6d 65 29 3b 0a  Name)+1,zName);.
4100: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 74 68  }../*.** Sync th
4110: 65 20 66 69 6c 65 2e 20 54 68 69 73 20 6a 75 73  e file. This jus
4120: 74 20 61 64 64 73 20 61 6e 20 65 6e 74 72 79 20  t adds an entry 
4130: 74 6f 20 74 68 65 20 77 72 69 74 65 2d 6f 70 20  to the write-op 
4140: 6c 69 73 74 2c 20 74 68 65 20 0a 2a 2a 20 73 79  list, the .** sy
4150: 6e 63 28 29 20 69 73 20 64 6f 6e 65 20 6c 61 74  nc() is done lat
4160: 65 72 20 62 79 20 73 71 6c 69 74 65 33 5f 61 73  er by sqlite3_as
4170: 79 6e 63 5f 66 6c 75 73 68 28 29 2e 0a 2a 2f 0a  ync_flush()..*/.
4180: 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63  static int async
4190: 53 79 6e 63 28 4f 73 46 69 6c 65 20 2a 69 64 2c  Sync(OsFile *id,
41a0: 20 69 6e 74 20 66 75 6c 6c 73 79 6e 63 29 7b 0a   int fullsync){.
41b0: 20 20 72 65 74 75 72 6e 20 61 64 64 4e 65 77 41    return addNewA
41c0: 73 79 6e 63 57 72 69 74 65 28 28 41 73 79 6e 63  syncWrite((Async
41d0: 46 69 6c 65 20 2a 29 69 64 2c 20 41 53 59 4e 43  File *)id, ASYNC
41e0: 5f 53 59 4e 43 2c 20 30 2c 20 66 75 6c 6c 73 79  _SYNC, 0, fullsy
41f0: 6e 63 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  nc, 0);.}../*.**
4200: 20 53 65 74 20 28 6f 72 20 63 6c 65 61 72 29 20   Set (or clear) 
4210: 74 68 65 20 66 75 6c 6c 2d 73 79 6e 63 20 66 6c  the full-sync fl
4220: 61 67 20 6f 6e 20 74 68 65 20 75 6e 64 65 72 6c  ag on the underl
4230: 79 69 6e 67 20 66 69 6c 65 2e 20 54 68 69 73 20  ying file. This 
4240: 6f 70 65 72 61 74 69 6f 6e 0a 2a 2a 20 69 73 20  operation.** is 
4250: 71 75 65 75 65 64 20 61 6e 64 20 70 65 72 66 6f  queued and perfo
4260: 72 6d 65 64 20 6c 61 74 65 72 20 62 79 20 73 71  rmed later by sq
4270: 6c 69 74 65 33 5f 61 73 79 6e 63 5f 66 6c 75 73  lite3_async_flus
4280: 68 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  h()..*/.static v
4290: 6f 69 64 20 61 73 79 6e 63 53 65 74 46 75 6c 6c  oid asyncSetFull
42a0: 53 79 6e 63 28 4f 73 46 69 6c 65 20 2a 69 64 2c  Sync(OsFile *id,
42b0: 20 69 6e 74 20 76 61 6c 75 65 29 7b 0a 20 20 61   int value){.  a
42c0: 64 64 4e 65 77 41 73 79 6e 63 57 72 69 74 65 28  ddNewAsyncWrite(
42d0: 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 69 64 2c  (AsyncFile *)id,
42e0: 20 41 53 59 4e 43 5f 53 45 54 46 55 4c 4c 53 59   ASYNC_SETFULLSY
42f0: 4e 43 2c 20 30 2c 20 76 61 6c 75 65 2c 20 30 29  NC, 0, value, 0)
4300: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20  ;.}../*.** Read 
4310: 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69  data from the fi
4320: 6c 65 2e 20 46 69 72 73 74 20 77 65 20 72 65 61  le. First we rea
4330: 64 20 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 73  d from the files
4340: 79 73 74 65 6d 2c 20 74 68 65 6e 20 61 64 6a 75  ystem, then adju
4350: 73 74 20 0a 2a 2a 20 74 68 65 20 63 6f 6e 74 65  st .** the conte
4360: 6e 74 73 20 6f 66 20 74 68 65 20 62 75 66 66 65  nts of the buffe
4370: 72 20 62 61 73 65 64 20 6f 6e 20 41 53 59 4e 43  r based on ASYNC
4380: 5f 57 52 49 54 45 20 6f 70 65 72 61 74 69 6f 6e  _WRITE operation
4390: 73 20 69 6e 20 74 68 65 20 0a 2a 2a 20 77 72 69  s in the .** wri
43a0: 74 65 2d 6f 70 20 71 75 65 75 65 2e 0a 2a 2a 0a  te-op queue..**.
43b0: 2a 2a 20 54 68 69 73 20 6d 65 74 68 6f 64 20 68  ** This method h
43c0: 6f 6c 64 73 20 74 68 65 20 6d 75 74 65 78 20 66  olds the mutex f
43d0: 72 6f 6d 20 73 74 61 72 74 20 74 6f 20 66 69 6e  rom start to fin
43e0: 69 73 68 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ish..*/.static i
43f0: 6e 74 20 61 73 79 6e 63 52 65 61 64 28 4f 73 46  nt asyncRead(OsF
4400: 69 6c 65 20 2a 69 64 2c 20 76 6f 69 64 20 2a 6f  ile *id, void *o
4410: 62 75 66 2c 20 69 6e 74 20 61 6d 74 29 7b 0a 20  buf, int amt){. 
4420: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
4430: 5f 4f 4b 3b 0a 20 20 69 36 34 20 66 69 6c 65 73  _OK;.  i64 files
4440: 69 7a 65 3b 0a 20 20 69 6e 74 20 6e 52 65 61 64  ize;.  int nRead
4450: 3b 0a 20 20 41 73 79 6e 63 46 69 6c 65 20 2a 70  ;.  AsyncFile *p
4460: 46 69 6c 65 20 3d 20 28 41 73 79 6e 63 46 69 6c  File = (AsyncFil
4470: 65 20 2a 29 69 64 3b 0a 20 20 4f 73 46 69 6c 65  e *)id;.  OsFile
4480: 20 2a 70 42 61 73 65 20 3d 20 70 46 69 6c 65 2d   *pBase = pFile-
4490: 3e 70 42 61 73 65 52 65 61 64 3b 0a 0a 20 20 69  >pBaseRead;..  i
44a0: 66 28 20 21 70 42 61 73 65 20 29 7b 0a 20 20 20  f( !pBase ){.   
44b0: 20 70 42 61 73 65 20 3d 20 70 46 69 6c 65 2d 3e   pBase = pFile->
44c0: 70 42 61 73 65 57 72 69 74 65 3b 0a 20 20 7d 0a  pBaseWrite;.  }.
44d0: 0a 20 20 2f 2a 20 49 66 20 61 6e 20 49 2f 4f 20  .  /* If an I/O 
44e0: 65 72 72 6f 72 20 68 61 73 20 70 72 65 76 69 6f  error has previo
44f0: 75 73 6c 79 20 6f 63 63 75 72 72 65 64 20 6f 6e  usly occurred on
4500: 20 74 68 69 73 20 66 69 6c 65 2c 20 74 68 65 6e   this file, then
4510: 20 61 6c 6c 0a 20 20 2a 2a 20 73 75 62 73 65 71   all.  ** subseq
4520: 75 65 6e 74 20 6f 70 65 72 61 74 69 6f 6e 73 20  uent operations 
4530: 66 61 69 6c 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  fail..  */.  if(
4540: 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 21 3d   async.ioError!=
4550: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4560: 20 72 65 74 75 72 6e 20 61 73 79 6e 63 2e 69 6f   return async.io
4570: 45 72 72 6f 72 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  Error;.  }..  /*
4580: 20 47 72 61 62 20 74 68 65 20 77 72 69 74 65 20   Grab the write 
4590: 71 75 65 75 65 20 6d 75 74 65 78 20 66 6f 72 20  queue mutex for 
45a0: 74 68 65 20 64 75 72 61 74 69 6f 6e 20 6f 66 20  the duration of 
45b0: 74 68 65 20 63 61 6c 6c 20 2a 2f 0a 20 20 70 74  the call */.  pt
45c0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
45d0: 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74  (&async.queueMut
45e0: 65 78 29 3b 0a 0a 20 20 69 66 28 20 70 42 61 73  ex);..  if( pBas
45f0: 65 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  e ){.    rc = sq
4600: 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65 28  lite3OsFileSize(
4610: 70 42 61 73 65 2c 20 26 66 69 6c 65 73 69 7a 65  pBase, &filesize
4620: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
4630: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
4640: 20 20 67 6f 74 6f 20 61 73 79 6e 63 72 65 61 64    goto asyncread
4650: 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20  _out;.    }.    
4660: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 65  rc = sqlite3OsSe
4670: 65 6b 28 70 42 61 73 65 2c 20 70 46 69 6c 65 2d  ek(pBase, pFile-
4680: 3e 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 69  >iOffset);.    i
4690: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
46a0: 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 61   ){.      goto a
46b0: 73 79 6e 63 72 65 61 64 5f 6f 75 74 3b 0a 20 20  syncread_out;.  
46c0: 20 20 7d 0a 20 20 20 20 6e 52 65 61 64 20 3d 20    }.    nRead = 
46d0: 4d 49 4e 28 66 69 6c 65 73 69 7a 65 20 2d 20 70  MIN(filesize - p
46e0: 46 69 6c 65 2d 3e 69 4f 66 66 73 65 74 2c 20 61  File->iOffset, a
46f0: 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 6e 52 65  mt);.    if( nRe
4700: 61 64 3e 30 20 29 7b 0a 20 20 20 20 20 20 72 63  ad>0 ){.      rc
4710: 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64   = sqlite3OsRead
4720: 28 70 42 61 73 65 2c 20 6f 62 75 66 2c 20 6e 52  (pBase, obuf, nR
4730: 65 61 64 29 3b 0a 20 20 20 20 20 20 54 52 41 43  ead);.      TRAC
4740: 45 28 28 22 52 45 41 44 20 25 73 20 25 64 20 62  E(("READ %s %d b
4750: 79 74 65 73 20 61 74 20 25 64 5c 6e 22 2c 20 70  ytes at %d\n", p
4760: 46 69 6c 65 2d 3e 7a 4e 61 6d 65 2c 20 6e 52 65  File->zName, nRe
4770: 61 64 2c 20 70 46 69 6c 65 2d 3e 69 4f 66 66 73  ad, pFile->iOffs
4780: 65 74 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  et));.    }.  }.
4790: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
47a0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 41 73 79 6e  E_OK ){.    Asyn
47b0: 63 57 72 69 74 65 20 2a 70 3b 0a 20 20 20 20 69  cWrite *p;.    i
47c0: 36 34 20 69 4f 66 66 73 65 74 20 3d 20 70 46 69  64 iOffset = pFi
47d0: 6c 65 2d 3e 69 4f 66 66 73 65 74 3b 20 20 20 20  le->iOffset;    
47e0: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
47f0: 74 20 73 65 65 6b 20 6f 66 66 73 65 74 20 2a 2f  t seek offset */
4800: 0a 0a 20 20 20 20 66 6f 72 28 70 3d 61 73 79 6e  ..    for(p=asyn
4810: 63 2e 70 51 75 65 75 65 46 69 72 73 74 3b 20 70  c.pQueueFirst; p
4820: 3b 20 70 20 3d 20 70 2d 3e 70 4e 65 78 74 29 7b  ; p = p->pNext){
4830: 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e 70 46  .      if( p->pF
4840: 69 6c 65 3d 3d 70 46 69 6c 65 20 26 26 20 70 2d  ile==pFile && p-
4850: 3e 6f 70 3d 3d 41 53 59 4e 43 5f 57 52 49 54 45  >op==ASYNC_WRITE
4860: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
4870: 69 42 65 67 69 6e 4f 75 74 20 3d 20 28 70 2d 3e  iBeginOut = (p->
4880: 69 4f 66 66 73 65 74 20 2d 20 69 4f 66 66 73 65  iOffset - iOffse
4890: 74 29 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  t);.        int 
48a0: 69 42 65 67 69 6e 49 6e 20 3d 20 2d 69 42 65 67  iBeginIn = -iBeg
48b0: 69 6e 4f 75 74 3b 0a 20 20 20 20 20 20 20 20 69  inOut;.        i
48c0: 6e 74 20 6e 43 6f 70 79 3b 0a 0a 20 20 20 20 20  nt nCopy;..     
48d0: 20 20 20 69 66 28 20 69 42 65 67 69 6e 49 6e 3c     if( iBeginIn<
48e0: 30 20 29 20 69 42 65 67 69 6e 49 6e 20 3d 20 30  0 ) iBeginIn = 0
48f0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 42  ;.        if( iB
4900: 65 67 69 6e 4f 75 74 3c 30 20 29 20 69 42 65 67  eginOut<0 ) iBeg
4910: 69 6e 4f 75 74 20 3d 20 30 3b 0a 20 20 20 20 20  inOut = 0;.     
4920: 20 20 20 6e 43 6f 70 79 20 3d 20 4d 49 4e 28 70     nCopy = MIN(p
4930: 2d 3e 6e 42 79 74 65 2d 69 42 65 67 69 6e 49 6e  ->nByte-iBeginIn
4940: 2c 20 61 6d 74 2d 69 42 65 67 69 6e 4f 75 74 29  , amt-iBeginOut)
4950: 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 6e  ;..        if( n
4960: 43 6f 70 79 3e 30 20 29 7b 0a 20 20 20 20 20 20  Copy>0 ){.      
4970: 20 20 20 20 6d 65 6d 63 70 79 28 26 28 28 63 68      memcpy(&((ch
4980: 61 72 20 2a 29 6f 62 75 66 29 5b 69 42 65 67 69  ar *)obuf)[iBegi
4990: 6e 4f 75 74 5d 2c 20 26 70 2d 3e 7a 42 75 66 5b  nOut], &p->zBuf[
49a0: 69 42 65 67 69 6e 49 6e 5d 2c 20 6e 43 6f 70 79  iBeginIn], nCopy
49b0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 54 52 41  );.          TRA
49c0: 43 45 28 28 22 4f 56 45 52 52 45 41 44 20 25 64  CE(("OVERREAD %d
49d0: 20 62 79 74 65 73 20 61 74 20 25 64 5c 6e 22 2c   bytes at %d\n",
49e0: 20 6e 43 6f 70 79 2c 20 69 42 65 67 69 6e 4f 75   nCopy, iBeginOu
49f0: 74 2b 69 4f 66 66 73 65 74 29 29 3b 0a 20 20 20  t+iOffset));.   
4a00: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
4a10: 20 20 20 7d 0a 0a 20 20 20 20 70 46 69 6c 65 2d     }..    pFile-
4a20: 3e 69 4f 66 66 73 65 74 20 2b 3d 20 28 69 36 34  >iOffset += (i64
4a30: 29 61 6d 74 3b 0a 20 20 7d 0a 0a 61 73 79 6e 63  )amt;.  }..async
4a40: 72 65 61 64 5f 6f 75 74 3a 0a 20 20 70 74 68 72  read_out:.  pthr
4a50: 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b  ead_mutex_unlock
4a60: 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74  (&async.queueMut
4a70: 65 78 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ex);.  return rc
4a80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 65 6b 20  ;.}../*.** Seek 
4a90: 74 6f 20 74 68 65 20 73 70 65 63 69 66 69 65 64  to the specified
4aa0: 20 6f 66 66 73 65 74 2e 20 54 68 69 73 20 6a 75   offset. This ju
4ab0: 73 74 20 61 64 6a 75 73 74 73 20 74 68 65 20 41  st adjusts the A
4ac0: 73 79 6e 63 46 69 6c 65 2e 69 4f 66 66 73 65 74  syncFile.iOffset
4ad0: 20 0a 2a 2a 20 76 61 72 69 61 62 6c 65 20 2d 20   .** variable - 
4ae0: 63 61 6c 6c 69 6e 67 20 73 65 65 6b 28 29 20 6f  calling seek() o
4af0: 6e 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  n the underlying
4b00: 20 66 69 6c 65 20 69 73 20 64 65 66 65 72 65 64   file is defered
4b10: 20 75 6e 74 69 6c 20 74 68 65 20 0a 2a 2a 20 6e   until the .** n
4b20: 65 78 74 20 72 65 61 64 28 29 20 6f 72 20 77 72  ext read() or wr
4b30: 69 74 65 28 29 20 6f 70 65 72 61 74 69 6f 6e 2e  ite() operation.
4b40: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
4b50: 61 73 79 6e 63 53 65 65 6b 28 4f 73 46 69 6c 65  asyncSeek(OsFile
4b60: 20 2a 69 64 2c 20 69 36 34 20 6f 66 66 73 65 74   *id, i64 offset
4b70: 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 20 2a  ){.  AsyncFile *
4b80: 70 46 69 6c 65 20 3d 20 28 41 73 79 6e 63 46 69  pFile = (AsyncFi
4b90: 6c 65 20 2a 29 69 64 3b 0a 20 20 70 46 69 6c 65  le *)id;.  pFile
4ba0: 2d 3e 69 4f 66 66 73 65 74 20 3d 20 6f 66 66 73  ->iOffset = offs
4bb0: 65 74 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  et;.  return SQL
4bc0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
4bd0: 20 52 65 61 64 20 74 68 65 20 73 69 7a 65 20 6f   Read the size o
4be0: 66 20 74 68 65 20 66 69 6c 65 2e 20 46 69 72 73  f the file. Firs
4bf0: 74 20 77 65 20 72 65 61 64 20 74 68 65 20 73 69  t we read the si
4c00: 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 73  ze of the file s
4c10: 79 73 74 65 6d 20 0a 2a 2a 20 65 6e 74 72 79 2c  ystem .** entry,
4c20: 20 74 68 65 6e 20 61 64 6a 75 73 74 20 66 6f 72   then adjust for
4c30: 20 61 6e 79 20 41 53 59 4e 43 5f 57 52 49 54 45   any ASYNC_WRITE
4c40: 20 6f 72 20 41 53 59 4e 43 5f 54 52 55 4e 43 41   or ASYNC_TRUNCA
4c50: 54 45 20 6f 70 65 72 61 74 69 6f 6e 73 20 0a 2a  TE operations .*
4c60: 2a 20 63 75 72 72 65 6e 74 6c 79 20 69 6e 20 74  * currently in t
4c70: 68 65 20 77 72 69 74 65 2d 6f 70 20 6c 69 73 74  he write-op list
4c80: 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d 65  . .**.** This me
4c90: 74 68 6f 64 20 68 6f 6c 64 73 20 74 68 65 20 6d  thod holds the m
4ca0: 75 74 65 78 20 66 72 6f 6d 20 73 74 61 72 74 20  utex from start 
4cb0: 74 6f 20 66 69 6e 69 73 68 2e 0a 2a 2f 0a 69 6e  to finish..*/.in
4cc0: 74 20 61 73 79 6e 63 46 69 6c 65 53 69 7a 65 28  t asyncFileSize(
4cd0: 4f 73 46 69 6c 65 20 2a 69 64 2c 20 69 36 34 20  OsFile *id, i64 
4ce0: 2a 70 53 69 7a 65 29 7b 0a 20 20 69 6e 74 20 72  *pSize){.  int r
4cf0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
4d00: 20 69 36 34 20 73 20 3d 20 30 3b 0a 20 20 4f 73   i64 s = 0;.  Os
4d10: 46 69 6c 65 20 2a 70 42 61 73 65 3b 0a 0a 20 20  File *pBase;..  
4d20: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f  pthread_mutex_lo
4d30: 63 6b 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d  ck(&async.queueM
4d40: 75 74 65 78 29 3b 0a 0a 20 20 2f 2a 20 52 65 61  utex);..  /* Rea
4d50: 64 20 74 68 65 20 66 69 6c 65 73 79 73 74 65 6d  d the filesystem
4d60: 20 73 69 7a 65 20 66 72 6f 6d 20 74 68 65 20 62   size from the b
4d70: 61 73 65 20 66 69 6c 65 2e 20 49 66 20 70 42 61  ase file. If pBa
4d80: 73 65 52 65 61 64 20 69 73 20 4e 55 4c 4c 2c 20  seRead is NULL, 
4d90: 74 68 69 73 0a 20 20 2a 2a 20 6d 65 61 6e 73 20  this.  ** means 
4da0: 74 68 65 20 66 69 6c 65 20 68 61 73 6e 27 74 20  the file hasn't 
4db0: 62 65 65 6e 20 6f 70 65 6e 65 64 20 79 65 74 2e  been opened yet.
4dc0: 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 61 6c   In this case al
4dd0: 6c 20 72 65 6c 65 76 61 6e 74 20 64 61 74 61 20  l relevant data 
4de0: 0a 20 20 2a 2a 20 6d 75 73 74 20 62 65 20 69 6e  .  ** must be in
4df0: 20 74 68 65 20 77 72 69 74 65 2d 6f 70 20 71 75   the write-op qu
4e00: 65 75 65 20 61 6e 79 77 61 79 2c 20 73 6f 20 77  eue anyway, so w
4e10: 65 20 63 61 6e 20 6f 6d 69 74 20 72 65 61 64 69  e can omit readi
4e20: 6e 67 20 66 72 6f 6d 20 74 68 65 0a 20 20 2a 2a  ng from the.  **
4e30: 20 66 69 6c 65 2d 73 79 73 74 65 6d 2e 0a 20 20   file-system..  
4e40: 2a 2f 0a 20 20 70 42 61 73 65 20 3d 20 28 28 41  */.  pBase = ((A
4e50: 73 79 6e 63 46 69 6c 65 20 2a 29 69 64 29 2d 3e  syncFile *)id)->
4e60: 70 42 61 73 65 52 65 61 64 3b 0a 20 20 69 66 28  pBaseRead;.  if(
4e70: 20 21 70 42 61 73 65 20 29 7b 0a 20 20 20 20 70   !pBase ){.    p
4e80: 42 61 73 65 20 3d 20 28 28 41 73 79 6e 63 46 69  Base = ((AsyncFi
4e90: 6c 65 20 2a 29 69 64 29 2d 3e 70 42 61 73 65 57  le *)id)->pBaseW
4ea0: 72 69 74 65 3b 0a 20 20 7d 0a 20 20 69 66 28 20  rite;.  }.  if( 
4eb0: 70 42 61 73 65 20 29 7b 0a 20 20 20 20 72 63 20  pBase ){.    rc 
4ec0: 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53  = sqlite3OsFileS
4ed0: 69 7a 65 28 70 42 61 73 65 2c 20 26 73 29 3b 0a  ize(pBase, &s);.
4ee0: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
4ef0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
4f00: 41 73 79 6e 63 57 72 69 74 65 20 2a 70 3b 0a 20  AsyncWrite *p;. 
4f10: 20 20 20 66 6f 72 28 70 3d 61 73 79 6e 63 2e 70     for(p=async.p
4f20: 51 75 65 75 65 46 69 72 73 74 3b 20 70 3b 20 70  QueueFirst; p; p
4f30: 20 3d 20 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20   = p->pNext){.  
4f40: 20 20 20 20 69 66 28 20 70 2d 3e 70 46 69 6c 65      if( p->pFile
4f50: 3d 3d 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 69  ==(AsyncFile *)i
4f60: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 73 77 69  d ){.        swi
4f70: 74 63 68 28 20 70 2d 3e 6f 70 20 29 7b 0a 20 20  tch( p->op ){.  
4f80: 20 20 20 20 20 20 20 20 63 61 73 65 20 41 53 59          case ASY
4f90: 4e 43 5f 57 52 49 54 45 3a 0a 20 20 20 20 20 20  NC_WRITE:.      
4fa0: 20 20 20 20 20 20 73 20 3d 20 4d 41 58 28 70 2d        s = MAX(p-
4fb0: 3e 69 4f 66 66 73 65 74 20 2b 20 28 69 36 34 29  >iOffset + (i64)
4fc0: 28 70 2d 3e 6e 42 79 74 65 29 2c 20 73 29 3b 0a  (p->nByte), s);.
4fd0: 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61              brea
4fe0: 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 63 61 73  k;.          cas
4ff0: 65 20 41 53 59 4e 43 5f 54 52 55 4e 43 41 54 45  e ASYNC_TRUNCATE
5000: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 20  :.            s 
5010: 3d 20 4d 49 4e 28 73 2c 20 70 2d 3e 6e 42 79 74  = MIN(s, p->nByt
5020: 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  e);.            
5030: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
5040: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
5050: 20 20 20 2a 70 53 69 7a 65 20 3d 20 73 3b 0a 20     *pSize = s;. 
5060: 20 7d 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74   }.  pthread_mut
5070: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63  ex_unlock(&async
5080: 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20  .queueMutex);.  
5090: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
50a0: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6f  .** Return the o
50b0: 70 65 72 61 74 69 6e 67 20 73 79 73 74 65 6d 20  perating system 
50c0: 66 69 6c 65 20 68 61 6e 64 6c 65 2e 20 54 68 69  file handle. Thi
50d0: 73 20 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 66  s is only used f
50e0: 6f 72 20 64 65 62 75 67 67 69 6e 67 20 0a 2a 2a  or debugging .**
50f0: 20 61 74 20 74 68 65 20 6d 6f 6d 65 6e 74 20 61   at the moment a
5100: 6e 79 77 61 79 2e 0a 2a 2f 0a 73 74 61 74 69 63  nyway..*/.static
5110: 20 69 6e 74 20 61 73 79 6e 63 46 69 6c 65 48 61   int asyncFileHa
5120: 6e 64 6c 65 28 4f 73 46 69 6c 65 20 2a 69 64 29  ndle(OsFile *id)
5130: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
5140: 65 33 4f 73 46 69 6c 65 48 61 6e 64 6c 65 28 28  e3OsFileHandle((
5150: 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 69 64 29  (AsyncFile *)id)
5160: 2d 3e 70 42 61 73 65 52 65 61 64 29 3b 0a 7d 0a  ->pBaseRead);.}.
5170: 0a 2f 2a 0a 2a 2a 20 4e 6f 20 64 69 73 6b 20 6c  ./*.** No disk l
5180: 6f 63 6b 69 6e 67 20 69 73 20 70 65 72 66 6f 72  ocking is perfor
5190: 6d 65 64 2e 20 20 57 65 20 6b 65 65 70 20 74 72  med.  We keep tr
51a0: 61 63 6b 20 6f 66 20 6c 6f 63 6b 73 20 6c 6f 63  ack of locks loc
51b0: 61 6c 6c 79 20 69 6e 0a 2a 2a 20 74 68 65 20 61  ally in.** the a
51c0: 73 79 6e 63 2e 61 4c 6f 63 6b 20 68 61 73 68 20  sync.aLock hash 
51d0: 74 61 62 6c 65 2e 20 20 4c 6f 63 6b 69 6e 67 20  table.  Locking 
51e0: 73 68 6f 75 6c 64 20 61 70 70 65 61 72 20 74 6f  should appear to
51f0: 20 77 6f 72 6b 20 74 68 65 20 73 61 6d 65 0a 2a   work the same.*
5200: 2a 20 61 73 20 77 69 74 68 20 73 74 61 6e 64 61  * as with standa
5210: 72 64 20 28 75 6e 6d 6f 64 69 66 69 65 64 29 20  rd (unmodified) 
5220: 53 51 4c 69 74 65 20 61 73 20 6c 6f 6e 67 20 61  SQLite as long a
5230: 73 20 61 6c 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e  s all connection
5240: 73 20 0a 2a 2a 20 63 6f 6d 65 20 66 72 6f 6d 20  s .** come from 
5250: 74 68 69 73 20 6f 6e 65 20 70 72 6f 63 65 73 73  this one process
5260: 2e 20 20 43 6f 6e 6e 65 63 74 69 6f 6e 73 20 66  .  Connections f
5270: 72 6f 6d 20 65 78 74 65 72 6e 61 6c 20 70 72 6f  rom external pro
5280: 63 65 73 73 65 73 0a 2a 2a 20 63 61 6e 6e 6f 74  cesses.** cannot
5290: 20 73 65 65 20 6f 75 72 20 69 6e 74 65 72 6e 61   see our interna
52a0: 6c 20 68 61 73 68 20 74 61 62 6c 65 20 28 6f 62  l hash table (ob
52b0: 76 69 6f 75 73 6c 79 29 20 61 6e 64 20 77 69 6c  viously) and wil
52c0: 6c 20 74 68 75 73 20 6e 6f 74 0a 2a 2a 20 68 6f  l thus not.** ho
52d0: 6e 6f 72 20 6f 75 72 20 6c 6f 63 6b 73 2e 0a 2a  nor our locks..*
52e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 73 79  /.static int asy
52f0: 6e 63 4c 6f 63 6b 28 4f 73 46 69 6c 65 20 2a 69  ncLock(OsFile *i
5300: 64 2c 20 69 6e 74 20 6c 6f 63 6b 54 79 70 65 29  d, int lockType)
5310: 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 20 2a 70  {.  AsyncFile *p
5320: 46 69 6c 65 20 3d 20 28 41 73 79 6e 63 46 69 6c  File = (AsyncFil
5330: 65 2a 29 69 64 3b 0a 20 20 54 52 41 43 45 28 28  e*)id;.  TRACE((
5340: 22 4c 4f 43 4b 20 25 64 20 28 25 73 29 5c 6e 22  "LOCK %d (%s)\n"
5350: 2c 20 6c 6f 63 6b 54 79 70 65 2c 20 70 46 69 6c  , lockType, pFil
5360: 65 2d 3e 7a 4e 61 6d 65 29 29 3b 0a 20 20 70 74  e->zName));.  pt
5370: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
5380: 28 26 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65  (&async.lockMute
5390: 78 29 3b 0a 20 20 73 71 6c 69 74 65 33 48 61 73  x);.  sqlite3Has
53a0: 68 49 6e 73 65 72 74 28 26 61 73 79 6e 63 2e 61  hInsert(&async.a
53b0: 4c 6f 63 6b 2c 20 70 46 69 6c 65 2d 3e 7a 4e 61  Lock, pFile->zNa
53c0: 6d 65 2c 20 70 46 69 6c 65 2d 3e 6e 4e 61 6d 65  me, pFile->nName
53d0: 2c 20 28 76 6f 69 64 2a 29 6c 6f 63 6b 54 79 70  , (void*)lockTyp
53e0: 65 29 3b 0a 20 20 70 74 68 72 65 61 64 5f 6d 75  e);.  pthread_mu
53f0: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e  tex_unlock(&asyn
5400: 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20 20  c.lockMutex);.  
5410: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
5420: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 61  ;.}.static int a
5430: 73 79 6e 63 55 6e 6c 6f 63 6b 28 4f 73 46 69 6c  syncUnlock(OsFil
5440: 65 20 2a 69 64 2c 20 69 6e 74 20 6c 6f 63 6b 54  e *id, int lockT
5450: 79 70 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 61  ype){.  return a
5460: 73 79 6e 63 4c 6f 63 6b 28 69 64 2c 20 6c 6f 63  syncLock(id, loc
5470: 6b 54 79 70 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  kType);.}../*.**
5480: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
5490: 73 20 63 61 6c 6c 65 64 20 77 68 65 6e 20 74 68  s called when th
54a0: 65 20 70 61 67 65 72 20 6c 61 79 65 72 20 66 69  e pager layer fi
54b0: 72 73 74 20 6f 70 65 6e 73 20 61 20 64 61 74 61  rst opens a data
54c0: 62 61 73 65 20 66 69 6c 65 0a 2a 2a 20 61 6e 64  base file.** and
54d0: 20 69 73 20 63 68 65 63 6b 69 6e 67 20 66 6f 72   is checking for
54e0: 20 61 20 68 6f 74 2d 6a 6f 75 72 6e 61 6c 2e 0a   a hot-journal..
54f0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 73  */.static int as
5500: 79 6e 63 43 68 65 63 6b 52 65 73 65 72 76 65 64  yncCheckReserved
5510: 4c 6f 63 6b 28 4f 73 46 69 6c 65 20 2a 69 64 29  Lock(OsFile *id)
5520: 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 20 2a 70  {.  AsyncFile *p
5530: 46 69 6c 65 20 3d 20 28 41 73 79 6e 63 46 69 6c  File = (AsyncFil
5540: 65 2a 29 69 64 3b 0a 20 20 69 6e 74 20 72 63 3b  e*)id;.  int rc;
5550: 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78  .  pthread_mutex
5560: 5f 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 6c 6f 63  _lock(&async.loc
5570: 6b 4d 75 74 65 78 29 3b 0a 20 20 72 63 20 3d 20  kMutex);.  rc = 
5580: 28 69 6e 74 29 73 71 6c 69 74 65 33 48 61 73 68  (int)sqlite3Hash
5590: 46 69 6e 64 28 26 61 73 79 6e 63 2e 61 4c 6f 63  Find(&async.aLoc
55a0: 6b 2c 20 70 46 69 6c 65 2d 3e 7a 4e 61 6d 65 2c  k, pFile->zName,
55b0: 20 70 46 69 6c 65 2d 3e 6e 4e 61 6d 65 29 3b 0a   pFile->nName);.
55c0: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
55d0: 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 6c 6f  unlock(&async.lo
55e0: 63 6b 4d 75 74 65 78 29 3b 0a 20 20 54 52 41 43  ckMutex);.  TRAC
55f0: 45 28 28 22 43 48 45 43 4b 2d 4c 4f 43 4b 20 25  E(("CHECK-LOCK %
5600: 64 20 28 25 73 29 5c 6e 22 2c 20 72 63 2c 20 70  d (%s)\n", rc, p
5610: 46 69 6c 65 2d 3e 7a 4e 61 6d 65 29 29 3b 0a 20  File->zName));. 
5620: 20 72 65 74 75 72 6e 20 72 63 3e 53 48 41 52 45   return rc>SHARE
5630: 44 5f 4c 4f 43 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  D_LOCK;.}../* .*
5640: 2a 20 54 68 69 73 20 69 73 20 62 72 6f 6b 65 6e  * This is broken
5650: 2e 20 42 75 74 20 73 71 6c 69 74 65 33 4f 73 4c  . But sqlite3OsL
5660: 6f 63 6b 53 74 61 74 65 28 29 20 69 73 20 6f 6e  ockState() is on
5670: 6c 79 20 75 73 65 64 20 66 6f 72 20 74 65 73 74  ly used for test
5680: 69 6e 67 20 61 6e 79 77 61 79 2e 0a 2a 2f 0a 73  ing anyway..*/.s
5690: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 4c  tatic int asyncL
56a0: 6f 63 6b 53 74 61 74 65 28 4f 73 46 69 6c 65 20  ockState(OsFile 
56b0: 2a 69 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 53  *id){.  return S
56c0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
56d0: 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** The following
56e0: 20 76 61 72 69 61 62 6c 65 73 20 68 6f 6c 64 20   variables hold 
56f0: 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68 65 20  pointers to the 
5700: 6f 72 69 67 69 6e 61 6c 20 76 65 72 73 69 6f 6e  original version
5710: 73 20 6f 66 0a 2a 2a 20 4f 53 2d 6c 61 79 65 72  s of.** OS-layer
5720: 20 69 6e 74 65 72 66 61 63 65 20 72 6f 75 74 69   interface routi
5730: 6e 65 73 20 74 68 61 74 20 61 72 65 20 6f 76 65  nes that are ove
5740: 72 6c 6f 61 64 65 64 20 69 6e 20 6f 72 64 65 72  rloaded in order
5750: 20 74 6f 20 63 72 65 61 74 65 0a 2a 2a 20 74 68   to create.** th
5760: 65 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49  e asynchronous I
5770: 2f 4f 20 62 61 63 6b 65 6e 64 2e 0a 2a 2f 0a 73  /O backend..*/.s
5780: 74 61 74 69 63 20 69 6e 74 20 28 2a 78 4f 72 69  tatic int (*xOri
5790: 67 4f 70 65 6e 52 65 61 64 57 72 69 74 65 29 28  gOpenReadWrite)(
57a0: 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 4f 73 46  const char*, OsF
57b0: 69 6c 65 2a 2a 2c 20 69 6e 74 2a 29 20 3d 20 30  ile**, int*) = 0
57c0: 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 28 2a 78  ;.static int (*x
57d0: 4f 72 69 67 4f 70 65 6e 45 78 63 6c 75 73 69 76  OrigOpenExclusiv
57e0: 65 29 28 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20  e)(const char*, 
57f0: 4f 73 46 69 6c 65 2a 2a 2c 20 69 6e 74 29 20 3d  OsFile**, int) =
5800: 20 30 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 28   0;.static int (
5810: 2a 78 4f 72 69 67 4f 70 65 6e 52 65 61 64 4f 6e  *xOrigOpenReadOn
5820: 6c 79 29 28 63 6f 6e 73 74 20 63 68 61 72 2a 2c  ly)(const char*,
5830: 20 4f 73 46 69 6c 65 2a 2a 29 20 3d 20 30 3b 0a   OsFile**) = 0;.
5840: 73 74 61 74 69 63 20 69 6e 74 20 28 2a 78 4f 72  static int (*xOr
5850: 69 67 44 65 6c 65 74 65 29 28 63 6f 6e 73 74 20  igDelete)(const 
5860: 63 68 61 72 2a 29 20 3d 20 30 3b 0a 73 74 61 74  char*) = 0;.stat
5870: 69 63 20 69 6e 74 20 28 2a 78 4f 72 69 67 46 69  ic int (*xOrigFi
5880: 6c 65 45 78 69 73 74 73 29 28 63 6f 6e 73 74 20  leExists)(const 
5890: 63 68 61 72 2a 29 20 3d 20 30 3b 0a 73 74 61 74  char*) = 0;.stat
58a0: 69 63 20 69 6e 74 20 28 2a 78 4f 72 69 67 53 79  ic int (*xOrigSy
58b0: 6e 63 44 69 72 65 63 74 6f 72 79 29 28 63 6f 6e  ncDirectory)(con
58c0: 73 74 20 63 68 61 72 2a 29 20 3d 20 30 3b 0a 0a  st char*) = 0;..
58d0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  /*.** This routi
58e0: 6e 65 20 64 6f 65 73 20 6d 6f 73 74 20 6f 66 20  ne does most of 
58f0: 74 68 65 20 77 6f 72 6b 20 6f 66 20 6f 70 65 6e  the work of open
5900: 69 6e 67 20 61 20 66 69 6c 65 20 61 6e 64 20 62  ing a file and b
5910: 75 69 6c 64 69 6e 67 0a 2a 2a 20 74 68 65 20 4f  uilding.** the O
5920: 73 46 69 6c 65 20 73 74 72 75 63 74 75 72 65 2e  sFile structure.
5930: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .*/.static int a
5940: 73 79 6e 63 4f 70 65 6e 46 69 6c 65 28 0a 20 20  syncOpenFile(.  
5950: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
5960: 65 2c 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 61  e,     /* The na
5970: 6d 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 74  me of the file t
5980: 6f 20 62 65 20 6f 70 65 6e 65 64 20 2a 2f 0a 20  o be opened */. 
5990: 20 4f 73 46 69 6c 65 20 2a 2a 70 46 69 6c 65 2c   OsFile **pFile,
59a0: 20 20 20 20 20 20 20 20 2f 2a 20 50 75 74 20 74          /* Put t
59b0: 68 65 20 4f 73 46 69 6c 65 20 73 74 72 75 63 74  he OsFile struct
59c0: 75 72 65 20 68 65 72 65 20 2a 2f 0a 20 20 4f 73  ure here */.  Os
59d0: 46 69 6c 65 20 2a 70 42 61 73 65 52 65 61 64 2c  File *pBaseRead,
59e0: 20 20 20 20 20 2f 2a 20 54 68 65 20 72 65 61 6c       /* The real
59f0: 20 4f 73 46 69 6c 65 20 66 72 6f 6d 20 74 68 65   OsFile from the
5a00: 20 72 65 61 6c 20 49 2f 4f 20 72 6f 75 74 69 6e   real I/O routin
5a10: 65 20 2a 2f 0a 20 20 69 6e 74 20 6f 70 65 6e 46  e */.  int openF
5a20: 6f 72 57 72 69 74 69 6e 67 20 20 20 20 20 2f 2a  orWriting     /*
5a30: 20 4f 70 65 6e 20 61 20 73 65 63 6f 6e 64 20 66   Open a second f
5a40: 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72 20 77  ile handle for w
5a50: 72 69 74 69 6e 67 20 69 66 20 74 72 75 65 20 2a  riting if true *
5a60: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 2c 20 69  /.){.  int rc, i
5a70: 2c 20 6e 3b 0a 20 20 41 73 79 6e 63 46 69 6c 65  , n;.  AsyncFile
5a80: 20 2a 70 3b 0a 20 20 4f 73 46 69 6c 65 20 2a 70   *p;.  OsFile *p
5a90: 42 61 73 65 57 72 69 74 65 20 3d 20 30 3b 0a 0a  BaseWrite = 0;..
5aa0: 20 20 73 74 61 74 69 63 20 49 6f 4d 65 74 68 6f    static IoMetho
5ab0: 64 20 69 6f 6d 65 74 68 6f 64 20 3d 20 7b 0a 20  d iomethod = {. 
5ac0: 20 20 20 61 73 79 6e 63 43 6c 6f 73 65 2c 0a 20     asyncClose,. 
5ad0: 20 20 20 61 73 79 6e 63 4f 70 65 6e 44 69 72 65     asyncOpenDire
5ae0: 63 74 6f 72 79 2c 0a 20 20 20 20 61 73 79 6e 63  ctory,.    async
5af0: 52 65 61 64 2c 0a 20 20 20 20 61 73 79 6e 63 57  Read,.    asyncW
5b00: 72 69 74 65 2c 0a 20 20 20 20 61 73 79 6e 63 53  rite,.    asyncS
5b10: 65 65 6b 2c 0a 20 20 20 20 61 73 79 6e 63 54 72  eek,.    asyncTr
5b20: 75 6e 63 61 74 65 2c 0a 20 20 20 20 61 73 79 6e  uncate,.    asyn
5b30: 63 53 79 6e 63 2c 0a 20 20 20 20 61 73 79 6e 63  cSync,.    async
5b40: 53 65 74 46 75 6c 6c 53 79 6e 63 2c 0a 20 20 20  SetFullSync,.   
5b50: 20 61 73 79 6e 63 46 69 6c 65 48 61 6e 64 6c 65   asyncFileHandle
5b60: 2c 0a 20 20 20 20 61 73 79 6e 63 46 69 6c 65 53  ,.    asyncFileS
5b70: 69 7a 65 2c 0a 20 20 20 20 61 73 79 6e 63 4c 6f  ize,.    asyncLo
5b80: 63 6b 2c 0a 20 20 20 20 61 73 79 6e 63 55 6e 6c  ck,.    asyncUnl
5b90: 6f 63 6b 2c 0a 20 20 20 20 61 73 79 6e 63 4c 6f  ock,.    asyncLo
5ba0: 63 6b 53 74 61 74 65 2c 0a 20 20 20 20 61 73 79  ckState,.    asy
5bb0: 6e 63 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c  ncCheckReservedL
5bc0: 6f 63 6b 0a 20 20 7d 3b 0a 0a 20 20 69 66 28 20  ock.  };..  if( 
5bd0: 6f 70 65 6e 46 6f 72 57 72 69 74 69 6e 67 20 26  openForWriting &
5be0: 26 20 53 51 4c 49 54 45 5f 41 53 59 4e 43 5f 54  & SQLITE_ASYNC_T
5bf0: 57 4f 5f 46 49 4c 45 48 41 4e 44 4c 45 53 20 29  WO_FILEHANDLES )
5c00: 7b 0a 20 20 20 20 69 6e 74 20 64 75 6d 6d 79 3b  {.    int dummy;
5c10: 0a 20 20 20 20 72 63 20 3d 20 78 4f 72 69 67 4f  .    rc = xOrigO
5c20: 70 65 6e 52 65 61 64 57 72 69 74 65 28 7a 4e 61  penReadWrite(zNa
5c30: 6d 65 2c 20 26 70 42 61 73 65 57 72 69 74 65 2c  me, &pBaseWrite,
5c40: 20 26 64 75 6d 6d 79 29 3b 0a 20 20 20 20 69 66   &dummy);.    if
5c50: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
5c60: 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 65 72  ){.      goto er
5c70: 72 6f 72 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20  ror_out;.    }. 
5c80: 20 7d 0a 0a 20 20 6e 20 3d 20 73 74 72 6c 65 6e   }..  n = strlen
5c90: 28 7a 4e 61 6d 65 29 3b 0a 20 20 66 6f 72 28 69  (zName);.  for(i
5ca0: 3d 6e 2d 31 3b 20 69 3e 3d 30 20 26 26 20 7a 4e  =n-1; i>=0 && zN
5cb0: 61 6d 65 5b 69 5d 21 3d 27 2f 27 3b 20 69 2d 2d  ame[i]!='/'; i--
5cc0: 29 7b 7d 0a 20 20 70 20 3d 20 28 41 73 79 6e 63  ){}.  p = (Async
5cd0: 46 69 6c 65 20 2a 29 73 71 6c 69 74 65 33 4f 73  File *)sqlite3Os
5ce0: 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 41 73  Malloc(sizeof(As
5cf0: 79 6e 63 46 69 6c 65 29 20 2b 20 6e 20 2d 20 69  yncFile) + n - i
5d00: 29 3b 0a 20 20 69 66 28 20 21 70 20 29 7b 0a 20  );.  if( !p ){. 
5d10: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
5d20: 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 65  OMEM;.    goto e
5d30: 72 72 6f 72 5f 6f 75 74 3b 0a 20 20 7d 0a 20 20  rror_out;.  }.  
5d40: 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a  memset(p, 0, siz
5d50: 65 6f 66 28 41 73 79 6e 63 46 69 6c 65 29 29 3b  eof(AsyncFile));
5d60: 0a 20 20 70 2d 3e 7a 4e 61 6d 65 20 3d 20 28 63  .  p->zName = (c
5d70: 68 61 72 2a 29 26 70 5b 31 5d 3b 0a 20 20 73 74  har*)&p[1];.  st
5d80: 72 63 70 79 28 70 2d 3e 7a 4e 61 6d 65 2c 20 26  rcpy(p->zName, &
5d90: 7a 4e 61 6d 65 5b 69 2b 31 5d 29 3b 0a 20 20 70  zName[i+1]);.  p
5da0: 2d 3e 6e 4e 61 6d 65 20 3d 20 6e 20 2d 20 69 3b  ->nName = n - i;
5db0: 0a 20 20 70 2d 3e 70 4d 65 74 68 6f 64 20 3d 20  .  p->pMethod = 
5dc0: 26 69 6f 6d 65 74 68 6f 64 3b 0a 20 20 70 2d 3e  &iomethod;.  p->
5dd0: 70 42 61 73 65 52 65 61 64 20 3d 20 70 42 61 73  pBaseRead = pBas
5de0: 65 52 65 61 64 3b 0a 20 20 70 2d 3e 70 42 61 73  eRead;.  p->pBas
5df0: 65 57 72 69 74 65 20 3d 20 70 42 61 73 65 57 72  eWrite = pBaseWr
5e00: 69 74 65 3b 0a 20 20 0a 20 20 2a 70 46 69 6c 65  ite;.  .  *pFile
5e10: 20 3d 20 28 4f 73 46 69 6c 65 20 2a 29 70 3b 0a   = (OsFile *)p;.
5e20: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
5e30: 4f 4b 3b 0a 0a 65 72 72 6f 72 5f 6f 75 74 3a 0a  OK;..error_out:.
5e40: 20 20 61 73 73 65 72 74 28 21 70 29 3b 0a 20 20    assert(!p);.  
5e50: 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 26  sqlite3OsClose(&
5e60: 70 42 61 73 65 52 65 61 64 29 3b 0a 20 20 73 71  pBaseRead);.  sq
5e70: 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 26 70 42  lite3OsClose(&pB
5e80: 61 73 65 57 72 69 74 65 29 3b 0a 20 20 2a 70 46  aseWrite);.  *pF
5e90: 69 6c 65 20 3d 20 30 3b 0a 20 20 72 65 74 75 72  ile = 0;.  retur
5ea0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  n rc;.}../*.** T
5eb0: 68 65 20 61 73 79 6e 63 2d 49 4f 20 62 61 63 6b  he async-IO back
5ec0: 65 6e 64 73 20 69 6d 70 6c 65 6d 65 6e 74 61 74  ends implementat
5ed0: 69 6f 6e 20 6f 66 20 74 68 65 20 74 68 72 65 65  ion of the three
5ee0: 20 66 75 6e 63 74 69 6f 6e 73 20 75 73 65 64 20   functions used 
5ef0: 74 6f 20 6f 70 65 6e 0a 2a 2a 20 61 20 66 69 6c  to open.** a fil
5f00: 65 20 28 78 4f 70 65 6e 45 78 63 6c 75 73 69 76  e (xOpenExclusiv
5f10: 65 2c 20 78 4f 70 65 6e 52 65 61 64 57 72 69 74  e, xOpenReadWrit
5f20: 65 20 61 6e 64 20 78 4f 70 65 6e 52 65 61 64 4f  e and xOpenReadO
5f30: 6e 6c 79 29 2e 20 4d 6f 73 74 20 6f 66 20 74 68  nly). Most of th
5f40: 65 20 0a 2a 2a 20 77 6f 72 6b 20 69 73 20 64 6f  e .** work is do
5f50: 6e 65 20 69 6e 20 66 75 6e 63 74 69 6f 6e 20 61  ne in function a
5f60: 73 79 6e 63 4f 70 65 6e 46 69 6c 65 28 29 20 2d  syncOpenFile() -
5f70: 20 73 65 65 20 61 62 6f 76 65 2e 0a 2a 2f 0a 73   see above..*/.s
5f80: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 4f  tatic int asyncO
5f90: 70 65 6e 45 78 63 6c 75 73 69 76 65 28 63 6f 6e  penExclusive(con
5fa0: 73 74 20 63 68 61 72 20 2a 7a 2c 20 4f 73 46 69  st char *z, OsFi
5fb0: 6c 65 20 2a 2a 70 70 46 69 6c 65 2c 20 69 6e 74  le **ppFile, int
5fc0: 20 64 65 6c 46 6c 61 67 29 7b 0a 20 20 69 6e 74   delFlag){.  int
5fd0: 20 72 63 20 3d 20 61 73 79 6e 63 4f 70 65 6e 46   rc = asyncOpenF
5fe0: 69 6c 65 28 7a 2c 20 70 70 46 69 6c 65 2c 20 30  ile(z, ppFile, 0
5ff0: 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  , 0);.  if( rc==
6000: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
6010: 20 41 73 79 6e 63 46 69 6c 65 20 2a 70 46 69 6c   AsyncFile *pFil
6020: 65 20 3d 20 28 41 73 79 6e 63 46 69 6c 65 20 2a  e = (AsyncFile *
6030: 29 28 2a 70 70 46 69 6c 65 29 3b 0a 20 20 20 20  )(*ppFile);.    
6040: 69 6e 74 20 6e 42 79 74 65 20 3d 20 73 74 72 6c  int nByte = strl
6050: 65 6e 28 7a 29 2b 31 3b 0a 20 20 20 20 69 36 34  en(z)+1;.    i64
6060: 20 69 20 3d 20 28 69 36 34 29 28 64 65 6c 46 6c   i = (i64)(delFl
6070: 61 67 29 3b 0a 20 20 20 20 72 63 20 3d 20 61 64  ag);.    rc = ad
6080: 64 4e 65 77 41 73 79 6e 63 57 72 69 74 65 28 70  dNewAsyncWrite(p
6090: 46 69 6c 65 2c 20 41 53 59 4e 43 5f 4f 50 45 4e  File, ASYNC_OPEN
60a0: 45 58 43 4c 55 53 49 56 45 2c 20 69 2c 20 6e 42  EXCLUSIVE, i, nB
60b0: 79 74 65 2c 20 7a 29 3b 0a 20 20 20 20 69 66 28  yte, z);.    if(
60c0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
60d0: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f  {.      sqlite3O
60e0: 73 46 72 65 65 28 70 46 69 6c 65 29 3b 0a 20 20  sFree(pFile);.  
60f0: 20 20 20 20 2a 70 70 46 69 6c 65 20 3d 20 30 3b      *ppFile = 0;
6100: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28  .    }.  }.  if(
6110: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
6120: 7b 0a 20 20 20 20 69 6e 63 72 4f 70 65 6e 46 69  {.    incrOpenFi
6130: 6c 65 43 6f 75 6e 74 28 29 3b 0a 20 20 7d 0a 20  leCount();.  }. 
6140: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74   return rc;.}.st
6150: 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 4f 70  atic int asyncOp
6160: 65 6e 52 65 61 64 4f 6e 6c 79 28 63 6f 6e 73 74  enReadOnly(const
6170: 20 63 68 61 72 20 2a 7a 2c 20 4f 73 46 69 6c 65   char *z, OsFile
6180: 20 2a 2a 70 70 46 69 6c 65 29 7b 0a 20 20 4f 73   **ppFile){.  Os
6190: 46 69 6c 65 20 2a 70 42 61 73 65 20 3d 20 30 3b  File *pBase = 0;
61a0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 78 4f 72 69  .  int rc = xOri
61b0: 67 4f 70 65 6e 52 65 61 64 4f 6e 6c 79 28 7a 2c  gOpenReadOnly(z,
61c0: 20 26 70 42 61 73 65 29 3b 0a 20 20 69 66 28 20   &pBase);.  if( 
61d0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
61e0: 0a 20 20 20 20 72 63 20 3d 20 61 73 79 6e 63 4f  .    rc = asyncO
61f0: 70 65 6e 46 69 6c 65 28 7a 2c 20 70 70 46 69 6c  penFile(z, ppFil
6200: 65 2c 20 70 42 61 73 65 2c 20 30 29 3b 0a 20 20  e, pBase, 0);.  
6210: 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  }.  if( rc==SQLI
6220: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 63  TE_OK ){.    inc
6230: 72 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74 28 29  rOpenFileCount()
6240: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
6250: 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  c;.}.static int 
6260: 61 73 79 6e 63 4f 70 65 6e 52 65 61 64 57 72 69  asyncOpenReadWri
6270: 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  te(const char *z
6280: 2c 20 4f 73 46 69 6c 65 20 2a 2a 70 70 46 69 6c  , OsFile **ppFil
6290: 65 2c 20 69 6e 74 20 2a 70 52 65 61 64 4f 6e 6c  e, int *pReadOnl
62a0: 79 29 7b 0a 20 20 4f 73 46 69 6c 65 20 2a 70 42  y){.  OsFile *pB
62b0: 61 73 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72  ase = 0;.  int r
62c0: 63 20 3d 20 78 4f 72 69 67 4f 70 65 6e 52 65 61  c = xOrigOpenRea
62d0: 64 57 72 69 74 65 28 7a 2c 20 26 70 42 61 73 65  dWrite(z, &pBase
62e0: 2c 20 70 52 65 61 64 4f 6e 6c 79 29 3b 0a 20 20  , pReadOnly);.  
62f0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6300: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 61 73  K ){.    rc = as
6310: 79 6e 63 4f 70 65 6e 46 69 6c 65 28 7a 2c 20 70  yncOpenFile(z, p
6320: 70 46 69 6c 65 2c 20 70 42 61 73 65 2c 20 28 2a  pFile, pBase, (*
6330: 70 52 65 61 64 4f 6e 6c 79 20 3f 20 30 20 3a 20  pReadOnly ? 0 : 
6340: 31 29 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  1));.  }.  if( r
6350: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
6360: 20 20 20 20 69 6e 63 72 4f 70 65 6e 46 69 6c 65      incrOpenFile
6370: 43 6f 75 6e 74 28 29 3b 0a 20 20 7d 0a 20 20 72  Count();.  }.  r
6380: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
6390: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
63a0: 6e 20 6f 66 20 73 71 6c 69 74 65 33 4f 73 44 65  n of sqlite3OsDe
63b0: 6c 65 74 65 2e 20 41 64 64 20 61 6e 20 65 6e 74  lete. Add an ent
63c0: 72 79 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66  ry to the end of
63d0: 20 74 68 65 20 0a 2a 2a 20 77 72 69 74 65 2d 6f   the .** write-o
63e0: 70 20 71 75 65 75 65 20 74 6f 20 70 65 72 66 6f  p queue to perfo
63f0: 72 6d 20 74 68 65 20 64 65 6c 65 74 65 2e 0a 2a  rm the delete..*
6400: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 73 79  /.static int asy
6410: 6e 63 44 65 6c 65 74 65 28 63 6f 6e 73 74 20 63  ncDelete(const c
6420: 68 61 72 20 2a 7a 29 7b 0a 20 20 72 65 74 75 72  har *z){.  retur
6430: 6e 20 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69  n addNewAsyncWri
6440: 74 65 28 30 2c 20 41 53 59 4e 43 5f 44 45 4c 45  te(0, ASYNC_DELE
6450: 54 45 2c 20 30 2c 20 73 74 72 6c 65 6e 28 7a 29  TE, 0, strlen(z)
6460: 2b 31 2c 20 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  +1, z);.}../*.**
6470: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
6480: 6f 66 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63  of sqlite3OsSync
6490: 44 69 72 65 63 74 6f 72 79 2e 20 41 64 64 20 61  Directory. Add a
64a0: 6e 20 65 6e 74 72 79 20 74 6f 20 74 68 65 20 65  n entry to the e
64b0: 6e 64 20 6f 66 20 74 68 65 20 0a 2a 2a 20 77 72  nd of the .** wr
64c0: 69 74 65 2d 6f 70 20 71 75 65 75 65 20 74 6f 20  ite-op queue to 
64d0: 70 65 72 66 6f 72 6d 20 74 68 65 20 64 69 72 65  perform the dire
64e0: 63 74 6f 72 79 20 73 79 6e 63 2e 0a 2a 2f 0a 73  ctory sync..*/.s
64f0: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 53  tatic int asyncS
6500: 79 6e 63 44 69 72 65 63 74 6f 72 79 28 63 6f 6e  yncDirectory(con
6510: 73 74 20 63 68 61 72 20 2a 7a 29 7b 0a 20 20 72  st char *z){.  r
6520: 65 74 75 72 6e 20 61 64 64 4e 65 77 41 73 79 6e  eturn addNewAsyn
6530: 63 57 72 69 74 65 28 30 2c 20 41 53 59 4e 43 5f  cWrite(0, ASYNC_
6540: 53 59 4e 43 44 49 52 45 43 54 4f 52 59 2c 20 30  SYNCDIRECTORY, 0
6550: 2c 20 73 74 72 6c 65 6e 28 7a 29 2b 31 2c 20 7a  , strlen(z)+1, z
6560: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
6570: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 71  ementation of sq
6580: 6c 69 74 65 33 4f 73 46 69 6c 65 45 78 69 73 74  lite3OsFileExist
6590: 73 2e 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  s. Return true i
65a0: 66 20 66 69 6c 65 20 27 7a 27 20 65 78 69 73 74  f file 'z' exist
65b0: 73 0a 2a 2a 20 69 6e 20 74 68 65 20 66 69 6c 65  s.** in the file
65c0: 20 73 79 73 74 65 6d 2e 20 0a 2a 2a 0a 2a 2a 20   system. .**.** 
65d0: 54 68 69 73 20 6d 65 74 68 6f 64 20 68 6f 6c 64  This method hold
65e0: 73 20 74 68 65 20 6d 75 74 65 78 20 66 72 6f 6d  s the mutex from
65f0: 20 73 74 61 72 74 20 74 6f 20 66 69 6e 69 73 68   start to finish
6600: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
6610: 61 73 79 6e 63 46 69 6c 65 45 78 69 73 74 73 28  asyncFileExists(
6620: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 29 7b 0a  const char *z){.
6630: 20 20 69 6e 74 20 72 65 74 3b 0a 20 20 41 73 79    int ret;.  Asy
6640: 6e 63 57 72 69 74 65 20 2a 70 3b 0a 0a 20 20 70  ncWrite *p;..  p
6650: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63  thread_mutex_loc
6660: 6b 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75  k(&async.queueMu
6670: 74 65 78 29 3b 0a 0a 20 20 2f 2a 20 53 65 65 20  tex);..  /* See 
6680: 69 66 20 74 68 65 20 72 65 61 6c 20 66 69 6c 65  if the real file
6690: 20 73 79 73 74 65 6d 20 63 6f 6e 74 61 69 6e 73   system contains
66a0: 20 74 68 65 20 73 70 65 63 69 66 69 65 64 20 66   the specified f
66b0: 69 6c 65 2e 20 20 2a 2f 0a 20 20 72 65 74 20 3d  ile.  */.  ret =
66c0: 20 78 4f 72 69 67 46 69 6c 65 45 78 69 73 74 73   xOrigFileExists
66d0: 28 7a 29 3b 0a 20 20 0a 20 20 66 6f 72 28 70 3d  (z);.  .  for(p=
66e0: 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73  async.pQueueFirs
66f0: 74 3b 20 70 3b 20 70 20 3d 20 70 2d 3e 70 4e 65  t; p; p = p->pNe
6700: 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e  xt){.    if( p->
6710: 6f 70 3d 3d 41 53 59 4e 43 5f 44 45 4c 45 54 45  op==ASYNC_DELETE
6720: 20 26 26 20 30 3d 3d 73 74 72 63 6d 70 28 70 2d   && 0==strcmp(p-
6730: 3e 7a 42 75 66 2c 20 7a 29 20 29 7b 0a 20 20 20  >zBuf, z) ){.   
6740: 20 20 20 72 65 74 20 3d 20 30 3b 0a 20 20 20 20     ret = 0;.    
6750: 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 6f 70 3d  }else if( p->op=
6760: 3d 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55  =ASYNC_OPENEXCLU
6770: 53 49 56 45 20 26 26 20 30 3d 3d 73 74 72 63 6d  SIVE && 0==strcm
6780: 70 28 70 2d 3e 7a 42 75 66 2c 20 7a 29 20 29 7b  p(p->zBuf, z) ){
6790: 0a 20 20 20 20 20 20 72 65 74 20 3d 20 31 3b 0a  .      ret = 1;.
67a0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 54 52 41      }.  }..  TRA
67b0: 43 45 28 28 22 45 58 49 53 54 53 3a 20 25 73 20  CE(("EXISTS: %s 
67c0: 3d 20 25 64 5c 6e 22 2c 20 7a 2c 20 72 65 74 29  = %d\n", z, ret)
67d0: 29 3b 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74  );.  pthread_mut
67e0: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63  ex_unlock(&async
67f0: 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20  .queueMutex);.  
6800: 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 2f  return ret;.}../
6810: 2a 0a 2a 2a 20 43 61 6c 6c 20 74 68 69 73 20 72  *.** Call this r
6820: 6f 75 74 69 6e 65 20 74 6f 20 65 6e 61 62 6c 65  outine to enable
6830: 20 6f 72 20 64 69 73 61 62 6c 65 20 74 68 65 0a   or disable the.
6840: 2a 2a 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20  ** asynchronous 
6850: 49 4f 20 66 65 61 74 75 72 65 73 20 69 6d 70 6c  IO features impl
6860: 65 6d 65 6e 74 65 64 20 69 6e 20 74 68 69 73 20  emented in this 
6870: 66 69 6c 65 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69  file. .**.** Thi
6880: 73 20 72 6f 75 74 69 6e 65 20 69 73 20 6e 6f 74  s routine is not
6890: 20 65 76 65 6e 20 72 65 6d 6f 74 65 6c 79 20 74   even remotely t
68a0: 68 72 65 61 64 73 61 66 65 2e 20 20 44 6f 20 6e  hreadsafe.  Do n
68b0: 6f 74 20 63 61 6c 6c 0a 2a 2a 20 74 68 69 73 20  ot call.** this 
68c0: 72 6f 75 74 69 6e 65 20 77 68 69 6c 65 20 61 6e  routine while an
68d0: 79 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73  y SQLite databas
68e0: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72  e connections ar
68f0: 65 20 6f 70 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69  e open..*/.stati
6900: 63 20 76 6f 69 64 20 61 73 79 6e 63 45 6e 61 62  c void asyncEnab
6910: 6c 65 28 69 6e 74 20 65 6e 61 62 6c 65 29 7b 0a  le(int enable){.
6920: 20 20 69 66 28 20 65 6e 61 62 6c 65 20 26 26 20    if( enable && 
6930: 78 4f 72 69 67 4f 70 65 6e 52 65 61 64 57 72 69  xOrigOpenReadWri
6940: 74 65 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 73  te==0 ){.    ass
6950: 65 72 74 28 73 71 6c 69 74 65 33 4f 73 2e 78 4f  ert(sqlite3Os.xO
6960: 70 65 6e 52 65 61 64 57 72 69 74 65 29 3b 0a 20  penReadWrite);. 
6970: 20 20 20 73 71 6c 69 74 65 33 48 61 73 68 49 6e     sqlite3HashIn
6980: 69 74 28 26 61 73 79 6e 63 2e 61 4c 6f 63 6b 2c  it(&async.aLock,
6990: 20 53 51 4c 49 54 45 5f 48 41 53 48 5f 42 49 4e   SQLITE_HASH_BIN
69a0: 41 52 59 2c 20 31 29 3b 0a 20 20 20 20 78 4f 72  ARY, 1);.    xOr
69b0: 69 67 4f 70 65 6e 52 65 61 64 57 72 69 74 65 20  igOpenReadWrite 
69c0: 3d 20 73 71 6c 69 74 65 33 4f 73 2e 78 4f 70 65  = sqlite3Os.xOpe
69d0: 6e 52 65 61 64 57 72 69 74 65 3b 0a 20 20 20 20  nReadWrite;.    
69e0: 78 4f 72 69 67 4f 70 65 6e 52 65 61 64 4f 6e 6c  xOrigOpenReadOnl
69f0: 79 20 3d 20 73 71 6c 69 74 65 33 4f 73 2e 78 4f  y = sqlite3Os.xO
6a00: 70 65 6e 52 65 61 64 4f 6e 6c 79 3b 0a 20 20 20  penReadOnly;.   
6a10: 20 78 4f 72 69 67 4f 70 65 6e 45 78 63 6c 75 73   xOrigOpenExclus
6a20: 69 76 65 20 3d 20 73 71 6c 69 74 65 33 4f 73 2e  ive = sqlite3Os.
6a30: 78 4f 70 65 6e 45 78 63 6c 75 73 69 76 65 3b 0a  xOpenExclusive;.
6a40: 20 20 20 20 78 4f 72 69 67 44 65 6c 65 74 65 20      xOrigDelete 
6a50: 3d 20 73 71 6c 69 74 65 33 4f 73 2e 78 44 65 6c  = sqlite3Os.xDel
6a60: 65 74 65 3b 0a 20 20 20 20 78 4f 72 69 67 46 69  ete;.    xOrigFi
6a70: 6c 65 45 78 69 73 74 73 20 3d 20 73 71 6c 69 74  leExists = sqlit
6a80: 65 33 4f 73 2e 78 46 69 6c 65 45 78 69 73 74 73  e3Os.xFileExists
6a90: 3b 0a 20 20 20 20 78 4f 72 69 67 53 79 6e 63 44  ;.    xOrigSyncD
6aa0: 69 72 65 63 74 6f 72 79 20 3d 20 73 71 6c 69 74  irectory = sqlit
6ab0: 65 33 4f 73 2e 78 53 79 6e 63 44 69 72 65 63 74  e3Os.xSyncDirect
6ac0: 6f 72 79 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65  ory;..    sqlite
6ad0: 33 4f 73 2e 78 4f 70 65 6e 52 65 61 64 57 72 69  3Os.xOpenReadWri
6ae0: 74 65 20 3d 20 61 73 79 6e 63 4f 70 65 6e 52 65  te = asyncOpenRe
6af0: 61 64 57 72 69 74 65 3b 0a 20 20 20 20 73 71 6c  adWrite;.    sql
6b00: 69 74 65 33 4f 73 2e 78 4f 70 65 6e 52 65 61 64  ite3Os.xOpenRead
6b10: 4f 6e 6c 79 20 3d 20 61 73 79 6e 63 4f 70 65 6e  Only = asyncOpen
6b20: 52 65 61 64 4f 6e 6c 79 3b 0a 20 20 20 20 73 71  ReadOnly;.    sq
6b30: 6c 69 74 65 33 4f 73 2e 78 4f 70 65 6e 45 78 63  lite3Os.xOpenExc
6b40: 6c 75 73 69 76 65 20 3d 20 61 73 79 6e 63 4f 70  lusive = asyncOp
6b50: 65 6e 45 78 63 6c 75 73 69 76 65 3b 0a 20 20 20  enExclusive;.   
6b60: 20 73 71 6c 69 74 65 33 4f 73 2e 78 44 65 6c 65   sqlite3Os.xDele
6b70: 74 65 20 3d 20 61 73 79 6e 63 44 65 6c 65 74 65  te = asyncDelete
6b80: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 2e  ;.    sqlite3Os.
6b90: 78 46 69 6c 65 45 78 69 73 74 73 20 3d 20 61 73  xFileExists = as
6ba0: 79 6e 63 46 69 6c 65 45 78 69 73 74 73 3b 0a 20  yncFileExists;. 
6bb0: 20 20 20 73 71 6c 69 74 65 33 4f 73 2e 78 53 79     sqlite3Os.xSy
6bc0: 6e 63 44 69 72 65 63 74 6f 72 79 20 3d 20 61 73  ncDirectory = as
6bd0: 79 6e 63 53 79 6e 63 44 69 72 65 63 74 6f 72 79  yncSyncDirectory
6be0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 73 71 6c  ;.    assert(sql
6bf0: 69 74 65 33 4f 73 2e 78 4f 70 65 6e 52 65 61 64  ite3Os.xOpenRead
6c00: 57 72 69 74 65 29 3b 0a 20 20 7d 0a 20 20 69 66  Write);.  }.  if
6c10: 28 20 21 65 6e 61 62 6c 65 20 26 26 20 78 4f 72  ( !enable && xOr
6c20: 69 67 4f 70 65 6e 52 65 61 64 57 72 69 74 65 21  igOpenReadWrite!
6c30: 3d 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  =0 ){.    assert
6c40: 28 73 71 6c 69 74 65 33 4f 73 2e 78 4f 70 65 6e  (sqlite3Os.xOpen
6c50: 52 65 61 64 57 72 69 74 65 29 3b 0a 20 20 20 20  ReadWrite);.    
6c60: 73 71 6c 69 74 65 33 48 61 73 68 43 6c 65 61 72  sqlite3HashClear
6c70: 28 26 61 73 79 6e 63 2e 61 4c 6f 63 6b 29 3b 0a  (&async.aLock);.
6c80: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 2e 78 4f      sqlite3Os.xO
6c90: 70 65 6e 52 65 61 64 57 72 69 74 65 20 3d 20 78  penReadWrite = x
6ca0: 4f 72 69 67 4f 70 65 6e 52 65 61 64 57 72 69 74  OrigOpenReadWrit
6cb0: 65 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  e;.    sqlite3Os
6cc0: 2e 78 4f 70 65 6e 52 65 61 64 4f 6e 6c 79 20 3d  .xOpenReadOnly =
6cd0: 20 78 4f 72 69 67 4f 70 65 6e 52 65 61 64 4f 6e   xOrigOpenReadOn
6ce0: 6c 79 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f  ly;.    sqlite3O
6cf0: 73 2e 78 4f 70 65 6e 45 78 63 6c 75 73 69 76 65  s.xOpenExclusive
6d00: 20 3d 20 78 4f 72 69 67 4f 70 65 6e 45 78 63 6c   = xOrigOpenExcl
6d10: 75 73 69 76 65 3b 0a 20 20 20 20 73 71 6c 69 74  usive;.    sqlit
6d20: 65 33 4f 73 2e 78 44 65 6c 65 74 65 20 3d 20 78  e3Os.xDelete = x
6d30: 4f 72 69 67 44 65 6c 65 74 65 3b 0a 20 20 20 20  OrigDelete;.    
6d40: 73 71 6c 69 74 65 33 4f 73 2e 78 46 69 6c 65 45  sqlite3Os.xFileE
6d50: 78 69 73 74 73 20 3d 20 78 4f 72 69 67 46 69 6c  xists = xOrigFil
6d60: 65 45 78 69 73 74 73 3b 0a 20 20 20 20 73 71 6c  eExists;.    sql
6d70: 69 74 65 33 4f 73 2e 78 53 79 6e 63 44 69 72 65  ite3Os.xSyncDire
6d80: 63 74 6f 72 79 20 3d 20 78 4f 72 69 67 53 79 6e  ctory = xOrigSyn
6d90: 63 44 69 72 65 63 74 6f 72 79 3b 0a 0a 20 20 20  cDirectory;..   
6da0: 20 78 4f 72 69 67 4f 70 65 6e 52 65 61 64 57 72   xOrigOpenReadWr
6db0: 69 74 65 20 3d 20 30 3b 0a 20 20 20 20 78 4f 72  ite = 0;.    xOr
6dc0: 69 67 4f 70 65 6e 52 65 61 64 4f 6e 6c 79 20 3d  igOpenReadOnly =
6dd0: 20 30 3b 0a 20 20 20 20 78 4f 72 69 67 4f 70 65   0;.    xOrigOpe
6de0: 6e 45 78 63 6c 75 73 69 76 65 20 3d 20 30 3b 0a  nExclusive = 0;.
6df0: 20 20 20 20 78 4f 72 69 67 44 65 6c 65 74 65 20      xOrigDelete 
6e00: 3d 20 30 3b 0a 20 20 20 20 78 4f 72 69 67 46 69  = 0;.    xOrigFi
6e10: 6c 65 45 78 69 73 74 73 20 3d 20 30 3b 0a 20 20  leExists = 0;.  
6e20: 20 20 78 4f 72 69 67 53 79 6e 63 44 69 72 65 63    xOrigSyncDirec
6e30: 74 6f 72 79 20 3d 20 30 3b 0a 20 20 20 20 61 73  tory = 0;.    as
6e40: 73 65 72 74 28 73 71 6c 69 74 65 33 4f 73 2e 78  sert(sqlite3Os.x
6e50: 4f 70 65 6e 52 65 61 64 57 72 69 74 65 29 3b 0a  OpenReadWrite);.
6e60: 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68    }.}../* .** Th
6e70: 69 73 20 70 72 6f 63 65 64 75 72 65 20 72 75 6e  is procedure run
6e80: 73 20 69 6e 20 61 20 73 65 70 61 72 61 74 65 20  s in a separate 
6e90: 74 68 72 65 61 64 2c 20 72 65 61 64 69 6e 67 20  thread, reading 
6ea0: 6d 65 73 73 61 67 65 73 20 6f 66 66 20 6f 66 20  messages off of 
6eb0: 74 68 65 0a 2a 2a 20 77 72 69 74 65 20 71 75 65  the.** write que
6ec0: 75 65 20 61 6e 64 20 70 72 6f 63 65 73 73 69 6e  ue and processin
6ed0: 67 20 74 68 65 6d 20 6f 6e 65 20 62 79 20 6f 6e  g them one by on
6ee0: 65 2e 20 20 0a 2a 2a 0a 2a 2a 20 49 66 20 61 73  e.  .**.** If as
6ef0: 79 6e 63 2e 77 72 69 74 65 72 48 61 6c 74 4e 6f  ync.writerHaltNo
6f00: 77 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20  w is true, then 
6f10: 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 65  this procedure e
6f20: 78 69 74 73 0a 2a 2a 20 61 66 74 65 72 20 70 72  xits.** after pr
6f30: 6f 63 65 73 73 69 6e 67 20 61 20 73 69 6e 67 6c  ocessing a singl
6f40: 65 20 6d 65 73 73 61 67 65 2e 0a 2a 2a 0a 2a 2a  e message..**.**
6f50: 20 49 66 20 61 73 79 6e 63 2e 77 72 69 74 65 72   If async.writer
6f60: 48 61 6c 74 57 68 65 6e 49 64 6c 65 20 69 73 20  HaltWhenIdle is 
6f70: 74 72 75 65 2c 20 74 68 65 6e 20 74 68 69 73 20  true, then this 
6f80: 70 72 6f 63 65 64 75 72 65 20 65 78 69 74 73 20  procedure exits 
6f90: 77 68 65 6e 0a 2a 2a 20 74 68 65 20 77 72 69 74  when.** the writ
6fa0: 65 20 71 75 65 75 65 20 69 73 20 65 6d 70 74 79  e queue is empty
6fb0: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 62 6f 74 68 20  ..**.** If both 
6fc0: 6f 66 20 74 68 65 20 61 62 6f 76 65 20 76 61 72  of the above var
6fd0: 69 61 62 6c 65 73 20 61 72 65 20 66 61 6c 73 65  iables are false
6fe0: 2c 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65  , this procedure
6ff0: 20 72 75 6e 73 0a 2a 2a 20 69 6e 64 65 66 69 6e   runs.** indefin
7000: 61 74 65 6c 79 2c 20 77 61 69 74 69 6e 67 20 66  ately, waiting f
7010: 6f 72 20 6f 70 65 72 61 74 69 6f 6e 73 20 74 6f  or operations to
7020: 20 62 65 20 61 64 64 65 64 20 74 6f 20 74 68 65   be added to the
7030: 20 77 72 69 74 65 20 71 75 65 75 65 0a 2a 2a 20   write queue.** 
7040: 61 6e 64 20 70 72 6f 63 65 73 73 69 6e 67 20 74  and processing t
7050: 68 65 6d 20 69 6e 20 74 68 65 20 6f 72 64 65 72  hem in the order
7060: 20 69 6e 20 77 68 69 63 68 20 74 68 65 79 20 61   in which they a
7070: 72 72 69 76 65 2e 0a 2a 2a 0a 2a 2a 20 41 6e 20  rrive..**.** An 
7080: 61 72 74 69 66 69 63 61 6c 20 64 65 6c 61 79 20  artifical delay 
7090: 6f 66 20 61 73 79 6e 63 2e 69 6f 44 65 6c 61 79  of async.ioDelay
70a0: 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73 20 69 73   milliseconds is
70b0: 20 69 6e 73 65 72 74 65 64 20 62 65 66 6f 72 65   inserted before
70c0: 0a 2a 2a 20 65 61 63 68 20 77 72 69 74 65 20 6f  .** each write o
70d0: 70 65 72 61 74 69 6f 6e 20 69 6e 20 6f 72 64 65  peration in orde
70e0: 72 20 74 6f 20 73 69 6d 75 6c 61 74 65 20 74 68  r to simulate th
70f0: 65 20 65 66 66 65 63 74 20 6f 66 20 61 20 73 6c  e effect of a sl
7100: 6f 77 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a 20 4f  ow disk..**.** O
7110: 6e 6c 79 20 6f 6e 65 20 69 6e 73 74 61 6e 63 65  nly one instance
7120: 20 6f 66 20 74 68 69 73 20 70 72 6f 63 65 64 75   of this procedu
7130: 72 65 20 6d 61 79 20 62 65 20 72 75 6e 6e 69 6e  re may be runnin
7140: 67 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2f 0a  g at a time..*/.
7150: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 61 73 79  static void *asy
7160: 6e 63 57 72 69 74 65 72 54 68 72 65 61 64 28 76  ncWriterThread(v
7170: 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20  oid *NotUsed){. 
7180: 20 41 73 79 6e 63 57 72 69 74 65 20 2a 70 20 3d   AsyncWrite *p =
7190: 20 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   0;.  int rc = S
71a0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20  QLITE_OK;.  int 
71b0: 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20 30  holdingMutex = 0
71c0: 3b 0a 0a 20 20 69 66 28 20 70 74 68 72 65 61 64  ;..  if( pthread
71d0: 5f 6d 75 74 65 78 5f 74 72 79 6c 6f 63 6b 28 26  _mutex_trylock(&
71e0: 61 73 79 6e 63 2e 77 72 69 74 65 72 4d 75 74 65  async.writerMute
71f0: 78 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  x) ){.    return
7200: 20 30 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28   0;.  }.  while(
7210: 20 61 73 79 6e 63 2e 77 72 69 74 65 72 48 61 6c   async.writerHal
7220: 74 4e 6f 77 3d 3d 30 20 29 7b 0a 20 20 20 20 4f  tNow==0 ){.    O
7230: 73 46 69 6c 65 20 2a 70 42 61 73 65 20 3d 20 30  sFile *pBase = 0
7240: 3b 0a 0a 20 20 20 20 69 66 28 20 21 68 6f 6c 64  ;..    if( !hold
7250: 69 6e 67 4d 75 74 65 78 20 29 7b 0a 20 20 20 20  ingMutex ){.    
7260: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
7270: 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 71 75 65 75  lock(&async.queu
7280: 65 4d 75 74 65 78 29 3b 0a 20 20 20 20 7d 0a 20  eMutex);.    }. 
7290: 20 20 20 77 68 69 6c 65 28 20 28 70 20 3d 20 61     while( (p = a
72a0: 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74  sync.pQueueFirst
72b0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 74  )==0 ){.      pt
72c0: 68 72 65 61 64 5f 63 6f 6e 64 5f 62 72 6f 61 64  hread_cond_broad
72d0: 63 61 73 74 28 26 61 73 79 6e 63 2e 65 6d 70 74  cast(&async.empt
72e0: 79 53 69 67 6e 61 6c 29 3b 0a 20 20 20 20 20 20  ySignal);.      
72f0: 69 66 28 20 61 73 79 6e 63 2e 77 72 69 74 65 72  if( async.writer
7300: 48 61 6c 74 57 68 65 6e 49 64 6c 65 20 29 7b 0a  HaltWhenIdle ){.
7310: 20 20 20 20 20 20 20 20 70 74 68 72 65 61 64 5f          pthread_
7320: 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73  mutex_unlock(&as
7330: 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b  ync.queueMutex);
7340: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
7350: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
7360: 20 20 20 20 20 54 52 41 43 45 28 28 22 49 44 4c       TRACE(("IDL
7370: 45 5c 6e 22 29 29 3b 0a 20 20 20 20 20 20 20 20  E\n"));.        
7380: 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f 77 61 69  pthread_cond_wai
7390: 74 28 26 61 73 79 6e 63 2e 71 75 65 75 65 53 69  t(&async.queueSi
73a0: 67 6e 61 6c 2c 20 26 61 73 79 6e 63 2e 71 75 65  gnal, &async.que
73b0: 75 65 4d 75 74 65 78 29 3b 0a 20 20 20 20 20 20  ueMutex);.      
73c0: 20 20 54 52 41 43 45 28 28 22 57 41 4b 45 55 50    TRACE(("WAKEUP
73d0: 5c 6e 22 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20  \n"));.      }. 
73e0: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 3d 3d     }.    if( p==
73f0: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 68  0 ) break;.    h
7400: 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20 31 3b  oldingMutex = 1;
7410: 0a 0a 20 20 20 20 2f 2a 20 52 69 67 68 74 20 6e  ..    /* Right n
7420: 6f 77 20 74 68 69 73 20 74 68 72 65 61 64 20 69  ow this thread i
7430: 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 6d 75  s holding the mu
7440: 74 65 78 20 6f 6e 20 74 68 65 20 77 72 69 74 65  tex on the write
7450: 2d 6f 70 20 71 75 65 75 65 2e 0a 20 20 20 20 2a  -op queue..    *
7460: 2a 20 56 61 72 69 61 62 6c 65 20 27 70 27 20 70  * Variable 'p' p
7470: 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 66 69 72  oints to the fir
7480: 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20  st entry in the 
7490: 77 72 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 20  write-op queue. 
74a0: 49 6e 0a 20 20 20 20 2a 2a 20 74 68 65 20 67 65  In.    ** the ge
74b0: 6e 65 72 61 6c 20 63 61 73 65 2c 20 77 65 20 68  neral case, we h
74c0: 6f 6c 64 20 6f 6e 20 74 6f 20 74 68 65 20 6d 75  old on to the mu
74d0: 74 65 78 20 66 6f 72 20 74 68 65 20 65 6e 74 69  tex for the enti
74e0: 72 65 20 62 6f 64 79 20 6f 66 0a 20 20 20 20 2a  re body of.    *
74f0: 2a 20 74 68 65 20 6c 6f 6f 70 2e 20 0a 20 20 20  * the loop. .   
7500: 20 2a 2a 0a 20 20 20 20 2a 2a 20 48 6f 77 65 76   **.    ** Howev
7510: 65 72 20 69 6e 20 74 68 65 20 63 61 73 65 73 20  er in the cases 
7520: 65 6e 75 6d 65 72 61 74 65 64 20 62 65 6c 6f 77  enumerated below
7530: 2c 20 77 65 20 72 65 6c 69 6e 71 75 69 73 68 20  , we relinquish 
7540: 74 68 65 20 6d 75 74 65 78 2c 0a 20 20 20 20 2a  the mutex,.    *
7550: 2a 20 70 65 72 66 6f 72 6d 20 74 68 65 20 49 4f  * perform the IO
7560: 2c 20 61 6e 64 20 74 68 65 6e 20 72 65 2d 72 65  , and then re-re
7570: 71 75 65 73 74 20 74 68 65 20 6d 75 74 65 78 20  quest the mutex 
7580: 62 65 66 6f 72 65 20 72 65 6d 6f 76 69 6e 67 20  before removing 
7590: 27 70 27 20 66 72 6f 6d 0a 20 20 20 20 2a 2a 20  'p' from.    ** 
75a0: 74 68 65 20 68 65 61 64 20 6f 66 20 74 68 65 20  the head of the 
75b0: 77 72 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 20  write-op queue. 
75c0: 54 68 65 20 69 64 65 61 20 69 73 20 74 6f 20 69  The idea is to i
75d0: 6e 63 72 65 61 73 65 20 63 6f 6e 63 75 72 72 65  ncrease concurre
75e0: 6e 63 79 20 77 69 74 68 0a 20 20 20 20 2a 2a 20  ncy with.    ** 
75f0: 73 71 6c 69 74 65 20 74 68 72 65 61 64 73 2e 0a  sqlite threads..
7600: 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20 20      **.    **   
7610: 20 20 2a 20 41 6e 20 41 53 59 4e 43 5f 43 4c 4f    * An ASYNC_CLO
7620: 53 45 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 20 20  SE operation..  
7630: 20 20 2a 2a 20 20 20 20 20 2a 20 41 6e 20 41 53    **     * An AS
7640: 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56  YNC_OPENEXCLUSIV
7650: 45 20 6f 70 65 72 61 74 69 6f 6e 2e 20 46 6f 72  E operation. For
7660: 20 74 68 69 73 20 6f 6e 65 2c 20 77 65 20 72 65   this one, we re
7670: 6c 69 6e 71 75 69 73 68 20 0a 20 20 20 20 2a 2a  linquish .    **
7680: 20 20 20 20 20 20 20 74 68 65 20 6d 75 74 65 78         the mutex
7690: 2c 20 63 61 6c 6c 20 74 68 65 20 75 6e 64 65 72  , call the under
76a0: 6c 79 69 6e 67 20 78 4f 70 65 6e 45 78 63 6c 75  lying xOpenExclu
76b0: 73 69 76 65 28 29 20 66 75 6e 63 74 69 6f 6e 2c  sive() function,
76c0: 20 74 68 65 6e 0a 20 20 20 20 2a 2a 20 20 20 20   then.    **    
76d0: 20 20 20 72 65 2d 61 71 75 69 72 65 20 74 68 65     re-aquire the
76e0: 20 6d 75 74 65 78 20 62 65 66 6f 72 65 20 73 65   mutex before se
76f0: 74 69 6e 67 20 74 68 65 20 41 73 79 6e 63 46 69  ting the AsyncFi
7700: 6c 65 2e 70 42 61 73 65 52 65 61 64 20 0a 20 20  le.pBaseRead .  
7710: 20 20 2a 2a 20 20 20 20 20 20 20 76 61 72 69 61    **       varia
7720: 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 20 20 20 20  ble..    **     
7730: 2a 20 41 53 59 4e 43 5f 53 59 4e 43 20 61 6e 64  * ASYNC_SYNC and
7740: 20 41 53 59 4e 43 5f 57 52 49 54 45 20 6f 70 65   ASYNC_WRITE ope
7750: 72 61 74 69 6f 6e 73 2c 20 69 66 20 0a 20 20 20  rations, if .   
7760: 20 2a 2a 20 20 20 20 20 20 20 53 51 4c 49 54 45   **       SQLITE
7770: 5f 41 53 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48  _ASYNC_TWO_FILEH
7780: 41 4e 44 4c 45 53 20 77 61 73 20 73 65 74 20 61  ANDLES was set a
7790: 74 20 63 6f 6d 70 69 6c 65 20 74 69 6d 65 20 61  t compile time a
77a0: 6e 64 20 74 77 6f 0a 20 20 20 20 2a 2a 20 20 20  nd two.    **   
77b0: 20 20 20 20 66 69 6c 65 2d 68 61 6e 64 6c 65 73      file-handles
77c0: 20 61 72 65 20 6f 70 65 6e 20 66 6f 72 20 74 68   are open for th
77d0: 65 20 70 61 72 74 69 63 75 6c 61 72 20 66 69 6c  e particular fil
77e0: 65 20 62 65 69 6e 67 20 22 73 79 6e 63 65 64 22  e being "synced"
77f0: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  ..    */.    if(
7800: 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 21 3d   async.ioError!=
7810: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e  SQLITE_OK && p->
7820: 6f 70 21 3d 41 53 59 4e 43 5f 43 4c 4f 53 45 20  op!=ASYNC_CLOSE 
7830: 29 7b 0a 20 20 20 20 20 20 70 2d 3e 6f 70 20 3d  ){.      p->op =
7840: 20 41 53 59 4e 43 5f 4e 4f 4f 50 3b 0a 20 20 20   ASYNC_NOOP;.   
7850: 20 7d 0a 20 20 20 20 69 66 28 20 70 2d 3e 70 46   }.    if( p->pF
7860: 69 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 42 61  ile ){.      pBa
7870: 73 65 20 3d 20 70 2d 3e 70 46 69 6c 65 2d 3e 70  se = p->pFile->p
7880: 42 61 73 65 57 72 69 74 65 3b 0a 20 20 20 20 20  BaseWrite;.     
7890: 20 69 66 28 20 0a 20 20 20 20 20 20 20 20 70 2d   if( .        p-
78a0: 3e 6f 70 3d 3d 41 53 59 4e 43 5f 43 4c 4f 53 45  >op==ASYNC_CLOSE
78b0: 20 7c 7c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e   || .        p->
78c0: 6f 70 3d 3d 41 53 59 4e 43 5f 4f 50 45 4e 45 58  op==ASYNC_OPENEX
78d0: 43 4c 55 53 49 56 45 20 7c 7c 0a 20 20 20 20 20  CLUSIVE ||.     
78e0: 20 20 20 28 70 42 61 73 65 20 26 26 20 28 70 2d     (pBase && (p-
78f0: 3e 6f 70 3d 3d 41 53 59 4e 43 5f 53 59 4e 43 20  >op==ASYNC_SYNC 
7900: 7c 7c 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f  || p->op==ASYNC_
7910: 57 52 49 54 45 29 20 29 20 0a 20 20 20 20 20 20  WRITE) ) .      
7920: 29 7b 0a 20 20 20 20 20 20 20 20 70 74 68 72 65  ){.        pthre
7930: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
7940: 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65  &async.queueMute
7950: 78 29 3b 0a 20 20 20 20 20 20 20 20 68 6f 6c 64  x);.        hold
7960: 69 6e 67 4d 75 74 65 78 20 3d 20 30 3b 0a 20 20  ingMutex = 0;.  
7970: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
7980: 21 70 42 61 73 65 20 29 7b 0a 20 20 20 20 20 20  !pBase ){.      
7990: 20 20 70 42 61 73 65 20 3d 20 70 2d 3e 70 46 69    pBase = p->pFi
79a0: 6c 65 2d 3e 70 42 61 73 65 52 65 61 64 3b 0a 20  le->pBaseRead;. 
79b0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
79c0: 20 20 73 77 69 74 63 68 28 20 70 2d 3e 6f 70 20    switch( p->op 
79d0: 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20 41 53  ){.      case AS
79e0: 59 4e 43 5f 4e 4f 4f 50 3a 0a 20 20 20 20 20 20  YNC_NOOP:.      
79f0: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20    break;..      
7a00: 63 61 73 65 20 41 53 59 4e 43 5f 57 52 49 54 45  case ASYNC_WRITE
7a10: 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  :.        assert
7a20: 28 20 70 42 61 73 65 20 29 3b 0a 20 20 20 20 20  ( pBase );.     
7a30: 20 20 20 54 52 41 43 45 28 28 22 57 52 49 54 45     TRACE(("WRITE
7a40: 20 25 73 20 25 64 20 62 79 74 65 73 20 61 74 20   %s %d bytes at 
7a50: 25 64 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 20  %d\n",.         
7a60: 20 20 20 20 20 20 20 70 2d 3e 70 46 69 6c 65 2d         p->pFile-
7a70: 3e 7a 4e 61 6d 65 2c 20 70 2d 3e 6e 42 79 74 65  >zName, p->nByte
7a80: 2c 20 70 2d 3e 69 4f 66 66 73 65 74 29 29 3b 0a  , p->iOffset));.
7a90: 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c          rc = sql
7aa0: 69 74 65 33 4f 73 53 65 65 6b 28 70 42 61 73 65  ite3OsSeek(pBase
7ab0: 2c 20 70 2d 3e 69 4f 66 66 73 65 74 29 3b 0a 20  , p->iOffset);. 
7ac0: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
7ad0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
7ae0: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
7af0: 65 33 4f 73 57 72 69 74 65 28 70 42 61 73 65 2c  e3OsWrite(pBase,
7b00: 20 28 63 6f 6e 73 74 20 76 6f 69 64 20 2a 29 28   (const void *)(
7b10: 70 2d 3e 7a 42 75 66 29 2c 20 70 2d 3e 6e 42 79  p->zBuf), p->nBy
7b20: 74 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  te);.        }. 
7b30: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20         break;.. 
7b40: 20 20 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f       case ASYNC_
7b50: 53 59 4e 43 3a 0a 20 20 20 20 20 20 20 20 61 73  SYNC:.        as
7b60: 73 65 72 74 28 20 70 42 61 73 65 20 29 3b 0a 20  sert( pBase );. 
7b70: 20 20 20 20 20 20 20 54 52 41 43 45 28 28 22 53         TRACE(("S
7b80: 59 4e 43 20 25 73 5c 6e 22 2c 20 70 2d 3e 70 46  YNC %s\n", p->pF
7b90: 69 6c 65 2d 3e 7a 4e 61 6d 65 29 29 3b 0a 20 20  ile->zName));.  
7ba0: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
7bb0: 65 33 4f 73 53 79 6e 63 28 70 42 61 73 65 2c 20  e3OsSync(pBase, 
7bc0: 70 2d 3e 6e 42 79 74 65 29 3b 0a 20 20 20 20 20  p->nByte);.     
7bd0: 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20     break;..     
7be0: 20 63 61 73 65 20 41 53 59 4e 43 5f 54 52 55 4e   case ASYNC_TRUN
7bf0: 43 41 54 45 3a 0a 20 20 20 20 20 20 20 20 61 73  CATE:.        as
7c00: 73 65 72 74 28 20 70 42 61 73 65 20 29 3b 0a 20  sert( pBase );. 
7c10: 20 20 20 20 20 20 20 54 52 41 43 45 28 28 22 54         TRACE(("T
7c20: 52 55 4e 43 41 54 45 20 25 73 20 74 6f 20 25 64  RUNCATE %s to %d
7c30: 20 62 79 74 65 73 5c 6e 22 2c 20 70 2d 3e 70 46   bytes\n", p->pF
7c40: 69 6c 65 2d 3e 7a 4e 61 6d 65 2c 20 70 2d 3e 69  ile->zName, p->i
7c50: 4f 66 66 73 65 74 29 29 3b 0a 20 20 20 20 20 20  Offset));.      
7c60: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
7c70: 54 72 75 6e 63 61 74 65 28 70 42 61 73 65 2c 20  Truncate(pBase, 
7c80: 70 2d 3e 69 4f 66 66 73 65 74 29 3b 0a 20 20 20  p->iOffset);.   
7c90: 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
7ca0: 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f 43 4c     case ASYNC_CL
7cb0: 4f 53 45 3a 0a 20 20 20 20 20 20 20 20 54 52 41  OSE:.        TRA
7cc0: 43 45 28 28 22 43 4c 4f 53 45 20 25 73 5c 6e 22  CE(("CLOSE %s\n"
7cd0: 2c 20 70 2d 3e 70 46 69 6c 65 2d 3e 7a 4e 61 6d  , p->pFile->zNam
7ce0: 65 29 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  e));.        sql
7cf0: 69 74 65 33 4f 73 43 6c 6f 73 65 28 26 70 2d 3e  ite3OsClose(&p->
7d00: 70 46 69 6c 65 2d 3e 70 42 61 73 65 57 72 69 74  pFile->pBaseWrit
7d10: 65 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  e);.        sqli
7d20: 74 65 33 4f 73 43 6c 6f 73 65 28 26 70 2d 3e 70  te3OsClose(&p->p
7d30: 46 69 6c 65 2d 3e 70 42 61 73 65 52 65 61 64 29  File->pBaseRead)
7d40: 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  ;.        sqlite
7d50: 33 4f 73 46 72 65 65 28 70 2d 3e 70 46 69 6c 65  3OsFree(p->pFile
7d60: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
7d70: 3b 0a 0a 20 20 20 20 20 20 63 61 73 65 20 41 53  ;..      case AS
7d80: 59 4e 43 5f 4f 50 45 4e 44 49 52 45 43 54 4f 52  YNC_OPENDIRECTOR
7d90: 59 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  Y:.        asser
7da0: 74 28 20 70 42 61 73 65 20 29 3b 0a 20 20 20 20  t( pBase );.    
7db0: 20 20 20 20 54 52 41 43 45 28 28 22 4f 50 45 4e      TRACE(("OPEN
7dc0: 44 49 52 20 25 73 5c 6e 22 2c 20 70 2d 3e 7a 42  DIR %s\n", p->zB
7dd0: 75 66 29 29 3b 0a 20 20 20 20 20 20 20 20 73 71  uf));.        sq
7de0: 6c 69 74 65 33 4f 73 4f 70 65 6e 44 69 72 65 63  lite3OsOpenDirec
7df0: 74 6f 72 79 28 70 42 61 73 65 2c 20 70 2d 3e 7a  tory(pBase, p->z
7e00: 42 75 66 29 3b 0a 20 20 20 20 20 20 20 20 62 72  Buf);.        br
7e10: 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 65  eak;..      case
7e20: 20 41 53 59 4e 43 5f 53 45 54 46 55 4c 4c 53 59   ASYNC_SETFULLSY
7e30: 4e 43 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65  NC:.        asse
7e40: 72 74 28 20 70 42 61 73 65 20 29 3b 0a 20 20 20  rt( pBase );.   
7e50: 20 20 20 20 20 54 52 41 43 45 28 28 22 53 45 54       TRACE(("SET
7e60: 46 55 4c 4c 53 59 4e 43 20 25 73 20 25 64 5c 6e  FULLSYNC %s %d\n
7e70: 22 2c 20 70 2d 3e 70 46 69 6c 65 2d 3e 7a 4e 61  ", p->pFile->zNa
7e80: 6d 65 2c 20 70 2d 3e 6e 42 79 74 65 29 29 3b 0a  me, p->nByte));.
7e90: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f          sqlite3O
7ea0: 73 53 65 74 46 75 6c 6c 53 79 6e 63 28 70 42 61  sSetFullSync(pBa
7eb0: 73 65 2c 20 70 2d 3e 6e 42 79 74 65 29 3b 0a 20  se, p->nByte);. 
7ec0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20         break;.. 
7ed0: 20 20 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f       case ASYNC_
7ee0: 44 45 4c 45 54 45 3a 0a 20 20 20 20 20 20 20 20  DELETE:.        
7ef0: 54 52 41 43 45 28 28 22 44 45 4c 45 54 45 20 25  TRACE(("DELETE %
7f00: 73 5c 6e 22 2c 20 70 2d 3e 7a 42 75 66 29 29 3b  s\n", p->zBuf));
7f10: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 78 4f  .        rc = xO
7f20: 72 69 67 44 65 6c 65 74 65 28 70 2d 3e 7a 42 75  rigDelete(p->zBu
7f30: 66 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  f);.        brea
7f40: 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 65 20 41  k;..      case A
7f50: 53 59 4e 43 5f 53 59 4e 43 44 49 52 45 43 54 4f  SYNC_SYNCDIRECTO
7f60: 52 59 3a 0a 20 20 20 20 20 20 20 20 54 52 41 43  RY:.        TRAC
7f70: 45 28 28 22 53 59 4e 43 44 49 52 20 25 73 5c 6e  E(("SYNCDIR %s\n
7f80: 22 2c 20 70 2d 3e 7a 42 75 66 29 29 3b 0a 20 20  ", p->zBuf));.  
7f90: 20 20 20 20 20 20 72 63 20 3d 20 78 4f 72 69 67        rc = xOrig
7fa0: 53 79 6e 63 44 69 72 65 63 74 6f 72 79 28 70 2d  SyncDirectory(p-
7fb0: 3e 7a 42 75 66 29 3b 0a 20 20 20 20 20 20 20 20  >zBuf);.        
7fc0: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61  break;..      ca
7fd0: 73 65 20 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43  se ASYNC_OPENEXC
7fe0: 4c 55 53 49 56 45 3a 20 7b 0a 20 20 20 20 20 20  LUSIVE: {.      
7ff0: 20 20 41 73 79 6e 63 46 69 6c 65 20 2a 70 46 69    AsyncFile *pFi
8000: 6c 65 20 3d 20 70 2d 3e 70 46 69 6c 65 3b 0a 20  le = p->pFile;. 
8010: 20 20 20 20 20 20 20 69 6e 74 20 64 65 6c 46 6c         int delFl
8020: 61 67 20 3d 20 28 28 70 2d 3e 69 4f 66 66 73 65  ag = ((p->iOffse
8030: 74 29 3f 31 3a 30 29 3b 0a 20 20 20 20 20 20 20  t)?1:0);.       
8040: 20 4f 73 46 69 6c 65 20 2a 70 42 61 73 65 20 3d   OsFile *pBase =
8050: 20 30 3b 0a 20 20 20 20 20 20 20 20 54 52 41 43   0;.        TRAC
8060: 45 28 28 22 4f 50 45 4e 20 25 73 20 64 65 6c 46  E(("OPEN %s delF
8070: 6c 61 67 3d 25 64 5c 6e 22 2c 20 70 2d 3e 7a 42  lag=%d\n", p->zB
8080: 75 66 2c 20 64 65 6c 46 6c 61 67 29 29 3b 0a 20  uf, delFlag));. 
8090: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 70 46         assert(pF
80a0: 69 6c 65 2d 3e 70 42 61 73 65 52 65 61 64 3d 3d  ile->pBaseRead==
80b0: 30 20 26 26 20 70 46 69 6c 65 2d 3e 70 42 61 73  0 && pFile->pBas
80c0: 65 57 72 69 74 65 3d 3d 30 29 3b 0a 20 20 20 20  eWrite==0);.    
80d0: 20 20 20 20 72 63 20 3d 20 78 4f 72 69 67 4f 70      rc = xOrigOp
80e0: 65 6e 45 78 63 6c 75 73 69 76 65 28 70 2d 3e 7a  enExclusive(p->z
80f0: 42 75 66 2c 20 26 70 42 61 73 65 2c 20 64 65 6c  Buf, &pBase, del
8100: 46 6c 61 67 29 3b 0a 20 20 20 20 20 20 20 20 61  Flag);.        a
8110: 73 73 65 72 74 28 20 68 6f 6c 64 69 6e 67 4d 75  ssert( holdingMu
8120: 74 65 78 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  tex==0 );.      
8130: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
8140: 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 71 75 65 75  lock(&async.queu
8150: 65 4d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 20  eMutex);.       
8160: 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20   holdingMutex = 
8170: 31 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72  1;.        if( r
8180: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
8190: 20 20 20 20 20 20 20 20 20 20 70 46 69 6c 65 2d            pFile-
81a0: 3e 70 42 61 73 65 57 72 69 74 65 20 3d 20 70 42  >pBaseWrite = pB
81b0: 61 73 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ase;.        }. 
81c0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
81d0: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 64 65 66      }..      def
81e0: 61 75 6c 74 3a 20 61 73 73 65 72 74 28 21 22 49  ault: assert(!"I
81f0: 6c 6c 65 67 61 6c 20 76 61 6c 75 65 20 66 6f 72  llegal value for
8200: 20 41 73 79 6e 63 57 72 69 74 65 2e 6f 70 22 29   AsyncWrite.op")
8210: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
8220: 49 66 20 77 65 20 64 69 64 6e 27 74 20 68 61 6e  If we didn't han
8230: 67 20 6f 6e 20 74 6f 20 74 68 65 20 6d 75 74 65  g on to the mute
8240: 78 20 64 75 72 69 6e 67 20 74 68 65 20 49 4f 20  x during the IO 
8250: 6f 70 2c 20 6f 62 74 61 69 6e 20 69 74 20 6e 6f  op, obtain it no
8260: 77 0a 20 20 20 20 2a 2a 20 73 6f 20 74 68 61 74  w.    ** so that
8270: 20 74 68 65 20 41 73 79 6e 63 57 72 69 74 65 20   the AsyncWrite 
8280: 73 74 72 75 63 74 75 72 65 20 63 61 6e 20 62 65  structure can be
8290: 20 73 61 66 65 6c 79 20 72 65 6d 6f 76 65 64 20   safely removed 
82a0: 66 72 6f 6d 20 74 68 65 20 0a 20 20 20 20 2a 2a  from the .    **
82b0: 20 67 6c 6f 62 61 6c 20 77 72 69 74 65 2d 6f 70   global write-op
82c0: 20 71 75 65 75 65 2e 0a 20 20 20 20 2a 2f 0a 20   queue..    */. 
82d0: 20 20 20 69 66 28 20 21 68 6f 6c 64 69 6e 67 4d     if( !holdingM
82e0: 75 74 65 78 20 29 7b 0a 20 20 20 20 20 20 70 74  utex ){.      pt
82f0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
8300: 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74  (&async.queueMut
8310: 65 78 29 3b 0a 20 20 20 20 20 20 68 6f 6c 64 69  ex);.      holdi
8320: 6e 67 4d 75 74 65 78 20 3d 20 31 3b 0a 20 20 20  ngMutex = 1;.   
8330: 20 7d 0a 20 20 20 20 2f 2a 20 54 52 41 43 45 28   }.    /* TRACE(
8340: 28 22 55 4e 4c 49 4e 4b 20 25 70 5c 6e 22 2c 20  ("UNLINK %p\n", 
8350: 70 29 29 3b 20 2a 2f 0a 20 20 20 20 69 66 28 20  p)); */.    if( 
8360: 70 3d 3d 61 73 79 6e 63 2e 70 51 75 65 75 65 4c  p==async.pQueueL
8370: 61 73 74 20 29 7b 0a 20 20 20 20 20 20 61 73 79  ast ){.      asy
8380: 6e 63 2e 70 51 75 65 75 65 4c 61 73 74 20 3d 20  nc.pQueueLast = 
8390: 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 79  0;.    }.    asy
83a0: 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74 20 3d  nc.pQueueFirst =
83b0: 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73   p->pNext;.    s
83c0: 71 6c 69 74 65 33 4f 73 46 72 65 65 28 70 29 3b  qlite3OsFree(p);
83d0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 68 6f 6c  .    assert( hol
83e0: 64 69 6e 67 4d 75 74 65 78 20 29 3b 0a 0a 20 20  dingMutex );..  
83f0: 20 20 2f 2a 20 41 6e 20 49 4f 20 65 72 72 6f 72    /* An IO error
8400: 20 68 61 73 20 6f 63 63 75 72 65 64 2e 20 57 65   has occured. We
8410: 20 63 61 6e 6e 6f 74 20 72 65 70 6f 72 74 20 74   cannot report t
8420: 68 65 20 65 72 72 6f 72 20 62 61 63 6b 20 74 6f  he error back to
8430: 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e 6e   the.    ** conn
8440: 65 63 74 69 6f 6e 20 74 68 61 74 20 72 65 71 75  ection that requ
8450: 65 73 74 65 64 20 74 68 65 20 49 2f 4f 20 73 69  ested the I/O si
8460: 6e 63 65 20 74 68 65 20 65 72 72 6f 72 20 68 61  nce the error ha
8470: 70 70 65 6e 65 64 20 0a 20 20 20 20 2a 2a 20 61  ppened .    ** a
8480: 73 79 6e 63 68 72 6f 6e 6f 75 73 6c 79 2e 20 20  synchronously.  
8490: 54 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68  The connection h
84a0: 61 73 20 61 6c 72 65 61 64 79 20 6d 6f 76 65 64  as already moved
84b0: 20 6f 6e 2e 20 20 54 68 65 72 65 20 0a 20 20 20   on.  There .   
84c0: 20 2a 2a 20 72 65 61 6c 6c 79 20 69 73 20 6e 6f   ** really is no
84d0: 62 6f 64 79 20 74 6f 20 72 65 70 6f 72 74 20 74  body to report t
84e0: 68 65 20 65 72 72 6f 72 20 74 6f 2e 0a 20 20 20  he error to..   
84f0: 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20 66   **.    ** The f
8500: 69 6c 65 20 66 6f 72 20 77 68 69 63 68 20 74 68  ile for which th
8510: 65 20 65 72 72 6f 72 20 6f 63 63 75 72 65 64 20  e error occured 
8520: 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 20  may have been a 
8530: 64 61 74 61 62 61 73 65 20 6f 72 0a 20 20 20 20  database or.    
8540: 2a 2a 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 2e  ** journal file.
8550: 20 52 65 67 61 72 64 6c 65 73 73 2c 20 6e 6f 6e   Regardless, non
8560: 65 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e 74  e of the current
8570: 6c 79 20 71 75 65 75 65 64 20 6f 70 65 72 61 74  ly queued operat
8580: 69 6f 6e 73 0a 20 20 20 20 2a 2a 20 61 73 73 6f  ions.    ** asso
8590: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
85a0: 73 61 6d 65 20 64 61 74 61 62 61 73 65 20 73 68  same database sh
85b0: 6f 75 6c 64 20 6e 6f 77 20 62 65 20 70 65 72 66  ould now be perf
85c0: 6f 72 6d 65 64 2e 20 4e 6f 72 20 73 68 6f 75 6c  ormed. Nor shoul
85d0: 64 0a 20 20 20 20 2a 2a 20 61 6e 79 20 73 75 62  d.    ** any sub
85e0: 73 65 71 75 65 6e 74 6c 79 20 72 65 71 75 65 73  sequently reques
85f0: 74 65 64 20 49 4f 20 6f 6e 20 65 69 74 68 65 72  ted IO on either
8600: 20 61 20 64 61 74 61 62 61 73 65 20 6f 72 20 6a   a database or j
8610: 6f 75 72 6e 61 6c 20 66 69 6c 65 20 0a 20 20 20  ournal file .   
8620: 20 2a 2a 20 68 61 6e 64 6c 65 20 66 6f 72 20 74   ** handle for t
8630: 68 65 20 73 61 6d 65 20 64 61 74 61 62 61 73 65  he same database
8640: 20 62 65 20 61 63 63 65 70 74 65 64 20 75 6e 74   be accepted unt
8650: 69 6c 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61  il the main data
8660: 62 61 73 65 0a 20 20 20 20 2a 2a 20 66 69 6c 65  base.    ** file
8670: 20 68 61 6e 64 6c 65 20 68 61 73 20 62 65 65 6e   handle has been
8680: 20 63 6c 6f 73 65 64 20 61 6e 64 20 72 65 6f 70   closed and reop
8690: 65 6e 65 64 2e 0a 20 20 20 20 2a 2a 0a 20 20 20  ened..    **.   
86a0: 20 2a 2a 20 46 75 72 74 68 65 72 6d 6f 72 65 2c   ** Furthermore,
86b0: 20 6e 6f 20 66 75 72 74 68 65 72 20 49 4f 20 73   no further IO s
86c0: 68 6f 75 6c 64 20 62 65 20 71 75 65 75 65 64 20  hould be queued 
86d0: 6f 72 20 70 65 72 66 6f 72 6d 65 64 20 6f 6e 20  or performed on 
86e0: 61 6e 79 20 66 69 6c 65 0a 20 20 20 20 2a 2a 20  any file.    ** 
86f0: 68 61 6e 64 6c 65 20 61 73 73 6f 63 69 61 74 65  handle associate
8700: 64 20 77 69 74 68 20 61 20 64 61 74 61 62 61 73  d with a databas
8710: 65 20 74 68 61 74 20 6d 61 79 20 68 61 76 65 20  e that may have 
8720: 62 65 65 6e 20 70 61 72 74 20 6f 66 20 61 20 0a  been part of a .
8730: 20 20 20 20 2a 2a 20 6d 75 6c 74 69 2d 66 69 6c      ** multi-fil
8740: 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 74 68  e transaction th
8750: 61 74 20 69 6e 63 6c 75 64 65 64 20 74 68 65 20  at included the 
8760: 64 61 74 61 62 61 73 65 20 61 73 73 6f 63 69 61  database associa
8770: 74 65 64 20 77 69 74 68 20 0a 20 20 20 20 2a 2a  ted with .    **
8780: 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20 28 69   the IO error (i
8790: 2e 65 2e 20 61 20 64 61 74 61 62 61 73 65 20 41  .e. a database A
87a0: 54 54 41 43 48 65 64 20 74 6f 20 74 68 65 20 73  TTACHed to the s
87b0: 61 6d 65 20 68 61 6e 64 6c 65 20 61 74 20 73 6f  ame handle at so
87c0: 6d 65 20 0a 20 20 20 20 2a 2a 20 70 6f 69 6e 74  me .    ** point
87d0: 20 69 6e 20 74 69 6d 65 29 2e 0a 20 20 20 20 2a   in time)..    *
87e0: 2f 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  /.    if( rc!=SQ
87f0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
8800: 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 20 3d   async.ioError =
8810: 20 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20   rc;.    }..    
8820: 2f 2a 20 44 72 6f 70 20 74 68 65 20 71 75 65 75  /* Drop the queu
8830: 65 20 6d 75 74 65 78 20 62 65 66 6f 72 65 20 63  e mutex before c
8840: 6f 6e 74 69 6e 75 69 6e 67 20 74 6f 20 74 68 65  ontinuing to the
8850: 20 6e 65 78 74 20 77 72 69 74 65 20 6f 70 65 72   next write oper
8860: 61 74 69 6f 6e 0a 20 20 20 20 2a 2a 20 69 6e 20  ation.    ** in 
8870: 6f 72 64 65 72 20 74 6f 20 67 69 76 65 20 6f 74  order to give ot
8880: 68 65 72 20 74 68 72 65 61 64 73 20 61 20 63 68  her threads a ch
8890: 61 6e 63 65 20 74 6f 20 77 6f 72 6b 20 77 69 74  ance to work wit
88a0: 68 20 74 68 65 20 77 72 69 74 65 20 71 75 65 75  h the write queu
88b0: 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  e..    */.    if
88c0: 28 20 21 61 73 79 6e 63 2e 70 51 75 65 75 65 46  ( !async.pQueueF
88d0: 69 72 73 74 20 7c 7c 20 21 61 73 79 6e 63 2e 69  irst || !async.i
88e0: 6f 45 72 72 6f 72 20 29 7b 0a 20 20 20 20 20 20  oError ){.      
88f0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
8900: 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 71 75 65 75  lock(&async.queu
8910: 65 4d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 68  eMutex);.      h
8920: 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20 30 3b  oldingMutex = 0;
8930: 0a 20 20 20 20 20 20 69 66 28 20 61 73 79 6e 63  .      if( async
8940: 2e 69 6f 44 65 6c 61 79 3e 30 20 29 7b 0a 20 20  .ioDelay>0 ){.  
8950: 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53        sqlite3OsS
8960: 6c 65 65 70 28 61 73 79 6e 63 2e 69 6f 44 65 6c  leep(async.ioDel
8970: 61 79 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  ay);.      }else
8980: 7b 0a 20 20 20 20 20 20 20 20 73 63 68 65 64 5f  {.        sched_
8990: 79 69 65 6c 64 28 29 3b 0a 20 20 20 20 20 20 7d  yield();.      }
89a0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20  .    }.  }.  .  
89b0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
89c0: 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 77 72 69 74  lock(&async.writ
89d0: 65 72 4d 75 74 65 78 29 3b 0a 20 20 72 65 74 75  erMutex);.  retu
89e0: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  rn 0;.}../******
89f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8a00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8a10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8a20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8a30: 2a 2a 2a 2a 0a 2a 2a 20 54 68 65 20 72 65 6d 61  ****.** The rema
8a40: 69 6e 69 6e 67 20 63 6f 64 65 20 64 65 66 69 6e  ining code defin
8a50: 65 73 20 61 20 54 63 6c 20 69 6e 74 65 72 66 61  es a Tcl interfa
8a60: 63 65 20 66 6f 72 20 74 65 73 74 69 6e 67 20 74  ce for testing t
8a70: 68 65 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 0a  he asynchronous.
8a80: 2a 2a 20 49 4f 20 69 6d 70 6c 65 6d 65 6e 74 61  ** IO implementa
8a90: 74 69 6f 6e 20 69 6e 20 74 68 69 73 20 66 69 6c  tion in this fil
8aa0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 61 64 61 70  e..**.** To adap
8ab0: 74 20 74 68 65 20 63 6f 64 65 20 74 6f 20 61 20  t the code to a 
8ac0: 6e 6f 6e 2d 54 43 4c 20 65 6e 76 69 72 6f 6e 6d  non-TCL environm
8ad0: 65 6e 74 2c 20 64 65 6c 65 74 65 20 6f 72 20 63  ent, delete or c
8ae0: 6f 6d 6d 65 6e 74 20 6f 75 74 0a 2a 2a 20 74 68  omment out.** th
8af0: 65 20 63 6f 64 65 20 74 68 61 74 20 66 6f 6c 6c  e code that foll
8b00: 6f 77 73 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 73  ows..*/../*.** s
8b10: 71 6c 69 74 65 33 61 73 79 6e 63 5f 65 6e 61 62  qlite3async_enab
8b20: 6c 65 20 3f 59 45 53 2f 4e 4f 3f 0a 2a 2a 0a 2a  le ?YES/NO?.**.*
8b30: 2a 20 45 6e 61 62 6c 65 20 6f 72 20 64 69 73 61  * Enable or disa
8b40: 62 6c 65 20 74 68 65 20 61 73 79 6e 63 68 72 6f  ble the asynchro
8b50: 6e 6f 75 73 20 49 2f 4f 20 62 61 63 6b 65 6e 64  nous I/O backend
8b60: 2e 20 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20  .  This command 
8b70: 69 73 0a 2a 2a 20 6e 6f 74 20 74 68 72 65 61 64  is.** not thread
8b80: 2d 73 61 66 65 2e 20 20 44 6f 20 6e 6f 74 20 63  -safe.  Do not c
8b90: 61 6c 6c 20 69 74 20 77 68 69 6c 65 20 61 6e 79  all it while any
8ba0: 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63   database connec
8bb0: 74 69 6f 6e 73 0a 2a 2a 20 61 72 65 20 6f 70 65  tions.** are ope
8bc0: 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  n..*/.static int
8bd0: 20 74 65 73 74 41 73 79 6e 63 45 6e 61 62 6c 65   testAsyncEnable
8be0: 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e  (.  void * clien
8bf0: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
8c00: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
8c10: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
8c20: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
8c30: 0a 29 7b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d  .){.  if( objc!=
8c40: 31 20 26 26 20 6f 62 6a 63 21 3d 32 20 29 7b 0a  1 && objc!=2 ){.
8c50: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
8c60: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
8c70: 6f 62 6a 76 2c 20 22 3f 59 45 53 2f 4e 4f 3f 22  objv, "?YES/NO?"
8c80: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
8c90: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69  L_ERROR;.  }.  i
8ca0: 66 28 20 6f 62 6a 63 3d 3d 31 20 29 7b 0a 20 20  f( objc==1 ){.  
8cb0: 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75    Tcl_SetObjResu
8cc0: 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e  lt(interp, Tcl_N
8cd0: 65 77 42 6f 6f 6c 65 61 6e 4f 62 6a 28 78 4f 72  ewBooleanObj(xOr
8ce0: 69 67 4f 70 65 6e 52 65 61 64 57 72 69 74 65 21  igOpenReadWrite!
8cf0: 3d 30 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  =0));.  }else{. 
8d00: 20 20 20 69 6e 74 20 65 6e 3b 0a 20 20 20 20 69     int en;.    i
8d10: 66 28 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61  f( Tcl_GetBoolea
8d20: 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  nFromObj(interp,
8d30: 20 6f 62 6a 76 5b 31 5d 2c 20 26 65 6e 29 20 29   objv[1], &en) )
8d40: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8d50: 52 3b 0a 20 20 20 20 61 73 79 6e 63 45 6e 61 62  R;.    asyncEnab
8d60: 6c 65 28 65 6e 29 3b 0a 20 20 7d 0a 20 20 72 65  le(en);.  }.  re
8d70: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
8d80: 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 61 73 79  /*.** sqlite3asy
8d90: 6e 63 5f 68 61 6c 74 20 20 22 6e 6f 77 22 7c 22  nc_halt  "now"|"
8da0: 69 64 6c 65 22 7c 22 6e 65 76 65 72 22 0a 2a 2a  idle"|"never".**
8db0: 0a 2a 2a 20 53 65 74 20 74 68 65 20 63 6f 6e 64  .** Set the cond
8dc0: 69 74 69 6f 6e 73 20 61 74 20 77 68 69 63 68 20  itions at which 
8dd0: 74 68 65 20 77 72 69 74 65 72 20 74 68 72 65 61  the writer threa
8de0: 64 20 77 69 6c 6c 20 68 61 6c 74 2e 0a 2a 2f 0a  d will halt..*/.
8df0: 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 41  static int testA
8e00: 73 79 6e 63 48 61 6c 74 28 0a 20 20 76 6f 69 64  syncHalt(.  void
8e10: 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20   * clientData,. 
8e20: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
8e30: 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c  erp,.  int objc,
8e40: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
8e50: 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f  T objv[].){.  co
8e60: 6e 73 74 20 63 68 61 72 20 2a 7a 43 6f 6e 64 3b  nst char *zCond;
8e70: 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29  .  if( objc!=2 )
8e80: 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  {.    Tcl_WrongN
8e90: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
8ea0: 2c 20 6f 62 6a 76 2c 20 22 5c 22 6e 6f 77 5c 22  , objv, "\"now\"
8eb0: 7c 5c 22 69 64 6c 65 5c 22 7c 5c 22 6e 65 76 65  |\"idle\"|\"neve
8ec0: 72 5c 22 22 29 3b 0a 20 20 20 20 72 65 74 75 72  r\"");.    retur
8ed0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
8ee0: 0a 20 20 7a 43 6f 6e 64 20 3d 20 54 63 6c 5f 47  .  zCond = Tcl_G
8ef0: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
8f00: 29 3b 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28  );.  if( strcmp(
8f10: 7a 43 6f 6e 64 2c 20 22 6e 6f 77 22 29 3d 3d 30  zCond, "now")==0
8f20: 20 29 7b 0a 20 20 20 20 61 73 79 6e 63 2e 77 72   ){.    async.wr
8f30: 69 74 65 72 48 61 6c 74 4e 6f 77 20 3d 20 31 3b  iterHaltNow = 1;
8f40: 0a 20 20 20 20 70 74 68 72 65 61 64 5f 63 6f 6e  .    pthread_con
8f50: 64 5f 62 72 6f 61 64 63 61 73 74 28 26 61 73 79  d_broadcast(&asy
8f60: 6e 63 2e 71 75 65 75 65 53 69 67 6e 61 6c 29 3b  nc.queueSignal);
8f70: 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72  .  }else if( str
8f80: 63 6d 70 28 7a 43 6f 6e 64 2c 20 22 69 64 6c 65  cmp(zCond, "idle
8f90: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 79  ")==0 ){.    asy
8fa0: 6e 63 2e 77 72 69 74 65 72 48 61 6c 74 57 68 65  nc.writerHaltWhe
8fb0: 6e 49 64 6c 65 20 3d 20 31 3b 0a 20 20 20 20 61  nIdle = 1;.    a
8fc0: 73 79 6e 63 2e 77 72 69 74 65 72 48 61 6c 74 4e  sync.writerHaltN
8fd0: 6f 77 20 3d 20 30 3b 0a 20 20 20 20 70 74 68 72  ow = 0;.    pthr
8fe0: 65 61 64 5f 63 6f 6e 64 5f 62 72 6f 61 64 63 61  ead_cond_broadca
8ff0: 73 74 28 26 61 73 79 6e 63 2e 71 75 65 75 65 53  st(&async.queueS
9000: 69 67 6e 61 6c 29 3b 0a 20 20 7d 65 6c 73 65 20  ignal);.  }else 
9010: 69 66 28 20 73 74 72 63 6d 70 28 7a 43 6f 6e 64  if( strcmp(zCond
9020: 2c 20 22 6e 65 76 65 72 22 29 3d 3d 30 20 29 7b  , "never")==0 ){
9030: 0a 20 20 20 20 61 73 79 6e 63 2e 77 72 69 74 65  .    async.write
9040: 72 48 61 6c 74 57 68 65 6e 49 64 6c 65 20 3d 20  rHaltWhenIdle = 
9050: 30 3b 0a 20 20 20 20 61 73 79 6e 63 2e 77 72 69  0;.    async.wri
9060: 74 65 72 48 61 6c 74 4e 6f 77 20 3d 20 30 3b 0a  terHaltNow = 0;.
9070: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 54 63 6c    }else{.    Tcl
9080: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
9090: 74 65 72 70 2c 20 0a 20 20 20 20 20 20 22 73 68  terp, .      "sh
90a0: 6f 75 6c 64 20 62 65 20 6f 6e 65 20 6f 66 3a 20  ould be one of: 
90b0: 5c 22 6e 6f 77 5c 22 2c 20 5c 22 69 64 6c 65 5c  \"now\", \"idle\
90c0: 22 2c 20 6f 72 20 5c 22 6e 65 76 65 72 5c 22 22  ", or \"never\""
90d0: 2c 20 28 63 68 61 72 2a 29 30 29 3b 0a 20 20 20  , (char*)0);.   
90e0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
90f0: 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  R;.  }.  return 
9100: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TCL_OK;.}../*.**
9110: 20 73 71 6c 69 74 65 33 61 73 79 6e 63 5f 64 65   sqlite3async_de
9120: 6c 61 79 20 3f 4d 53 3f 0a 2a 2a 0a 2a 2a 20 51  lay ?MS?.**.** Q
9130: 75 65 72 79 20 6f 72 20 73 65 74 20 74 68 65 20  uery or set the 
9140: 6e 75 6d 62 65 72 20 6f 66 20 6d 69 6c 6c 69 73  number of millis
9150: 65 63 6f 6e 64 73 20 6f 66 20 64 65 6c 61 79 20  econds of delay 
9160: 69 6e 20 74 68 65 20 77 72 69 74 65 72 0a 2a 2a  in the writer.**
9170: 20 74 68 72 65 61 64 20 61 66 74 65 72 20 65 61   thread after ea
9180: 63 68 20 77 72 69 74 65 20 6f 70 65 72 61 74 69  ch write operati
9190: 6f 6e 2e 20 20 54 68 65 20 64 65 66 61 75 6c 74  on.  The default
91a0: 20 69 73 20 30 2e 20 20 42 79 20 69 6e 63 72 65   is 0.  By incre
91b0: 61 73 69 6e 67 0a 2a 2a 20 74 68 65 20 6d 65 6d  asing.** the mem
91c0: 6f 72 79 20 64 65 6c 61 79 20 77 65 20 63 61 6e  ory delay we can
91d0: 20 73 69 6d 75 6c 61 74 65 20 74 68 65 20 65 66   simulate the ef
91e0: 66 65 63 74 20 6f 66 20 73 6c 6f 77 20 64 69 73  fect of slow dis
91f0: 6b 20 49 2f 4f 2e 0a 2a 2f 0a 73 74 61 74 69 63  k I/O..*/.static
9200: 20 69 6e 74 20 74 65 73 74 41 73 79 6e 63 44 65   int testAsyncDe
9210: 6c 61 79 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c  lay(.  void * cl
9220: 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f  ientData,.  Tcl_
9230: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a  Interp *interp,.
9240: 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63    int objc,.  Tc
9250: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
9260: 76 5b 5d 0a 29 7b 0a 20 20 69 66 28 20 6f 62 6a  v[].){.  if( obj
9270: 63 21 3d 31 20 26 26 20 6f 62 6a 63 21 3d 32 20  c!=1 && objc!=2 
9280: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
9290: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
92a0: 31 2c 20 6f 62 6a 76 2c 20 22 3f 4d 53 3f 22 29  1, objv, "?MS?")
92b0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
92c0: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66  _ERROR;.  }.  if
92d0: 28 20 6f 62 6a 63 3d 3d 31 20 29 7b 0a 20 20 20  ( objc==1 ){.   
92e0: 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c   Tcl_SetObjResul
92f0: 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65  t(interp, Tcl_Ne
9300: 77 49 6e 74 4f 62 6a 28 61 73 79 6e 63 2e 69 6f  wIntObj(async.io
9310: 44 65 6c 61 79 29 29 3b 0a 20 20 7d 65 6c 73 65  Delay));.  }else
9320: 7b 0a 20 20 20 20 69 6e 74 20 69 6f 44 65 6c 61  {.    int ioDela
9330: 79 3b 0a 20 20 20 20 69 66 28 20 54 63 6c 5f 47  y;.    if( Tcl_G
9340: 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74  etIntFromObj(int
9350: 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 69  erp, objv[1], &i
9360: 6f 44 65 6c 61 79 29 20 29 20 72 65 74 75 72 6e  oDelay) ) return
9370: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
9380: 61 73 79 6e 63 2e 69 6f 44 65 6c 61 79 20 3d 20  async.ioDelay = 
9390: 69 6f 44 65 6c 61 79 3b 0a 20 20 7d 0a 20 20 72  ioDelay;.  }.  r
93a0: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
93b0: 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 61 73  ./*.** sqlite3as
93c0: 79 6e 63 5f 73 74 61 72 74 0a 2a 2a 0a 2a 2a 20  ync_start.**.** 
93d0: 53 74 61 72 74 20 61 20 6e 65 77 20 77 72 69 74  Start a new writ
93e0: 65 72 20 74 68 72 65 61 64 2e 0a 2a 2f 0a 73 74  er thread..*/.st
93f0: 61 74 69 63 20 69 6e 74 20 74 65 73 74 41 73 79  atic int testAsy
9400: 6e 63 53 74 61 72 74 28 0a 20 20 76 6f 69 64 20  ncStart(.  void 
9410: 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20  * clientData,.  
9420: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
9430: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
9440: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
9450: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 70 74 68   objv[].){.  pth
9460: 72 65 61 64 5f 74 20 78 3b 0a 20 20 69 6e 74 20  read_t x;.  int 
9470: 72 63 3b 0a 20 20 72 63 20 3d 20 70 74 68 72 65  rc;.  rc = pthre
9480: 61 64 5f 63 72 65 61 74 65 28 26 78 2c 20 30 2c  ad_create(&x, 0,
9490: 20 61 73 79 6e 63 57 72 69 74 65 72 54 68 72 65   asyncWriterThre
94a0: 61 64 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63  ad, 0);.  if( rc
94b0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65   ){.    Tcl_Appe
94c0: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
94d0: 20 22 66 61 69 6c 65 64 20 74 6f 20 63 72 65 61   "failed to crea
94e0: 74 65 20 74 68 65 20 74 68 72 65 61 64 22 2c 20  te the thread", 
94f0: 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  0);.    return T
9500: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
9510: 70 74 68 72 65 61 64 5f 64 65 74 61 63 68 28 78  pthread_detach(x
9520: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
9530: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c  OK;.}../*.** sql
9540: 69 74 65 33 61 73 79 6e 63 5f 77 61 69 74 0a 2a  ite3async_wait.*
9550: 2a 0a 2a 2a 20 57 61 69 74 20 66 6f 72 20 74 68  *.** Wait for th
9560: 65 20 63 75 72 72 65 6e 74 20 77 72 69 74 65 72  e current writer
9570: 20 74 68 72 65 61 64 20 74 6f 20 74 65 72 6d 69   thread to termi
9580: 6e 61 74 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  nate..**.** If t
9590: 68 65 20 63 75 72 72 65 6e 74 20 77 72 69 74 65  he current write
95a0: 72 20 74 68 72 65 61 64 20 69 73 20 73 65 74 20  r thread is set 
95b0: 74 6f 20 72 75 6e 20 66 6f 72 65 76 65 72 20 74  to run forever t
95c0: 68 65 6e 20 74 68 69 73 0a 2a 2a 20 63 6f 6d 6d  hen this.** comm
95d0: 61 6e 64 20 77 6f 75 6c 64 20 62 6c 6f 63 6b 20  and would block 
95e0: 66 6f 72 65 76 65 72 2e 20 20 54 6f 20 70 72 65  forever.  To pre
95f0: 76 65 6e 74 20 74 68 61 74 2c 20 61 6e 20 65 72  vent that, an er
9600: 72 6f 72 20 69 73 20 72 65 74 75 72 6e 65 64 2e  ror is returned.
9610: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
9620: 74 65 73 74 41 73 79 6e 63 57 61 69 74 28 0a 20  testAsyncWait(. 
9630: 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61   void * clientDa
9640: 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  ta,.  Tcl_Interp
9650: 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20   *interp,.  int 
9660: 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20  objc,.  Tcl_Obj 
9670: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b  *CONST objv[].){
9680: 0a 20 20 69 6e 74 20 63 6e 74 20 3d 20 31 30 3b  .  int cnt = 10;
9690: 0a 20 20 69 66 28 20 61 73 79 6e 63 2e 77 72 69  .  if( async.wri
96a0: 74 65 72 48 61 6c 74 4e 6f 77 3d 3d 30 20 26 26  terHaltNow==0 &&
96b0: 20 61 73 79 6e 63 2e 77 72 69 74 65 72 48 61 6c   async.writerHal
96c0: 74 57 68 65 6e 49 64 6c 65 3d 3d 30 20 29 7b 0a  tWhenIdle==0 ){.
96d0: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65      Tcl_AppendRe
96e0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 77 6f  sult(interp, "wo
96f0: 75 6c 64 20 62 6c 6f 63 6b 20 66 6f 72 65 76 65  uld block foreve
9700: 72 22 2c 20 28 63 68 61 72 2a 29 30 29 3b 0a 20  r", (char*)0);. 
9710: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
9720: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 77 68 69 6c  ROR;.  }..  whil
9730: 65 28 20 63 6e 74 2d 2d 20 26 26 20 21 70 74 68  e( cnt-- && !pth
9740: 72 65 61 64 5f 6d 75 74 65 78 5f 74 72 79 6c 6f  read_mutex_trylo
9750: 63 6b 28 26 61 73 79 6e 63 2e 77 72 69 74 65 72  ck(&async.writer
9760: 4d 75 74 65 78 29 20 29 7b 0a 20 20 20 20 70 74  Mutex) ){.    pt
9770: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
9780: 63 6b 28 26 61 73 79 6e 63 2e 77 72 69 74 65 72  ck(&async.writer
9790: 4d 75 74 65 78 29 3b 0a 20 20 20 20 73 63 68 65  Mutex);.    sche
97a0: 64 5f 79 69 65 6c 64 28 29 3b 0a 20 20 7d 0a 20  d_yield();.  }. 
97b0: 20 69 66 28 20 63 6e 74 3e 3d 30 20 29 7b 0a 20   if( cnt>=0 ){. 
97c0: 20 20 20 54 52 41 43 45 28 28 22 57 41 49 54 5c     TRACE(("WAIT\
97d0: 6e 22 29 29 3b 0a 20 20 20 20 70 74 68 72 65 61  n"));.    pthrea
97e0: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73  d_mutex_lock(&as
97f0: 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b  ync.queueMutex);
9800: 0a 20 20 20 20 70 74 68 72 65 61 64 5f 63 6f 6e  .    pthread_con
9810: 64 5f 62 72 6f 61 64 63 61 73 74 28 26 61 73 79  d_broadcast(&asy
9820: 6e 63 2e 71 75 65 75 65 53 69 67 6e 61 6c 29 3b  nc.queueSignal);
9830: 0a 20 20 20 20 70 74 68 72 65 61 64 5f 6d 75 74  .    pthread_mut
9840: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63  ex_unlock(&async
9850: 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20  .queueMutex);.  
9860: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
9870: 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 77 72 69 74  lock(&async.writ
9880: 65 72 4d 75 74 65 78 29 3b 0a 20 20 20 20 70 74  erMutex);.    pt
9890: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
98a0: 63 6b 28 26 61 73 79 6e 63 2e 77 72 69 74 65 72  ck(&async.writer
98b0: 4d 75 74 65 78 29 3b 0a 20 20 7d 65 6c 73 65 7b  Mutex);.  }else{
98c0: 0a 20 20 20 20 54 52 41 43 45 28 28 22 4e 4f 2d  .    TRACE(("NO-
98d0: 57 41 49 54 5c 6e 22 29 29 3b 0a 20 20 7d 0a 20  WAIT\n"));.  }. 
98e0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
98f0: 7d 0a 0a 0a 23 65 6e 64 69 66 20 20 2f 2a 20 4f  }...#endif  /* O
9900: 53 5f 55 4e 49 58 20 61 6e 64 20 54 48 52 45 41  S_UNIX and THREA
9910: 44 53 41 46 45 20 61 6e 64 20 64 65 66 69 6e 65  DSAFE and define
9920: 64 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  d(SQLITE_ENABLE_
9930: 52 45 44 45 46 5f 49 4f 29 20 2a 2f 0a 0a 2f 2a  REDEF_IO) */../*
9940: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
9950: 20 72 65 67 69 73 74 65 72 73 20 74 68 65 20 63   registers the c
9960: 75 73 74 6f 6d 20 54 43 4c 20 63 6f 6d 6d 61 6e  ustom TCL comman
9970: 64 73 20 64 65 66 69 6e 65 64 20 69 6e 20 74 68  ds defined in th
9980: 69 73 0a 2a 2a 20 6d 6f 64 75 6c 65 2e 20 20 54  is.** module.  T
9990: 68 69 73 20 73 68 6f 75 6c 64 20 62 65 20 74 68  his should be th
99a0: 65 20 6f 6e 6c 79 20 70 72 6f 63 65 64 75 72 65  e only procedure
99b0: 20 76 69 73 69 62 6c 65 20 66 72 6f 6d 20 6f 75   visible from ou
99c0: 74 73 69 64 65 0a 2a 2a 20 6f 66 20 74 68 69 73  tside.** of this
99d0: 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 69 6e 74 20   module..*/.int 
99e0: 53 71 6c 69 74 65 74 65 73 74 61 73 79 6e 63 5f  Sqlitetestasync_
99f0: 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20  Init(Tcl_Interp 
9a00: 2a 69 6e 74 65 72 70 29 7b 0a 23 69 66 20 4f 53  *interp){.#if OS
9a10: 5f 55 4e 49 58 20 26 26 20 54 48 52 45 41 44 53  _UNIX && THREADS
9a20: 41 46 45 20 26 26 20 64 65 66 69 6e 65 64 28 53  AFE && defined(S
9a30: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 52 45 44  QLITE_ENABLE_RED
9a40: 45 46 5f 49 4f 29 0a 20 20 54 63 6c 5f 43 72 65  EF_IO).  Tcl_Cre
9a50: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
9a60: 74 65 72 70 2c 22 73 71 6c 69 74 65 33 61 73 79  terp,"sqlite3asy
9a70: 6e 63 5f 65 6e 61 62 6c 65 22 2c 74 65 73 74 41  nc_enable",testA
9a80: 73 79 6e 63 45 6e 61 62 6c 65 2c 30 2c 30 29 3b  syncEnable,0,0);
9a90: 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  .  Tcl_CreateObj
9aa0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 22  Command(interp,"
9ab0: 73 71 6c 69 74 65 33 61 73 79 6e 63 5f 68 61 6c  sqlite3async_hal
9ac0: 74 22 2c 74 65 73 74 41 73 79 6e 63 48 61 6c 74  t",testAsyncHalt
9ad0: 2c 30 2c 30 29 3b 0a 20 20 54 63 6c 5f 43 72 65  ,0,0);.  Tcl_Cre
9ae0: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
9af0: 74 65 72 70 2c 22 73 71 6c 69 74 65 33 61 73 79  terp,"sqlite3asy
9b00: 6e 63 5f 64 65 6c 61 79 22 2c 74 65 73 74 41 73  nc_delay",testAs
9b10: 79 6e 63 44 65 6c 61 79 2c 30 2c 30 29 3b 0a 20  yncDelay,0,0);. 
9b20: 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f   Tcl_CreateObjCo
9b30: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 22 73 71  mmand(interp,"sq
9b40: 6c 69 74 65 33 61 73 79 6e 63 5f 73 74 61 72 74  lite3async_start
9b50: 22 2c 74 65 73 74 41 73 79 6e 63 53 74 61 72 74  ",testAsyncStart
9b60: 2c 30 2c 30 29 3b 0a 20 20 54 63 6c 5f 43 72 65  ,0,0);.  Tcl_Cre
9b70: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
9b80: 74 65 72 70 2c 22 73 71 6c 69 74 65 33 61 73 79  terp,"sqlite3asy
9b90: 6e 63 5f 77 61 69 74 22 2c 74 65 73 74 41 73 79  nc_wait",testAsy
9ba0: 6e 63 57 61 69 74 2c 30 2c 30 29 3b 0a 20 20 54  ncWait,0,0);.  T
9bb0: 63 6c 5f 4c 69 6e 6b 56 61 72 28 69 6e 74 65 72  cl_LinkVar(inter
9bc0: 70 2c 20 22 73 71 6c 69 74 65 33 61 73 79 6e 63  p, "sqlite3async
9bd0: 5f 74 72 61 63 65 22 2c 0a 20 20 20 20 20 20 28  _trace",.      (
9be0: 63 68 61 72 2a 29 26 73 71 6c 69 74 65 33 61 73  char*)&sqlite3as
9bf0: 79 6e 63 5f 74 72 61 63 65 2c 20 54 43 4c 5f 4c  ync_trace, TCL_L
9c00: 49 4e 4b 5f 49 4e 54 29 3b 0a 23 65 6e 64 69 66  INK_INT);.#endif
9c10: 20 20 2f 2a 20 4f 53 5f 55 4e 49 58 20 61 6e 64    /* OS_UNIX and
9c20: 20 54 48 52 45 41 44 53 41 46 45 20 61 6e 64 20   THREADSAFE and 
9c30: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45  defined(SQLITE_E
9c40: 4e 41 42 4c 45 5f 52 45 44 45 46 5f 49 4f 29 20  NABLE_REDEF_IO) 
9c50: 2a 2f 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  */.  return TCL_
9c60: 4f 4b 3b 0a 7d 0a                                OK;.}.