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

Artifact fd2344c394ad27e76274aa60b74a1ad5ff27533e:


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 24 49 64 3a  *****.**.** $Id:
0180: 20 74 65 73 74 5f 61 73 79 6e 63 2e 63 2c 76 20   test_async.c,v 
0190: 31 2e 35 35 20 32 30 30 39 2f 30 33 2f 32 38 20  1.55 2009/03/28 
01a0: 31 37 3a 32 31 3a 35 32 20 64 61 6e 69 65 6c 6b  17:21:52 danielk
01b0: 31 39 37 37 20 45 78 70 20 24 0a 2a 2a 0a 2a 2a  1977 Exp $.**.**
01c0: 20 54 68 69 73 20 66 69 6c 65 20 63 6f 6e 74 61   This file conta
01d0: 69 6e 73 20 61 6e 20 65 78 61 6d 70 6c 65 20 69  ins an example i
01e0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
01f0: 20 61 6e 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73   an asynchronous
0200: 20 49 4f 20 0a 2a 2a 20 62 61 63 6b 65 6e 64 20   IO .** backend 
0210: 66 6f 72 20 53 51 4c 69 74 65 2e 0a 2a 2a 0a 2a  for SQLite..**.*
0220: 2a 20 57 48 41 54 20 49 53 20 41 53 59 4e 43 48  * WHAT IS ASYNCH
0230: 52 4f 4e 4f 55 53 20 49 2f 4f 3f 0a 2a 2a 0a 2a  RONOUS I/O?.**.*
0240: 2a 20 57 69 74 68 20 61 73 79 6e 63 68 72 6f 6e  * With asynchron
0250: 6f 75 73 20 49 2f 4f 2c 20 77 72 69 74 65 20 72  ous I/O, write r
0260: 65 71 75 65 73 74 73 20 61 72 65 20 68 61 6e 64  equests are hand
0270: 6c 65 64 20 62 79 20 61 20 73 65 70 61 72 61 74  led by a separat
0280: 65 20 74 68 72 65 61 64 0a 2a 2a 20 72 75 6e 6e  e thread.** runn
0290: 69 6e 67 20 69 6e 20 74 68 65 20 62 61 63 6b 67  ing in the backg
02a0: 72 6f 75 6e 64 2e 20 20 54 68 69 73 20 6d 65 61  round.  This mea
02b0: 6e 73 20 74 68 61 74 20 74 68 65 20 74 68 72 65  ns that the thre
02c0: 61 64 20 74 68 61 74 20 69 6e 69 74 69 61 74 65  ad that initiate
02d0: 73 0a 2a 2a 20 61 20 64 61 74 61 62 61 73 65 20  s.** a database 
02e0: 77 72 69 74 65 20 64 6f 65 73 20 6e 6f 74 20 68  write does not h
02f0: 61 76 65 20 74 6f 20 77 61 69 74 20 66 6f 72 20  ave to wait for 
0300: 28 73 6f 6d 65 74 69 6d 65 73 20 73 6c 6f 77 29  (sometimes slow)
0310: 20 64 69 73 6b 20 49 2f 4f 0a 2a 2a 20 74 6f 20   disk I/O.** to 
0320: 6f 63 63 75 72 2e 20 20 54 68 65 20 77 72 69 74  occur.  The writ
0330: 65 20 73 65 65 6d 73 20 74 6f 20 68 61 70 70 65  e seems to happe
0340: 6e 20 76 65 72 79 20 71 75 69 63 6b 6c 79 2c 20  n very quickly, 
0350: 74 68 6f 75 67 68 20 69 6e 20 72 65 61 6c 69 74  though in realit
0360: 79 0a 2a 2a 20 69 74 20 69 73 20 68 61 70 70 65  y.** it is happe
0370: 6e 69 6e 67 20 61 74 20 69 74 73 20 75 73 75 61  ning at its usua
0380: 6c 20 73 6c 6f 77 20 70 61 63 65 20 69 6e 20 74  l slow pace in t
0390: 68 65 20 62 61 63 6b 67 72 6f 75 6e 64 2e 0a 2a  he background..*
03a0: 2a 0a 2a 2a 20 41 73 79 6e 63 68 72 6f 6e 6f 75  *.** Asynchronou
03b0: 73 20 49 2f 4f 20 61 70 70 65 61 72 73 20 74 6f  s I/O appears to
03c0: 20 67 69 76 65 20 62 65 74 74 65 72 20 72 65 73   give better res
03d0: 70 6f 6e 73 69 76 65 6e 65 73 73 2c 20 62 75 74  ponsiveness, but
03e0: 20 61 74 20 61 20 70 72 69 63 65 2e 0a 2a 2a 20   at a price..** 
03f0: 59 6f 75 20 6c 6f 73 65 20 74 68 65 20 44 75 72  You lose the Dur
0400: 61 62 6c 65 20 70 72 6f 70 65 72 74 79 2e 20 20  able property.  
0410: 57 69 74 68 20 74 68 65 20 64 65 66 61 75 6c 74  With the default
0420: 20 49 2f 4f 20 62 61 63 6b 65 6e 64 20 6f 66 20   I/O backend of 
0430: 53 51 4c 69 74 65 2c 0a 2a 2a 20 6f 6e 63 65 20  SQLite,.** once 
0440: 61 20 77 72 69 74 65 20 63 6f 6d 70 6c 65 74 65  a write complete
0450: 73 2c 20 79 6f 75 20 6b 6e 6f 77 20 74 68 61 74  s, you know that
0460: 20 74 68 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e   the information
0470: 20 79 6f 75 20 77 72 6f 74 65 20 69 73 0a 2a 2a   you wrote is.**
0480: 20 73 61 66 65 6c 79 20 6f 6e 20 64 69 73 6b 2e   safely on disk.
0490: 20 20 57 69 74 68 20 74 68 65 20 61 73 79 6e 63    With the async
04a0: 68 72 6f 6e 6f 75 73 20 49 2f 4f 2c 20 74 68 69  hronous I/O, thi
04b0: 73 20 69 73 20 6e 6f 74 20 74 68 65 20 63 61 73  s is not the cas
04c0: 65 2e 20 20 49 66 0a 2a 2a 20 79 6f 75 72 20 70  e.  If.** your p
04d0: 72 6f 67 72 61 6d 20 63 72 61 73 68 65 73 20 6f  rogram crashes o
04e0: 72 20 69 66 20 61 20 70 6f 77 65 72 20 6c 6f 73  r if a power los
04f0: 73 20 6f 63 63 75 72 73 20 61 66 74 65 72 20 74  s occurs after t
0500: 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 77  he database.** w
0510: 72 69 74 65 20 62 75 74 20 62 65 66 6f 72 65 20  rite but before 
0520: 74 68 65 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73  the asynchronous
0530: 20 77 72 69 74 65 20 74 68 72 65 61 64 20 68 61   write thread ha
0540: 73 20 63 6f 6d 70 6c 65 74 65 64 2c 20 74 68 65  s completed, the
0550: 6e 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  n the.** databas
0560: 65 20 63 68 61 6e 67 65 20 6d 69 67 68 74 20 6e  e change might n
0570: 65 76 65 72 20 6d 61 6b 65 20 69 74 20 74 6f 20  ever make it to 
0580: 64 69 73 6b 20 61 6e 64 20 74 68 65 20 6e 65 78  disk and the nex
0590: 74 20 75 73 65 72 20 6f 66 20 74 68 65 0a 2a 2a  t user of the.**
05a0: 20 64 61 74 61 62 61 73 65 20 6d 69 67 68 74 20   database might 
05b0: 6e 6f 74 20 73 65 65 20 79 6f 75 72 20 63 68 61  not see your cha
05c0: 6e 67 65 2e 0a 2a 2a 0a 2a 2a 20 59 6f 75 20 6c  nge..**.** You l
05d0: 6f 73 65 20 44 75 72 61 62 69 6c 69 74 79 20 77  ose Durability w
05e0: 69 74 68 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73  ith asynchronous
05f0: 20 49 2f 4f 2c 20 62 75 74 20 79 6f 75 20 73 74   I/O, but you st
0600: 69 6c 6c 20 72 65 74 61 69 6e 20 74 68 65 0a 2a  ill retain the.*
0610: 2a 20 6f 74 68 65 72 20 70 61 72 74 73 20 6f 66  * other parts of
0620: 20 41 43 49 44 3a 20 20 41 74 6f 6d 69 63 2c 20   ACID:  Atomic, 
0630: 20 43 6f 6e 73 69 73 74 65 6e 74 2c 20 61 6e 64   Consistent, and
0640: 20 49 73 6f 6c 61 74 65 64 2e 20 20 4d 61 6e 79   Isolated.  Many
0650: 0a 2a 2a 20 61 70 70 6c 69 61 74 69 6f 6e 73 20  .** appliations 
0660: 67 65 74 20 61 6c 6f 6e 67 20 66 69 6e 65 20 77  get along fine w
0670: 69 74 68 6f 75 74 20 74 68 65 20 44 75 72 61 62  ithout the Durab
0680: 6c 69 74 79 2e 0a 2a 2a 0a 2a 2a 20 48 4f 57 20  lity..**.** HOW 
0690: 49 54 20 57 4f 52 4b 53 0a 2a 2a 0a 2a 2a 20 41  IT WORKS.**.** A
06a0: 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49 2f 4f 20  synchronous I/O 
06b0: 77 6f 72 6b 73 20 62 79 20 63 72 65 61 74 69 6e  works by creatin
06c0: 67 20 61 20 73 70 65 63 69 61 6c 20 53 51 4c 69  g a special SQLi
06d0: 74 65 20 22 76 66 73 22 20 73 74 72 75 63 74 75  te "vfs" structu
06e0: 72 65 0a 2a 2a 20 61 6e 64 20 72 65 67 69 73 74  re.** and regist
06f0: 65 72 69 6e 67 20 69 74 20 77 69 74 68 20 73 71  ering it with sq
0700: 6c 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74  lite3_vfs_regist
0710: 65 72 28 29 2e 20 57 68 65 6e 20 66 69 6c 65 73  er(). When files
0720: 20 6f 70 65 6e 65 64 20 76 69 61 20 0a 2a 2a 20   opened via .** 
0730: 74 68 69 73 20 76 66 73 20 61 72 65 20 77 72 69  this vfs are wri
0740: 74 74 65 6e 20 74 6f 20 28 75 73 69 6e 67 20 73  tten to (using s
0750: 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 29 29  qlite3OsWrite())
0760: 2c 20 74 68 65 20 64 61 74 61 20 69 73 20 6e 6f  , the data is no
0770: 74 20 0a 2a 2a 20 77 72 69 74 74 65 6e 20 64 69  t .** written di
0780: 72 65 63 74 6c 79 20 74 6f 20 64 69 73 6b 2c 20  rectly to disk, 
0790: 62 75 74 20 69 73 20 70 6c 61 63 65 64 20 69 6e  but is placed in
07a0: 20 74 68 65 20 22 77 72 69 74 65 2d 71 75 65 75   the "write-queu
07b0: 65 22 20 74 6f 20 62 65 0a 2a 2a 20 68 61 6e 64  e" to be.** hand
07c0: 6c 65 64 20 62 79 20 74 68 65 20 62 61 63 6b 67  led by the backg
07d0: 72 6f 75 6e 64 20 74 68 72 65 61 64 2e 0a 2a 2a  round thread..**
07e0: 0a 2a 2a 20 57 68 65 6e 20 66 69 6c 65 73 20 6f  .** When files o
07f0: 70 65 6e 65 64 20 77 69 74 68 20 74 68 65 20 61  pened with the a
0800: 73 79 6e 63 68 72 6f 6e 6f 75 73 20 76 66 73 20  synchronous vfs 
0810: 61 72 65 20 72 65 61 64 20 66 72 6f 6d 20 0a 2a  are read from .*
0820: 2a 20 28 75 73 69 6e 67 20 73 71 6c 69 74 65 33  * (using sqlite3
0830: 4f 73 52 65 61 64 28 29 29 2c 20 74 68 65 20 64  OsRead()), the d
0840: 61 74 61 20 69 73 20 72 65 61 64 20 66 72 6f 6d  ata is read from
0850: 20 74 68 65 20 66 69 6c 65 20 6f 6e 20 0a 2a 2a   the file on .**
0860: 20 64 69 73 6b 20 61 6e 64 20 74 68 65 20 77 72   disk and the wr
0870: 69 74 65 2d 71 75 65 75 65 2c 20 73 6f 20 74 68  ite-queue, so th
0880: 61 74 20 66 72 6f 6d 20 74 68 65 20 70 6f 69 6e  at from the poin
0890: 74 20 6f 66 20 76 69 65 77 20 6f 66 0a 2a 2a 20  t of view of.** 
08a0: 74 68 65 20 76 66 73 20 72 65 61 64 65 72 20 74  the vfs reader t
08b0: 68 65 20 4f 73 57 72 69 74 65 28 29 20 61 70 70  he OsWrite() app
08c0: 65 61 72 73 20 74 6f 20 68 61 76 65 20 61 6c 72  ears to have alr
08d0: 65 61 64 79 20 63 6f 6d 70 6c 65 74 65 64 2e 0a  eady completed..
08e0: 2a 2a 0a 2a 2a 20 54 68 65 20 73 70 65 63 69 61  **.** The specia
08f0: 6c 20 76 66 73 20 69 73 20 72 65 67 69 73 74 65  l vfs is registe
0900: 72 65 64 20 28 61 6e 64 20 75 6e 72 65 67 69 73  red (and unregis
0910: 74 65 72 65 64 29 20 62 79 20 63 61 6c 6c 73 20  tered) by calls 
0920: 74 6f 20 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20  to .** function 
0930: 61 73 79 6e 63 45 6e 61 62 6c 65 28 29 20 28 73  asyncEnable() (s
0940: 65 65 20 62 65 6c 6f 77 29 2e 0a 2a 2a 0a 2a 2a  ee below)..**.**
0950: 20 4c 49 4d 49 54 41 54 49 4f 4e 53 0a 2a 2a 0a   LIMITATIONS.**.
0960: 2a 2a 20 54 68 69 73 20 64 65 6d 6f 6e 73 74 72  ** This demonstr
0970: 61 74 69 6f 6e 20 63 6f 64 65 20 69 73 20 64 65  ation code is de
0980: 6c 69 62 65 72 61 74 65 6c 79 20 6b 65 70 74 20  liberately kept 
0990: 73 69 6d 70 6c 65 20 69 6e 20 6f 72 64 65 72 20  simple in order 
09a0: 74 6f 20 6b 65 65 70 0a 2a 2a 20 74 68 65 20 6d  to keep.** the m
09b0: 61 69 6e 20 69 64 65 61 73 20 63 6c 65 61 72 20  ain ideas clear 
09c0: 61 6e 64 20 65 61 73 79 20 74 6f 20 75 6e 64 65  and easy to unde
09d0: 72 73 74 61 6e 64 2e 20 20 52 65 61 6c 20 61 70  rstand.  Real ap
09e0: 70 6c 69 63 61 74 69 6f 6e 73 20 74 68 61 74 0a  plications that.
09f0: 2a 2a 20 77 61 6e 74 20 74 6f 20 64 6f 20 61 73  ** want to do as
0a00: 79 6e 63 68 72 6f 6e 6f 75 73 20 49 2f 4f 20 6d  ynchronous I/O m
0a10: 69 67 68 74 20 77 61 6e 74 20 74 6f 20 61 64 64  ight want to add
0a20: 20 61 64 64 69 74 69 6f 6e 61 6c 20 63 61 70 61   additional capa
0a30: 62 69 6c 69 74 69 65 73 2e 0a 2a 2a 20 46 6f 72  bilities..** For
0a40: 20 65 78 61 6d 70 6c 65 2c 20 69 6e 20 74 68 69   example, in thi
0a50: 73 20 64 65 6d 6f 6e 73 74 72 61 74 69 6f 6e 20  s demonstration 
0a60: 69 66 20 77 72 69 74 65 73 20 61 72 65 20 68 61  if writes are ha
0a70: 70 70 65 6e 69 6e 67 20 61 74 20 61 20 73 74 65  ppening at a ste
0a80: 61 64 79 0a 2a 2a 20 73 74 72 65 61 6d 20 74 68  ady.** stream th
0a90: 61 74 20 65 78 63 65 65 64 73 20 74 68 65 20 49  at exceeds the I
0aa0: 2f 4f 20 63 61 70 61 62 69 6c 69 74 79 20 6f 66  /O capability of
0ab0: 20 74 68 65 20 62 61 63 6b 67 72 6f 75 6e 64 20   the background 
0ac0: 77 72 69 74 65 72 20 74 68 72 65 61 64 2c 0a 2a  writer thread,.*
0ad0: 2a 20 74 68 65 20 71 75 65 75 65 20 6f 66 20 70  * the queue of p
0ae0: 65 6e 64 69 6e 67 20 77 72 69 74 65 20 6f 70 65  ending write ope
0af0: 72 61 74 69 6f 6e 73 20 77 69 6c 6c 20 67 72 6f  rations will gro
0b00: 77 20 77 69 74 68 6f 75 74 20 62 6f 75 6e 64 20  w without bound 
0b10: 75 6e 74 69 6c 20 77 65 0a 2a 2a 20 72 75 6e 20  until we.** run 
0b20: 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 2e 20 20  out of memory.  
0b30: 55 73 65 72 73 20 6f 66 20 74 68 69 73 20 74 65  Users of this te
0b40: 63 68 6e 69 71 75 65 20 6d 61 79 20 77 61 6e 74  chnique may want
0b50: 20 74 6f 20 6b 65 65 70 20 74 72 61 63 6b 20 6f   to keep track o
0b60: 66 0a 2a 2a 20 74 68 65 20 71 75 61 6e 74 69 74  f.** the quantit
0b70: 79 20 6f 66 20 70 65 6e 64 69 6e 67 20 77 72 69  y of pending wri
0b80: 74 65 73 20 61 6e 64 20 73 74 6f 70 20 61 63 63  tes and stop acc
0b90: 65 70 74 69 6e 67 20 6e 65 77 20 77 72 69 74 65  epting new write
0ba0: 20 72 65 71 75 65 73 74 73 0a 2a 2a 20 77 68 65   requests.** whe
0bb0: 6e 20 74 68 65 20 62 75 66 66 65 72 20 67 65 74  n the buffer get
0bc0: 73 20 74 6f 20 62 65 20 74 6f 6f 20 62 69 67 2e  s to be too big.
0bd0: 0a 2a 2a 0a 2a 2a 20 4c 4f 43 4b 49 4e 47 20 2b  .**.** LOCKING +
0be0: 20 43 4f 4e 43 55 52 52 45 4e 43 59 0a 2a 2a 0a   CONCURRENCY.**.
0bf0: 2a 2a 20 4d 75 6c 74 69 70 6c 65 20 63 6f 6e 6e  ** Multiple conn
0c00: 65 63 74 69 6f 6e 73 20 66 72 6f 6d 20 77 69 74  ections from wit
0c10: 68 69 6e 20 61 20 73 69 6e 67 6c 65 20 70 72 6f  hin a single pro
0c20: 63 65 73 73 20 74 68 61 74 20 75 73 65 20 74 68  cess that use th
0c30: 69 73 0a 2a 2a 20 69 6d 70 6c 65 6d 65 6e 74 61  is.** implementa
0c40: 74 69 6f 6e 20 6f 66 20 61 73 79 6e 63 68 72 6f  tion of asynchro
0c50: 6e 6f 75 73 20 49 4f 20 6d 61 79 20 61 63 63 65  nous IO may acce
0c60: 73 73 20 61 20 73 69 6e 67 6c 65 20 64 61 74 61  ss a single data
0c70: 62 61 73 65 0a 2a 2a 20 66 69 6c 65 20 63 6f 6e  base.** file con
0c80: 63 75 72 72 65 6e 74 6c 79 2e 20 46 72 6f 6d 20  currently. From 
0c90: 74 68 65 20 70 6f 69 6e 74 20 6f 66 20 76 69 65  the point of vie
0ca0: 77 20 6f 66 20 74 68 65 20 75 73 65 72 2c 20 69  w of the user, i
0cb0: 66 20 61 6c 6c 0a 2a 2a 20 63 6f 6e 6e 65 63 74  f all.** connect
0cc0: 69 6f 6e 73 20 61 72 65 20 66 72 6f 6d 20 77 69  ions are from wi
0cd0: 74 68 69 6e 20 61 20 73 69 6e 67 6c 65 20 70 72  thin a single pr
0ce0: 6f 63 65 73 73 2c 20 74 68 65 72 65 20 69 73 20  ocess, there is 
0cf0: 6e 6f 20 64 69 66 66 65 72 65 6e 63 65 0a 2a 2a  no difference.**
0d00: 20 62 65 74 77 65 65 6e 20 74 68 65 20 63 6f 6e   between the con
0d10: 63 75 72 72 65 6e 63 79 20 6f 66 66 65 72 65 64  currency offered
0d20: 20 62 79 20 22 6e 6f 72 6d 61 6c 22 20 53 51 4c   by "normal" SQL
0d30: 69 74 65 20 61 6e 64 20 53 51 4c 69 74 65 0a 2a  ite and SQLite.*
0d40: 2a 20 75 73 69 6e 67 20 74 68 65 20 61 73 79 6e  * using the asyn
0d50: 63 68 72 6f 6e 6f 75 73 20 62 61 63 6b 65 6e 64  chronous backend
0d60: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 63 6f 6e 6e 65  ..**.** If conne
0d70: 63 74 69 6f 6e 73 20 66 72 6f 6d 20 77 69 74 68  ctions from with
0d80: 69 6e 20 6d 75 6c 74 69 70 6c 65 20 64 61 74 61  in multiple data
0d90: 62 61 73 65 20 66 69 6c 65 73 20 6d 61 79 20 61  base files may a
0da0: 63 63 65 73 73 20 74 68 65 0a 2a 2a 20 64 61 74  ccess the.** dat
0db0: 61 62 61 73 65 20 66 69 6c 65 2c 20 74 68 65 20  abase file, the 
0dc0: 45 4e 41 42 4c 45 5f 46 49 4c 45 5f 4c 4f 43 4b  ENABLE_FILE_LOCK
0dd0: 49 4e 47 20 73 79 6d 62 6f 6c 20 28 73 65 65 20  ING symbol (see 
0de0: 62 65 6c 6f 77 29 20 6d 75 73 74 20 62 65 0a 2a  below) must be.*
0df0: 2a 20 64 65 66 69 6e 65 64 2e 20 49 66 20 69 74  * defined. If it
0e00: 20 69 73 20 6e 6f 74 20 64 65 66 69 6e 65 64 2c   is not defined,
0e10: 20 74 68 65 6e 20 6e 6f 20 6c 6f 63 6b 73 20 61   then no locks a
0e20: 72 65 20 65 73 74 61 62 6c 69 73 68 65 64 20 6f  re established o
0e30: 6e 20 0a 2a 2a 20 74 68 65 20 64 61 74 61 62 61  n .** the databa
0e40: 73 65 20 66 69 6c 65 2e 20 49 6e 20 74 68 69 73  se file. In this
0e50: 20 63 61 73 65 2c 20 69 66 20 6d 75 6c 74 69 70   case, if multip
0e60: 6c 65 20 70 72 6f 63 65 73 73 65 73 20 61 63 63  le processes acc
0e70: 65 73 73 20 0a 2a 2a 20 74 68 65 20 64 61 74 61  ess .** the data
0e80: 62 61 73 65 20 66 69 6c 65 2c 20 63 6f 72 72 75  base file, corru
0e90: 70 74 69 6f 6e 20 77 69 6c 6c 20 71 75 69 63 6b  ption will quick
0ea0: 6c 79 20 72 65 73 75 6c 74 2e 0a 2a 2a 0a 2a 2a  ly result..**.**
0eb0: 20 49 66 20 45 4e 41 42 4c 45 5f 46 49 4c 45 5f   If ENABLE_FILE_
0ec0: 4c 4f 43 4b 49 4e 47 20 69 73 20 64 65 66 69 6e  LOCKING is defin
0ed0: 65 64 20 28 74 68 65 20 64 65 66 61 75 6c 74 29  ed (the default)
0ee0: 2c 20 74 68 65 6e 20 63 6f 6e 6e 65 63 74 69 6f  , then connectio
0ef0: 6e 73 20 0a 2a 2a 20 66 72 6f 6d 20 77 69 74 68  ns .** from with
0f00: 69 6e 20 6d 75 6c 74 69 70 6c 65 20 70 72 6f 63  in multiple proc
0f10: 65 73 73 65 73 20 6d 61 79 20 61 63 63 65 73 73  esses may access
0f20: 20 61 20 73 69 6e 67 6c 65 20 64 61 74 61 62 61   a single databa
0f30: 73 65 20 66 69 6c 65 20 0a 2a 2a 20 77 69 74 68  se file .** with
0f40: 6f 75 74 20 72 69 73 6b 69 6e 67 20 63 6f 72 72  out risking corr
0f50: 75 70 74 69 6f 6e 2e 20 48 6f 77 65 76 65 72 20  uption. However 
0f60: 63 6f 6e 63 75 72 72 65 6e 63 79 20 69 73 20 72  concurrency is r
0f70: 65 64 75 63 65 64 20 61 73 0a 2a 2a 20 66 6f 6c  educed as.** fol
0f80: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 2a 20  lows:.**.**   * 
0f90: 57 68 65 6e 20 61 20 63 6f 6e 6e 65 63 74 69 6f  When a connectio
0fa0: 6e 20 75 73 69 6e 67 20 61 73 79 6e 63 68 72 6f  n using asynchro
0fb0: 6e 6f 75 73 20 49 4f 20 62 65 67 69 6e 73 20 61  nous IO begins a
0fc0: 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 20 20 20   database.**    
0fd0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68   transaction, th
0fe0: 65 20 64 61 74 61 62 61 73 65 20 69 73 20 6c 6f  e database is lo
0ff0: 63 6b 65 64 20 69 6d 6d 65 64 69 61 74 65 6c 79  cked immediately
1000: 2e 20 48 6f 77 65 76 65 72 20 74 68 65 0a 2a 2a  . However the.**
1010: 20 20 20 20 20 6c 6f 63 6b 20 69 73 20 6e 6f 74       lock is not
1020: 20 72 65 6c 65 61 73 65 64 20 75 6e 74 69 6c 20   released until 
1030: 61 66 74 65 72 20 61 6c 6c 20 72 65 6c 65 76 61  after all releva
1040: 6e 74 20 6f 70 65 72 61 74 69 6f 6e 73 0a 2a 2a  nt operations.**
1050: 20 20 20 20 20 69 6e 20 74 68 65 20 77 72 69 74       in the writ
1060: 65 2d 71 75 65 75 65 20 68 61 76 65 20 62 65 65  e-queue have bee
1070: 6e 20 66 6c 75 73 68 65 64 20 74 6f 20 64 69 73  n flushed to dis
1080: 6b 2e 20 54 68 69 73 20 6d 65 61 6e 73 0a 2a 2a  k. This means.**
1090: 20 20 20 20 20 28 66 6f 72 20 65 78 61 6d 70 6c       (for exampl
10a0: 65 29 20 74 68 61 74 20 74 68 65 20 64 61 74 61  e) that the data
10b0: 62 61 73 65 20 6d 61 79 20 72 65 6d 61 69 6e 20  base may remain 
10c0: 6c 6f 63 6b 65 64 20 66 6f 72 20 73 6f 6d 65 20  locked for some 
10d0: 0a 2a 2a 20 20 20 20 20 74 69 6d 65 20 61 66 74  .**     time aft
10e0: 65 72 20 61 20 22 43 4f 4d 4d 49 54 22 20 6f 72  er a "COMMIT" or
10f0: 20 22 52 4f 4c 4c 42 41 43 4b 22 20 69 73 20 69   "ROLLBACK" is i
1100: 73 73 75 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 2a  ssued..**.**   *
1110: 20 49 66 20 61 6e 20 61 70 70 6c 69 63 61 74 69   If an applicati
1120: 6f 6e 20 75 73 69 6e 67 20 61 73 79 6e 63 68 72  on using asynchr
1130: 6f 6e 6f 75 73 20 49 4f 20 65 78 65 63 75 74 65  onous IO execute
1140: 73 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 0a 2a  s transactions.*
1150: 2a 20 20 20 20 20 69 6e 20 71 75 69 63 6b 20 73  *     in quick s
1160: 75 63 63 65 73 73 69 6f 6e 2c 20 6f 74 68 65 72  uccession, other
1170: 20 64 61 74 61 62 61 73 65 20 75 73 65 72 73 20   database users 
1180: 6d 61 79 20 62 65 20 65 66 66 65 63 74 69 76 65  may be effective
1190: 6c 79 0a 2a 2a 20 20 20 20 20 6c 6f 63 6b 65 64  ly.**     locked
11a0: 20 6f 75 74 20 6f 66 20 74 68 65 20 64 61 74 61   out of the data
11b0: 62 61 73 65 2e 20 54 68 69 73 20 69 73 20 62 65  base. This is be
11c0: 63 61 75 73 65 20 77 68 65 6e 20 61 20 42 45 47  cause when a BEG
11d0: 49 4e 0a 2a 2a 20 20 20 20 20 69 73 20 65 78 65  IN.**     is exe
11e0: 63 75 74 65 64 2c 20 61 20 64 61 74 61 62 61 73  cuted, a databas
11f0: 65 20 6c 6f 63 6b 20 69 73 20 65 73 74 61 62 6c  e lock is establ
1200: 69 73 68 65 64 20 69 6d 6d 65 64 69 61 74 65 6c  ished immediatel
1210: 79 2e 20 42 75 74 0a 2a 2a 20 20 20 20 20 77 68  y. But.**     wh
1220: 65 6e 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e  en the correspon
1230: 64 69 6e 67 20 43 4f 4d 4d 49 54 20 6f 72 20 52  ding COMMIT or R
1240: 4f 4c 4c 42 41 43 4b 20 6f 63 63 75 72 73 2c 20  OLLBACK occurs, 
1250: 74 68 65 20 6c 6f 63 6b 0a 2a 2a 20 20 20 20 20  the lock.**     
1260: 69 73 20 6e 6f 74 20 72 65 6c 65 61 73 65 64 20  is not released 
1270: 75 6e 74 69 6c 20 74 68 65 20 72 65 6c 65 76 61  until the releva
1280: 6e 74 20 70 61 72 74 20 6f 66 20 74 68 65 20 77  nt part of the w
1290: 72 69 74 65 2d 71 75 65 75 65 20 0a 2a 2a 20 20  rite-queue .**  
12a0: 20 20 20 68 61 73 20 62 65 65 6e 20 66 6c 75 73     has been flus
12b0: 68 65 64 20 74 68 72 6f 75 67 68 2e 20 41 73 20  hed through. As 
12c0: 61 20 72 65 73 75 6c 74 2c 20 69 66 20 61 20 43  a result, if a C
12d0: 4f 4d 4d 49 54 20 69 73 20 66 6f 6c 6c 6f 77 65  OMMIT is followe
12e0: 64 0a 2a 2a 20 20 20 20 20 62 79 20 61 20 42 45  d.**     by a BE
12f0: 47 49 4e 20 62 65 66 6f 72 65 20 74 68 65 20 77  GIN before the w
1300: 72 69 74 65 2d 71 75 65 75 65 20 69 73 20 66 6c  rite-queue is fl
1310: 75 73 68 65 64 20 74 68 72 6f 75 67 68 2c 20 74  ushed through, t
1320: 68 65 20 64 61 74 61 62 61 73 65 20 0a 2a 2a 20  he database .** 
1330: 20 20 20 20 69 73 20 6e 65 76 65 72 20 75 6e 6c      is never unl
1340: 6f 63 6b 65 64 2c 70 72 65 76 65 6e 74 69 6e 67  ocked,preventing
1350: 20 6f 74 68 65 72 20 70 72 6f 63 65 73 73 65 73   other processes
1360: 20 66 72 6f 6d 20 61 63 63 65 73 73 69 6e 67 20   from accessing 
1370: 0a 2a 2a 20 20 20 20 20 74 68 65 20 64 61 74 61  .**     the data
1380: 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 44 65 66 69  base..**.** Defi
1390: 6e 69 6e 67 20 45 4e 41 42 4c 45 5f 46 49 4c 45  ning ENABLE_FILE
13a0: 5f 4c 4f 43 4b 49 4e 47 20 77 68 65 6e 20 75 73  _LOCKING when us
13b0: 69 6e 67 20 61 6e 20 4e 46 53 20 6f 72 20 6f 74  ing an NFS or ot
13c0: 68 65 72 20 72 65 6d 6f 74 65 20 0a 2a 2a 20 66  her remote .** f
13d0: 69 6c 65 2d 73 79 73 74 65 6d 20 6d 61 79 20 73  ile-system may s
13e0: 6c 6f 77 20 74 68 69 6e 67 73 20 64 6f 77 6e 2c  low things down,
13f0: 20 61 73 20 73 79 6e 63 68 72 6f 6e 6f 75 73 20   as synchronous 
1400: 72 6f 75 6e 64 2d 74 72 69 70 73 20 74 6f 20 74  round-trips to t
1410: 68 65 20 0a 2a 2a 20 73 65 72 76 65 72 20 6d 61  he .** server ma
1420: 79 20 62 65 20 72 65 71 75 69 72 65 64 20 74 6f  y be required to
1430: 20 65 73 74 61 62 6c 69 73 68 20 64 61 74 61 62   establish datab
1440: 61 73 65 20 66 69 6c 65 20 6c 6f 63 6b 73 2e 0a  ase file locks..
1450: 2a 2f 0a 23 64 65 66 69 6e 65 20 45 4e 41 42 4c  */.#define ENABL
1460: 45 5f 46 49 4c 45 5f 4c 4f 43 4b 49 4e 47 0a 0a  E_FILE_LOCKING..
1470: 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 41  #ifndef SQLITE_A
1480: 4d 41 4c 47 41 4d 41 54 49 4f 4e 0a 23 20 69 6e  MALGAMATION.# in
1490: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74  clude "sqliteInt
14a0: 2e 68 22 0a 23 20 69 6e 63 6c 75 64 65 20 3c 61  .h".# include <a
14b0: 73 73 65 72 74 2e 68 3e 0a 23 20 69 6e 63 6c 75  ssert.h>.# inclu
14c0: 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 65  de <string.h>.#e
14d0: 6e 64 69 66 0a 23 69 6e 63 6c 75 64 65 20 3c 74  ndif.#include <t
14e0: 63 6c 2e 68 3e 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  cl.h>../*.** Thi
14f0: 73 20 74 65 73 74 20 75 73 65 73 20 70 74 68 72  s test uses pthr
1500: 65 61 64 73 20 61 6e 64 20 68 65 6e 63 65 20 6f  eads and hence o
1510: 6e 6c 79 20 77 6f 72 6b 73 20 6f 6e 20 75 6e 69  nly works on uni
1520: 78 20 61 6e 64 20 77 69 74 68 0a 2a 2a 20 61 20  x and with.** a 
1530: 74 68 72 65 61 64 73 61 66 65 20 62 75 69 6c 64  threadsafe build
1540: 20 6f 66 20 53 51 4c 69 74 65 2e 0a 2a 2f 0a 23   of SQLite..*/.#
1550: 69 66 20 53 51 4c 49 54 45 5f 4f 53 5f 55 4e 49  if SQLITE_OS_UNI
1560: 58 20 26 26 20 53 51 4c 49 54 45 5f 54 48 52 45  X && SQLITE_THRE
1570: 41 44 53 41 46 45 0a 0a 2f 2a 0a 2a 2a 20 54 68  ADSAFE../*.** Th
1580: 69 73 20 64 65 6d 6f 20 75 73 65 73 20 70 74 68  is demo uses pth
1590: 72 65 61 64 73 2e 20 20 49 66 20 79 6f 75 20 64  reads.  If you d
15a0: 6f 20 6e 6f 74 20 68 61 76 65 20 61 20 70 74 68  o not have a pth
15b0: 72 65 61 64 73 20 69 6d 70 6c 65 6d 65 6e 74 61  reads implementa
15c0: 74 69 6f 6e 0a 2a 2a 20 66 6f 72 20 79 6f 75 72  tion.** for your
15d0: 20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65   operating syste
15e0: 6d 2c 20 79 6f 75 20 77 69 6c 6c 20 6e 65 65 64  m, you will need
15f0: 20 74 6f 20 72 65 63 6f 64 65 20 74 68 65 20 74   to recode the t
1600: 68 72 65 61 64 69 6e 67 20 0a 2a 2a 20 6c 6f 67  hreading .** log
1610: 69 63 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20  ic..*/.#include 
1620: 3c 70 74 68 72 65 61 64 2e 68 3e 0a 23 69 6e 63  <pthread.h>.#inc
1630: 6c 75 64 65 20 3c 73 63 68 65 64 2e 68 3e 0a 0a  lude <sched.h>..
1640: 2f 2a 20 55 73 65 66 75 6c 20 6d 61 63 72 6f 73  /* Useful macros
1650: 20 75 73 65 64 20 69 6e 20 73 65 76 65 72 61 6c   used in several
1660: 20 70 6c 61 63 65 73 20 2a 2f 0a 23 64 65 66 69   places */.#defi
1670: 6e 65 20 4d 49 4e 28 78 2c 79 29 20 28 28 78 29  ne MIN(x,y) ((x)
1680: 3c 28 79 29 3f 28 78 29 3a 28 79 29 29 0a 23 64  <(y)?(x):(y)).#d
1690: 65 66 69 6e 65 20 4d 41 58 28 78 2c 79 29 20 28  efine MAX(x,y) (
16a0: 28 78 29 3e 28 79 29 3f 28 78 29 3a 28 79 29 29  (x)>(y)?(x):(y))
16b0: 0a 0a 2f 2a 20 46 6f 72 77 61 72 64 20 72 65 66  ../* Forward ref
16c0: 65 72 65 6e 63 65 73 20 2a 2f 0a 74 79 70 65 64  erences */.typed
16d0: 65 66 20 73 74 72 75 63 74 20 41 73 79 6e 63 57  ef struct AsyncW
16e0: 72 69 74 65 20 41 73 79 6e 63 57 72 69 74 65 3b  rite AsyncWrite;
16f0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
1700: 41 73 79 6e 63 46 69 6c 65 20 41 73 79 6e 63 46  AsyncFile AsyncF
1710: 69 6c 65 3b 0a 74 79 70 65 64 65 66 20 73 74 72  ile;.typedef str
1720: 75 63 74 20 41 73 79 6e 63 46 69 6c 65 44 61 74  uct AsyncFileDat
1730: 61 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 3b  a AsyncFileData;
1740: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
1750: 41 73 79 6e 63 46 69 6c 65 4c 6f 63 6b 20 41 73  AsyncFileLock As
1760: 79 6e 63 46 69 6c 65 4c 6f 63 6b 3b 0a 74 79 70  yncFileLock;.typ
1770: 65 64 65 66 20 73 74 72 75 63 74 20 41 73 79 6e  edef struct Asyn
1780: 63 4c 6f 63 6b 20 41 73 79 6e 63 4c 6f 63 6b 3b  cLock AsyncLock;
1790: 0a 0a 2f 2a 20 45 6e 61 62 6c 65 20 66 6f 72 20  ../* Enable for 
17a0: 64 65 62 75 67 67 69 6e 67 20 2a 2f 0a 73 74 61  debugging */.sta
17b0: 74 69 63 20 69 6e 74 20 73 71 6c 69 74 65 33 61  tic int sqlite3a
17c0: 73 79 6e 63 5f 74 72 61 63 65 20 3d 20 30 3b 0a  sync_trace = 0;.
17d0: 23 20 64 65 66 69 6e 65 20 41 53 59 4e 43 5f 54  # define ASYNC_T
17e0: 52 41 43 45 28 58 29 20 69 66 28 20 73 71 6c 69  RACE(X) if( sqli
17f0: 74 65 33 61 73 79 6e 63 5f 74 72 61 63 65 20 29  te3async_trace )
1800: 20 61 73 79 6e 63 54 72 61 63 65 20 58 0a 73 74   asyncTrace X.st
1810: 61 74 69 63 20 76 6f 69 64 20 61 73 79 6e 63 54  atic void asyncT
1820: 72 61 63 65 28 63 6f 6e 73 74 20 63 68 61 72 20  race(const char 
1830: 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a  *zFormat, ...){.
1840: 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 76 61 5f    char *z;.  va_
1850: 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74  list ap;.  va_st
1860: 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29  art(ap, zFormat)
1870: 3b 0a 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f  ;.  z = sqlite3_
1880: 76 6d 70 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74  vmprintf(zFormat
1890: 2c 20 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28  , ap);.  va_end(
18a0: 61 70 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 73  ap);.  fprintf(s
18b0: 74 64 65 72 72 2c 20 22 5b 25 64 5d 20 25 73 22  tderr, "[%d] %s"
18c0: 2c 20 28 69 6e 74 29 70 74 68 72 65 61 64 5f 73  , (int)pthread_s
18d0: 65 6c 66 28 29 2c 20 7a 29 3b 0a 20 20 73 71 6c  elf(), z);.  sql
18e0: 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 7d 0a  ite3_free(z);.}.
18f0: 0a 2f 2a 0a 2a 2a 20 54 48 52 45 41 44 20 53 41  ./*.** THREAD SA
1900: 46 45 54 59 20 4e 4f 54 45 53 0a 2a 2a 0a 2a 2a  FETY NOTES.**.**
1910: 20 42 61 73 69 63 20 72 75 6c 65 73 3a 0a 2a 2a   Basic rules:.**
1920: 0a 2a 2a 20 20 20 20 20 2a 20 42 6f 74 68 20 72  .**     * Both r
1930: 65 61 64 20 61 6e 64 20 77 72 69 74 65 20 61 63  ead and write ac
1940: 63 65 73 73 20 74 6f 20 74 68 65 20 67 6c 6f 62  cess to the glob
1950: 61 6c 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75  al write-op queu
1960: 65 20 6d 75 73 74 20 62 65 20 0a 2a 2a 20 20 20  e must be .**   
1970: 20 20 20 20 70 72 6f 74 65 63 74 65 64 20 62 79      protected by
1980: 20 74 68 65 20 61 73 79 6e 63 2e 71 75 65 75 65   the async.queue
1990: 4d 75 74 65 78 2e 20 41 73 20 61 72 65 20 74 68  Mutex. As are th
19a0: 65 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 20  e async.ioError 
19b0: 61 6e 64 0a 2a 2a 20 20 20 20 20 20 20 61 73 79  and.**       asy
19c0: 6e 63 2e 6e 46 69 6c 65 20 76 61 72 69 61 62 6c  nc.nFile variabl
19d0: 65 73 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20  es..**.**     * 
19e0: 54 68 65 20 61 73 79 6e 63 2e 70 4c 6f 63 6b 20  The async.pLock 
19f0: 6c 69 73 74 20 61 6e 64 20 61 6c 6c 20 41 73 79  list and all Asy
1a00: 6e 63 4c 6f 63 6b 20 61 6e 64 20 41 73 79 6e 63  ncLock and Async
1a10: 46 69 6c 65 4c 6f 63 6b 0a 2a 2a 20 20 20 20 20  FileLock.**     
1a20: 20 20 73 74 72 75 63 74 75 72 65 73 20 6d 75 73    structures mus
1a30: 74 20 62 65 20 70 72 6f 74 65 63 74 65 64 20 62  t be protected b
1a40: 79 20 74 68 65 20 61 73 79 6e 63 2e 6c 6f 63 6b  y the async.lock
1a50: 4d 75 74 65 78 20 6d 75 74 65 78 2e 0a 2a 2a 0a  Mutex mutex..**.
1a60: 2a 2a 20 20 20 20 20 2a 20 54 68 65 20 66 69 6c  **     * The fil
1a70: 65 20 68 61 6e 64 6c 65 73 20 66 72 6f 6d 20 74  e handles from t
1a80: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 73 79  he underlying sy
1a90: 73 74 65 6d 20 61 72 65 20 6e 6f 74 20 61 73 73  stem are not ass
1aa0: 75 6d 65 64 20 74 6f 20 0a 2a 2a 20 20 20 20 20  umed to .**     
1ab0: 20 20 62 65 20 74 68 72 65 61 64 20 73 61 66 65    be thread safe
1ac0: 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 53 65  ..**.**     * Se
1ad0: 65 20 74 68 65 20 6c 61 73 74 20 74 77 6f 20 70  e the last two p
1ae0: 61 72 61 67 72 61 70 68 73 20 75 6e 64 65 72 20  aragraphs under 
1af0: 22 54 68 65 20 57 72 69 74 65 72 20 54 68 72 65  "The Writer Thre
1b00: 61 64 22 20 66 6f 72 0a 2a 2a 20 20 20 20 20 20  ad" for.**      
1b10: 20 61 6e 20 61 73 73 75 6d 70 74 69 6f 6e 20 74   an assumption t
1b20: 6f 20 64 6f 20 77 69 74 68 20 66 69 6c 65 2d 68  o do with file-h
1b30: 61 6e 64 6c 65 20 73 79 6e 63 68 72 6f 6e 69 7a  andle synchroniz
1b40: 61 74 69 6f 6e 20 62 79 20 74 68 65 20 4f 73 2e  ation by the Os.
1b50: 0a 2a 2a 0a 2a 2a 20 44 65 61 64 6c 6f 63 6b 20  .**.** Deadlock 
1b60: 70 72 65 76 65 6e 74 69 6f 6e 3a 0a 2a 2a 0a 2a  prevention:.**.*
1b70: 2a 20 20 20 20 20 54 68 65 72 65 20 61 72 65 20  *     There are 
1b80: 74 68 72 65 65 20 6d 75 74 65 78 20 75 73 65 64  three mutex used
1b90: 20 62 79 20 74 68 65 20 73 79 73 74 65 6d 3a 20   by the system: 
1ba0: 74 68 65 20 22 77 72 69 74 65 72 22 20 6d 75 74  the "writer" mut
1bb0: 65 78 2c 20 0a 2a 2a 20 20 20 20 20 74 68 65 20  ex, .**     the 
1bc0: 22 71 75 65 75 65 22 20 6d 75 74 65 78 20 61 6e  "queue" mutex an
1bd0: 64 20 74 68 65 20 22 6c 6f 63 6b 22 20 6d 75 74  d the "lock" mut
1be0: 65 78 2e 20 52 75 6c 65 73 20 61 72 65 3a 0a 2a  ex. Rules are:.*
1bf0: 2a 0a 2a 2a 20 20 20 20 20 2a 20 49 74 20 69 73  *.**     * It is
1c00: 20 69 6c 6c 65 67 61 6c 20 74 6f 20 62 6c 6f 63   illegal to bloc
1c10: 6b 20 6f 6e 20 74 68 65 20 77 72 69 74 65 72 20  k on the writer 
1c20: 6d 75 74 65 78 20 77 68 65 6e 20 61 6e 79 20 6f  mutex when any o
1c30: 74 68 65 72 20 6d 75 74 65 78 0a 2a 2a 20 20 20  ther mutex.**   
1c40: 20 20 20 20 61 72 65 20 68 65 6c 64 2c 20 61 6e      are held, an
1c50: 64 20 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 49  d .**.**     * I
1c60: 74 20 69 73 20 69 6c 6c 65 67 61 6c 20 74 6f 20  t is illegal to 
1c70: 62 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 71 75 65  block on the que
1c80: 75 65 20 6d 75 74 65 78 20 77 68 65 6e 20 74 68  ue mutex when th
1c90: 65 20 6c 6f 63 6b 20 6d 75 74 65 78 0a 2a 2a 20  e lock mutex.** 
1ca0: 20 20 20 20 20 20 69 73 20 68 65 6c 64 2e 0a 2a        is held..*
1cb0: 2a 0a 2a 2a 20 20 20 20 20 69 2e 65 2e 20 6d 75  *.**     i.e. mu
1cc0: 74 65 78 27 73 20 6d 75 73 74 20 62 65 20 67 72  tex's must be gr
1cd0: 61 62 62 65 64 20 69 6e 20 74 68 65 20 6f 72 64  abbed in the ord
1ce0: 65 72 20 22 77 72 69 74 65 72 22 2c 20 22 71 75  er "writer", "qu
1cf0: 65 75 65 22 2c 20 22 6c 6f 63 6b 22 2e 0a 2a 2a  eue", "lock"..**
1d00: 0a 2a 2a 20 46 69 6c 65 20 73 79 73 74 65 6d 20  .** File system 
1d10: 6f 70 65 72 61 74 69 6f 6e 73 20 28 69 6e 76 6f  operations (invo
1d20: 6b 65 64 20 62 79 20 53 51 4c 69 74 65 20 74 68  ked by SQLite th
1d30: 72 65 61 64 29 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  read):.**.**    
1d40: 20 78 4f 70 65 6e 0a 2a 2a 20 20 20 20 20 78 44   xOpen.**     xD
1d50: 65 6c 65 74 65 0a 2a 2a 20 20 20 20 20 78 46 69  elete.**     xFi
1d60: 6c 65 45 78 69 73 74 73 0a 2a 2a 0a 2a 2a 20 46  leExists.**.** F
1d70: 69 6c 65 20 68 61 6e 64 6c 65 20 6f 70 65 72 61  ile handle opera
1d80: 74 69 6f 6e 73 20 28 69 6e 76 6f 6b 65 64 20 62  tions (invoked b
1d90: 79 20 53 51 4c 69 74 65 20 74 68 72 65 61 64 29  y SQLite thread)
1da0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 20  :.**.**         
1db0: 61 73 79 6e 63 57 72 69 74 65 2c 20 61 73 79 6e  asyncWrite, asyn
1dc0: 63 43 6c 6f 73 65 2c 20 61 73 79 6e 63 54 72 75  cClose, asyncTru
1dd0: 6e 63 61 74 65 2c 20 61 73 79 6e 63 53 79 6e 63  ncate, asyncSync
1de0: 20 0a 2a 2a 20 20 20 20 0a 2a 2a 20 20 20 20 20   .**    .**     
1df0: 54 68 65 20 6f 70 65 72 61 74 69 6f 6e 73 20 61  The operations a
1e00: 62 6f 76 65 20 61 64 64 20 61 6e 20 65 6e 74 72  bove add an entr
1e10: 79 20 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c 20  y to the global 
1e20: 77 72 69 74 65 2d 6f 70 20 6c 69 73 74 2e 20 54  write-op list. T
1e30: 68 65 79 0a 2a 2a 20 20 20 20 20 70 72 65 70 61  hey.**     prepa
1e40: 72 65 20 74 68 65 20 65 6e 74 72 79 2c 20 61 63  re the entry, ac
1e50: 71 75 69 72 65 20 74 68 65 20 61 73 79 6e 63 2e  quire the async.
1e60: 71 75 65 75 65 4d 75 74 65 78 20 6d 6f 6d 65 6e  queueMutex momen
1e70: 74 61 72 69 6c 79 20 77 68 69 6c 65 0a 2a 2a 20  tarily while.** 
1e80: 20 20 20 20 6c 69 73 74 20 70 6f 69 6e 74 65 72      list pointer
1e90: 73 20 61 72 65 20 20 6d 61 6e 69 70 75 6c 61 74  s are  manipulat
1ea0: 65 64 20 74 6f 20 69 6e 73 65 72 74 20 74 68 65  ed to insert the
1eb0: 20 6e 65 77 20 65 6e 74 72 79 2c 20 74 68 65 6e   new entry, then
1ec0: 20 72 65 6c 65 61 73 65 0a 2a 2a 20 20 20 20 20   release.**     
1ed0: 74 68 65 20 6d 75 74 65 78 20 61 6e 64 20 73 69  the mutex and si
1ee0: 67 6e 61 6c 20 74 68 65 20 77 72 69 74 65 72 20  gnal the writer 
1ef0: 74 68 72 65 61 64 20 74 6f 20 77 61 6b 65 20 75  thread to wake u
1f00: 70 20 69 6e 20 63 61 73 65 20 69 74 20 68 61 70  p in case it hap
1f10: 70 65 6e 73 0a 2a 2a 20 20 20 20 20 74 6f 20 62  pens.**     to b
1f20: 65 20 61 73 6c 65 65 70 2e 0a 2a 2a 0a 2a 2a 20  e asleep..**.** 
1f30: 20 20 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 61     .**         a
1f40: 73 79 6e 63 52 65 61 64 2c 20 61 73 79 6e 63 46  syncRead, asyncF
1f50: 69 6c 65 53 69 7a 65 2e 0a 2a 2a 0a 2a 2a 20 20  ileSize..**.**  
1f60: 20 20 20 52 65 61 64 20 6f 70 65 72 61 74 69 6f     Read operatio
1f70: 6e 73 2e 20 42 6f 74 68 20 6f 66 20 74 68 65 73  ns. Both of thes
1f80: 65 20 72 65 61 64 20 66 72 6f 6d 20 62 6f 74 68  e read from both
1f90: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20   the underlying 
1fa0: 66 69 6c 65 0a 2a 2a 20 20 20 20 20 66 69 72 73  file.**     firs
1fb0: 74 20 74 68 65 6e 20 61 64 6a 75 73 74 20 74 68  t then adjust th
1fc0: 65 69 72 20 72 65 73 75 6c 74 20 62 61 73 65 64  eir result based
1fd0: 20 6f 6e 20 70 65 6e 64 69 6e 67 20 77 72 69 74   on pending writ
1fe0: 65 73 20 69 6e 20 74 68 65 20 0a 2a 2a 20 20 20  es in the .**   
1ff0: 20 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75 65    write-op queue
2000: 2e 20 20 20 53 6f 20 61 73 79 6e 63 2e 71 75 65  .   So async.que
2010: 75 65 4d 75 74 65 78 20 69 73 20 68 65 6c 64 20  ueMutex is held 
2020: 66 6f 72 20 74 68 65 20 64 75 72 61 74 69 6f 6e  for the duration
2030: 0a 2a 2a 20 20 20 20 20 6f 66 20 74 68 65 73 65  .**     of these
2040: 20 6f 70 65 72 61 74 69 6f 6e 73 20 74 6f 20 70   operations to p
2050: 72 65 76 65 6e 74 20 6f 74 68 65 72 20 74 68 72  revent other thr
2060: 65 61 64 73 20 66 72 6f 6d 20 63 68 61 6e 67 69  eads from changi
2070: 6e 67 20 74 68 65 0a 2a 2a 20 20 20 20 20 71 75  ng the.**     qu
2080: 65 75 65 20 69 6e 20 6d 69 64 20 6f 70 65 72 61  eue in mid opera
2090: 74 69 6f 6e 2e 0a 2a 2a 20 20 20 20 0a 2a 2a 0a  tion..**    .**.
20a0: 2a 2a 20 20 20 20 20 20 20 20 20 61 73 79 6e 63  **         async
20b0: 4c 6f 63 6b 2c 20 61 73 79 6e 63 55 6e 6c 6f 63  Lock, asyncUnloc
20c0: 6b 2c 20 61 73 79 6e 63 43 68 65 63 6b 52 65 73  k, asyncCheckRes
20d0: 65 72 76 65 64 4c 6f 63 6b 0a 2a 2a 20 20 20 20  ervedLock.**    
20e0: 0a 2a 2a 20 20 20 20 20 54 68 65 73 65 20 70 72  .**     These pr
20f0: 69 6d 69 74 69 76 65 73 20 69 6d 70 6c 65 6d 65  imitives impleme
2100: 6e 74 20 69 6e 2d 70 72 6f 63 65 73 73 20 6c 6f  nt in-process lo
2110: 63 6b 69 6e 67 20 75 73 69 6e 67 20 61 20 68 61  cking using a ha
2120: 73 68 20 74 61 62 6c 65 0a 2a 2a 20 20 20 20 20  sh table.**     
2130: 6f 6e 20 74 68 65 20 66 69 6c 65 20 6e 61 6d 65  on the file name
2140: 2e 20 20 46 69 6c 65 73 20 61 72 65 20 6c 6f 63  .  Files are loc
2150: 6b 65 64 20 63 6f 72 72 65 63 74 6c 79 20 66 6f  ked correctly fo
2160: 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 63 6f  r connections co
2170: 6d 69 6e 67 0a 2a 2a 20 20 20 20 20 66 72 6f 6d  ming.**     from
2180: 20 74 68 65 20 73 61 6d 65 20 70 72 6f 63 65 73   the same proces
2190: 73 2e 20 20 42 75 74 20 6f 74 68 65 72 20 70 72  s.  But other pr
21a0: 6f 63 65 73 73 65 73 20 63 61 6e 6e 6f 74 20 73  ocesses cannot s
21b0: 65 65 20 74 68 65 73 65 20 6c 6f 63 6b 73 0a 2a  ee these locks.*
21c0: 2a 20 20 20 20 20 61 6e 64 20 77 69 6c 6c 20 74  *     and will t
21d0: 68 65 72 65 66 6f 72 65 20 6e 6f 74 20 68 6f 6e  herefore not hon
21e0: 6f 72 20 74 68 65 6d 2e 0a 2a 2a 0a 2a 2a 0a 2a  or them..**.**.*
21f0: 2a 20 54 68 65 20 77 72 69 74 65 72 20 74 68 72  * The writer thr
2200: 65 61 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 54  ead:.**.**     T
2210: 68 65 20 61 73 79 6e 63 2e 77 72 69 74 65 72 4d  he async.writerM
2220: 75 74 65 78 20 69 73 20 75 73 65 64 20 74 6f 20  utex is used to 
2230: 6d 61 6b 65 20 73 75 72 65 20 6f 6e 6c 79 20 74  make sure only t
2240: 68 65 72 65 20 69 73 20 6f 6e 6c 79 0a 2a 2a 20  here is only.** 
2250: 20 20 20 20 61 20 73 69 6e 67 6c 65 20 77 72 69      a single wri
2260: 74 65 72 20 74 68 72 65 61 64 20 72 75 6e 6e 69  ter thread runni
2270: 6e 67 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2a  ng at a time..**
2280: 0a 2a 2a 20 20 20 20 20 49 6e 73 69 64 65 20 74  .**     Inside t
2290: 68 65 20 77 72 69 74 65 72 20 74 68 72 65 61 64  he writer thread
22a0: 20 69 73 20 61 20 6c 6f 6f 70 20 74 68 61 74 20   is a loop that 
22b0: 77 6f 72 6b 73 20 6c 69 6b 65 20 74 68 69 73 3a  works like this:
22c0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 20 57  .**.**         W
22d0: 48 49 4c 45 20 28 77 72 69 74 65 2d 6f 70 20 6c  HILE (write-op l
22e0: 69 73 74 20 69 73 20 6e 6f 74 20 65 6d 70 74 79  ist is not empty
22f0: 29 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  ).**            
2300: 20 44 6f 20 49 4f 20 6f 70 65 72 61 74 69 6f 6e   Do IO operation
2310: 20 61 74 20 68 65 61 64 20 6f 66 20 77 72 69 74   at head of writ
2320: 65 2d 6f 70 20 6c 69 73 74 0a 2a 2a 20 20 20 20  e-op list.**    
2330: 20 20 20 20 20 20 20 20 20 52 65 6d 6f 76 65 20           Remove 
2340: 65 6e 74 72 79 20 66 72 6f 6d 20 68 65 61 64 20  entry from head 
2350: 6f 66 20 77 72 69 74 65 2d 6f 70 20 6c 69 73 74  of write-op list
2360: 0a 2a 2a 20 20 20 20 20 20 20 20 20 45 4e 44 20  .**         END 
2370: 57 48 49 4c 45 0a 2a 2a 0a 2a 2a 20 20 20 20 20  WHILE.**.**     
2380: 54 68 65 20 61 73 79 6e 63 2e 71 75 65 75 65 4d  The async.queueM
2390: 75 74 65 78 20 69 73 20 61 6c 77 61 79 73 20 68  utex is always h
23a0: 65 6c 64 20 64 75 72 69 6e 67 20 74 68 65 20 3c  eld during the <
23b0: 77 72 69 74 65 2d 6f 70 20 6c 69 73 74 20 69 73  write-op list is
23c0: 20 0a 2a 2a 20 20 20 20 20 6e 6f 74 20 65 6d 70   .**     not emp
23d0: 74 79 3e 20 74 65 73 74 2c 20 61 6e 64 20 77 68  ty> test, and wh
23e0: 65 6e 20 74 68 65 20 65 6e 74 72 79 20 69 73 20  en the entry is 
23f0: 72 65 6d 6f 76 65 64 20 66 72 6f 6d 20 74 68 65  removed from the
2400: 20 68 65 61 64 0a 2a 2a 20 20 20 20 20 6f 66 20   head.**     of 
2410: 74 68 65 20 77 72 69 74 65 2d 6f 70 20 6c 69 73  the write-op lis
2420: 74 2e 20 53 6f 6d 65 74 69 6d 65 73 20 69 74 20  t. Sometimes it 
2430: 69 73 20 68 65 6c 64 20 66 6f 72 20 74 68 65 20  is held for the 
2440: 69 6e 74 65 72 69 6d 0a 2a 2a 20 20 20 20 20 70  interim.**     p
2450: 65 72 69 6f 64 20 28 77 68 69 6c 65 20 74 68 65  eriod (while the
2460: 20 49 4f 20 69 73 20 70 65 72 66 6f 72 6d 65 64   IO is performed
2470: 29 2c 20 61 6e 64 20 73 6f 6d 65 74 69 6d 65 73  ), and sometimes
2480: 20 69 74 20 69 73 0a 2a 2a 20 20 20 20 20 72 65   it is.**     re
2490: 6c 69 6e 71 75 69 73 68 65 64 2e 20 49 74 20 69  linquished. It i
24a0: 73 20 72 65 6c 69 6e 71 75 69 73 68 65 64 20 69  s relinquished i
24b0: 66 20 28 61 29 20 74 68 65 20 49 4f 20 6f 70 20  f (a) the IO op 
24c0: 69 73 20 61 6e 0a 2a 2a 20 20 20 20 20 41 53 59  is an.**     ASY
24d0: 4e 43 5f 43 4c 4f 53 45 20 6f 72 20 28 62 29 20  NC_CLOSE or (b) 
24e0: 77 68 65 6e 20 74 68 65 20 66 69 6c 65 20 68 61  when the file ha
24f0: 6e 64 6c 65 20 77 61 73 20 6f 70 65 6e 65 64 2c  ndle was opened,
2500: 20 74 77 6f 20 6f 66 0a 2a 2a 20 20 20 20 20 74   two of.**     t
2510: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 73 79  he underlying sy
2520: 73 74 65 6d 73 20 68 61 6e 64 6c 65 73 20 77 65  stems handles we
2530: 72 65 20 6f 70 65 6e 65 64 20 6f 6e 20 74 68 65  re opened on the
2540: 20 73 61 6d 65 0a 2a 2a 20 20 20 20 20 66 69 6c   same.**     fil
2550: 65 2d 73 79 73 74 65 6d 20 65 6e 74 72 79 2e 0a  e-system entry..
2560: 2a 2a 0a 2a 2a 20 20 20 20 20 49 66 20 63 6f 6e  **.**     If con
2570: 64 69 74 69 6f 6e 20 28 62 29 20 61 62 6f 76 65  dition (b) above
2580: 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20 6f   is true, then o
2590: 6e 65 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 0a  ne file-handle .
25a0: 2a 2a 20 20 20 20 20 28 41 73 79 6e 63 46 69 6c  **     (AsyncFil
25b0: 65 2e 70 42 61 73 65 52 65 61 64 29 20 69 73 20  e.pBaseRead) is 
25c0: 75 73 65 64 20 65 78 63 6c 75 73 69 76 65 6c 79  used exclusively
25d0: 20 62 79 20 73 71 6c 69 74 65 20 74 68 72 65 61   by sqlite threa
25e0: 64 73 20 74 6f 20 72 65 61 64 20 74 68 65 0a 2a  ds to read the.*
25f0: 2a 20 20 20 20 20 66 69 6c 65 2c 20 74 68 65 20  *     file, the 
2600: 6f 74 68 65 72 20 28 41 73 79 6e 63 46 69 6c 65  other (AsyncFile
2610: 2e 70 42 61 73 65 57 72 69 74 65 29 20 62 79 20  .pBaseWrite) by 
2620: 73 71 6c 69 74 65 33 5f 61 73 79 6e 63 5f 66 6c  sqlite3_async_fl
2630: 75 73 68 28 29 20 0a 2a 2a 20 20 20 20 20 74 68  ush() .**     th
2640: 72 65 61 64 73 20 74 6f 20 70 65 72 66 6f 72 6d  reads to perform
2650: 20 77 72 69 74 65 28 29 20 6f 70 65 72 61 74 69   write() operati
2660: 6f 6e 73 2e 20 54 68 69 73 20 6d 65 61 6e 73 20  ons. This means 
2670: 74 68 61 74 20 72 65 61 64 20 0a 2a 2a 20 20 20  that read .**   
2680: 20 20 6f 70 65 72 61 74 69 6f 6e 73 20 61 72 65    operations are
2690: 20 6e 6f 74 20 62 6c 6f 63 6b 65 64 20 62 79 20   not blocked by 
26a0: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 77 72 69  asynchronous wri
26b0: 74 65 73 20 28 61 6c 74 68 6f 75 67 68 20 0a 2a  tes (although .*
26c0: 2a 20 20 20 20 20 61 73 79 6e 63 68 72 6f 6e 6f  *     asynchrono
26d0: 75 73 20 77 72 69 74 65 73 20 6d 61 79 20 73 74  us writes may st
26e0: 69 6c 6c 20 62 65 20 62 6c 6f 63 6b 65 64 20 62  ill be blocked b
26f0: 79 20 72 65 61 64 73 29 2e 0a 2a 2a 0a 2a 2a 20  y reads)..**.** 
2700: 20 20 20 20 54 68 69 73 20 61 73 73 75 6d 65 73      This assumes
2710: 20 74 68 61 74 20 74 68 65 20 4f 53 20 6b 65 65   that the OS kee
2720: 70 73 20 74 77 6f 20 68 61 6e 64 6c 65 73 20 6f  ps two handles o
2730: 70 65 6e 20 6f 6e 20 74 68 65 20 73 61 6d 65 20  pen on the same 
2740: 66 69 6c 65 0a 2a 2a 20 20 20 20 20 70 72 6f 70  file.**     prop
2750: 65 72 6c 79 20 69 6e 20 73 79 6e 63 2e 20 54 68  erly in sync. Th
2760: 61 74 20 69 73 2c 20 61 6e 79 20 72 65 61 64 20  at is, any read 
2770: 6f 70 65 72 61 74 69 6f 6e 20 74 68 61 74 20 73  operation that s
2780: 74 61 72 74 73 20 61 66 74 65 72 20 61 0a 2a 2a  tarts after a.**
2790: 20 20 20 20 20 77 72 69 74 65 20 6f 70 65 72 61       write opera
27a0: 74 69 6f 6e 20 6f 6e 20 74 68 65 20 73 61 6d 65  tion on the same
27b0: 20 66 69 6c 65 20 73 79 73 74 65 6d 20 65 6e 74   file system ent
27c0: 72 79 20 68 61 73 20 63 6f 6d 70 6c 65 74 65 64  ry has completed
27d0: 20 72 65 74 75 72 6e 73 0a 2a 2a 20 20 20 20 20   returns.**     
27e0: 64 61 74 61 20 63 6f 6e 73 69 73 74 65 6e 74 20  data consistent 
27f0: 77 69 74 68 20 74 68 65 20 77 72 69 74 65 2e 20  with the write. 
2800: 57 65 20 61 6c 73 6f 20 61 73 73 75 6d 65 20 74  We also assume t
2810: 68 61 74 20 69 66 20 6f 6e 65 20 74 68 72 65 61  hat if one threa
2820: 64 20 0a 2a 2a 20 20 20 20 20 72 65 61 64 73 20  d .**     reads 
2830: 61 20 66 69 6c 65 20 77 68 69 6c 65 20 61 6e 6f  a file while ano
2840: 74 68 65 72 20 69 73 20 77 72 69 74 69 6e 67 20  ther is writing 
2850: 69 74 20 61 6c 6c 20 62 79 74 65 73 20 6f 74 68  it all bytes oth
2860: 65 72 20 74 68 61 6e 20 74 68 65 0a 2a 2a 20 20  er than the.**  
2870: 20 20 20 6f 6e 65 73 20 61 63 74 75 61 6c 6c 79     ones actually
2880: 20 62 65 69 6e 67 20 77 72 69 74 74 65 6e 20 63   being written c
2890: 6f 6e 74 61 69 6e 20 76 61 6c 69 64 20 64 61 74  ontain valid dat
28a0: 61 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 49 66 20  a..**.**     If 
28b0: 74 68 65 20 61 62 6f 76 65 20 61 73 73 75 6d 70  the above assump
28c0: 74 69 6f 6e 73 20 61 72 65 20 6e 6f 74 20 74 72  tions are not tr
28d0: 75 65 2c 20 73 65 74 20 74 68 65 20 70 72 65 70  ue, set the prep
28e0: 72 6f 63 65 73 73 6f 72 20 73 79 6d 62 6f 6c 0a  rocessor symbol.
28f0: 2a 2a 20 20 20 20 20 53 51 4c 49 54 45 5f 41 53  **     SQLITE_AS
2900: 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e 44  YNC_TWO_FILEHAND
2910: 4c 45 53 20 74 6f 20 30 2e 0a 2a 2f 0a 0a 23 69  LES to 0..*/..#i
2920: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 41 53 59  fndef SQLITE_ASY
2930: 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e 44 4c  NC_TWO_FILEHANDL
2940: 45 53 0a 2f 2a 20 23 64 65 66 69 6e 65 20 53 51  ES./* #define SQ
2950: 4c 49 54 45 5f 41 53 59 4e 43 5f 54 57 4f 5f 46  LITE_ASYNC_TWO_F
2960: 49 4c 45 48 41 4e 44 4c 45 53 20 30 20 2a 2f 0a  ILEHANDLES 0 */.
2970: 23 64 65 66 69 6e 65 20 53 51 4c 49 54 45 5f 41  #define SQLITE_A
2980: 53 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e  SYNC_TWO_FILEHAN
2990: 44 4c 45 53 20 31 0a 23 65 6e 64 69 66 0a 0a 2f  DLES 1.#endif../
29a0: 2a 0a 2a 2a 20 53 74 61 74 65 20 69 6e 66 6f 72  *.** State infor
29b0: 6d 61 74 69 6f 6e 20 69 73 20 68 65 6c 64 20 69  mation is held i
29c0: 6e 20 74 68 65 20 73 74 61 74 69 63 20 76 61 72  n the static var
29d0: 69 61 62 6c 65 20 22 61 73 79 6e 63 22 20 64 65  iable "async" de
29e0: 66 69 6e 65 64 0a 2a 2a 20 61 73 20 74 68 65 20  fined.** as the 
29f0: 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75 63 74  following struct
2a00: 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 42 6f 74 68 20  ure..**.** Both 
2a10: 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 20 61 6e  async.ioError an
2a20: 64 20 61 73 79 6e 63 2e 6e 46 69 6c 65 20 61 72  d async.nFile ar
2a30: 65 20 70 72 6f 74 65 63 74 65 64 20 62 79 20 61  e protected by a
2a40: 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 2e  sync.queueMutex.
2a50: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63  .*/.static struc
2a60: 74 20 54 65 73 74 41 73 79 6e 63 53 74 61 74 69  t TestAsyncStati
2a70: 63 44 61 74 61 20 7b 0a 20 20 70 74 68 72 65 61  cData {.  pthrea
2a80: 64 5f 6d 75 74 65 78 5f 74 20 6c 6f 63 6b 4d 75  d_mutex_t lockMu
2a90: 74 65 78 3b 20 20 20 2f 2a 20 46 6f 72 20 61 63  tex;   /* For ac
2aa0: 63 65 73 73 20 74 6f 20 61 4c 6f 63 6b 20 68 61  cess to aLock ha
2ab0: 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 70 74  sh table */.  pt
2ac0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 71 75  hread_mutex_t qu
2ad0: 65 75 65 4d 75 74 65 78 3b 20 20 2f 2a 20 4d 75  eueMutex;  /* Mu
2ae0: 74 65 78 20 66 6f 72 20 61 63 63 65 73 73 20 74  tex for access t
2af0: 6f 20 77 72 69 74 65 20 6f 70 65 72 61 74 69 6f  o write operatio
2b00: 6e 20 71 75 65 75 65 20 2a 2f 0a 20 20 70 74 68  n queue */.  pth
2b10: 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 77 72 69  read_mutex_t wri
2b20: 74 65 72 4d 75 74 65 78 3b 20 2f 2a 20 50 72 65  terMutex; /* Pre
2b30: 76 65 6e 74 73 20 6d 75 6c 74 69 70 6c 65 20 77  vents multiple w
2b40: 72 69 74 65 72 20 74 68 72 65 61 64 73 20 2a 2f  riter threads */
2b50: 0a 20 20 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f  .  pthread_cond_
2b60: 74 20 71 75 65 75 65 53 69 67 6e 61 6c 3b 20 20  t queueSignal;  
2b70: 2f 2a 20 46 6f 72 20 77 61 6b 69 6e 67 20 75 70  /* For waking up
2b80: 20 73 6c 65 65 70 69 6e 67 20 77 72 69 74 65 72   sleeping writer
2b90: 20 74 68 72 65 61 64 20 2a 2f 0a 20 20 70 74 68   thread */.  pth
2ba0: 72 65 61 64 5f 63 6f 6e 64 5f 74 20 65 6d 70 74  read_cond_t empt
2bb0: 79 53 69 67 6e 61 6c 3b 20 20 2f 2a 20 4e 6f 74  ySignal;  /* Not
2bc0: 69 66 79 20 77 68 65 6e 20 74 68 65 20 77 72 69  ify when the wri
2bd0: 74 65 20 71 75 65 75 65 20 69 73 20 65 6d 70 74  te queue is empt
2be0: 79 20 2a 2f 0a 20 20 41 73 79 6e 63 57 72 69 74  y */.  AsyncWrit
2bf0: 65 20 2a 70 51 75 65 75 65 46 69 72 73 74 3b 20  e *pQueueFirst; 
2c00: 20 20 20 20 2f 2a 20 4e 65 78 74 20 77 72 69 74      /* Next writ
2c10: 65 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f 20 62  e operation to b
2c20: 65 20 70 72 6f 63 65 73 73 65 64 20 2a 2f 0a 20  e processed */. 
2c30: 20 41 73 79 6e 63 57 72 69 74 65 20 2a 70 51 75   AsyncWrite *pQu
2c40: 65 75 65 4c 61 73 74 3b 20 20 20 20 20 20 2f 2a  eueLast;      /*
2c50: 20 4c 61 73 74 20 77 72 69 74 65 20 6f 70 65 72   Last write oper
2c60: 61 74 69 6f 6e 20 6f 6e 20 74 68 65 20 6c 69 73  ation on the lis
2c70: 74 20 2a 2f 0a 20 20 41 73 79 6e 63 4c 6f 63 6b  t */.  AsyncLock
2c80: 20 2a 70 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20   *pLock;        
2c90: 20 20 20 20 2f 2a 20 4c 69 6e 6b 65 64 20 6c 69      /* Linked li
2ca0: 73 74 20 6f 66 20 61 6c 6c 20 41 73 79 6e 63 4c  st of all AsyncL
2cb0: 6f 63 6b 20 73 74 72 75 63 74 75 72 65 73 20 2a  ock structures *
2cc0: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 69 6e 74  /.  volatile int
2cd0: 20 69 6f 44 65 6c 61 79 3b 20 20 20 20 20 20 20   ioDelay;       
2ce0: 20 20 20 20 20 20 2f 2a 20 45 78 74 72 61 20 64        /* Extra d
2cf0: 65 6c 61 79 20 62 65 74 77 65 65 6e 20 77 72 69  elay between wri
2d00: 74 65 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f  te operations */
2d10: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 69 6e 74 20  .  volatile int 
2d20: 77 72 69 74 65 72 48 61 6c 74 57 68 65 6e 49 64  writerHaltWhenId
2d30: 6c 65 3b 20 20 2f 2a 20 57 72 69 74 65 72 20 74  le;  /* Writer t
2d40: 68 72 65 61 64 20 68 61 6c 74 73 20 77 68 65 6e  hread halts when
2d50: 20 71 75 65 75 65 20 65 6d 70 74 79 20 2a 2f 0a   queue empty */.
2d60: 20 20 76 6f 6c 61 74 69 6c 65 20 69 6e 74 20 77    volatile int w
2d70: 72 69 74 65 72 48 61 6c 74 4e 6f 77 3b 20 20 20  riterHaltNow;   
2d80: 20 20 20 20 2f 2a 20 57 72 69 74 65 72 20 74 68      /* Writer th
2d90: 72 65 61 64 20 68 61 6c 74 73 20 61 66 74 65 72  read halts after
2da0: 20 6e 65 78 74 20 6f 70 20 2a 2f 0a 20 20 69 6e   next op */.  in
2db0: 74 20 69 6f 45 72 72 6f 72 3b 20 20 20 20 20 20  t ioError;      
2dc0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
2dd0: 75 65 20 69 66 20 61 6e 20 49 4f 20 65 72 72 6f  ue if an IO erro
2de0: 72 20 68 61 73 20 6f 63 63 75 72 72 65 64 20 2a  r has occurred *
2df0: 2f 0a 20 20 69 6e 74 20 6e 46 69 6c 65 3b 20 20  /.  int nFile;  
2e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e10: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6f 70   /* Number of op
2e20: 65 6e 20 66 69 6c 65 73 20 28 66 72 6f 6d 20 73  en files (from s
2e30: 71 6c 69 74 65 20 70 6f 76 29 20 2a 2f 0a 7d 20  qlite pov) */.} 
2e40: 61 73 79 6e 63 20 3d 20 7b 0a 20 20 50 54 48 52  async = {.  PTHR
2e50: 45 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41  EAD_MUTEX_INITIA
2e60: 4c 49 5a 45 52 2c 0a 20 20 50 54 48 52 45 41 44  LIZER,.  PTHREAD
2e70: 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c 49 5a  _MUTEX_INITIALIZ
2e80: 45 52 2c 0a 20 20 50 54 48 52 45 41 44 5f 4d 55  ER,.  PTHREAD_MU
2e90: 54 45 58 5f 49 4e 49 54 49 41 4c 49 5a 45 52 2c  TEX_INITIALIZER,
2ea0: 0a 20 20 50 54 48 52 45 41 44 5f 43 4f 4e 44 5f  .  PTHREAD_COND_
2eb0: 49 4e 49 54 49 41 4c 49 5a 45 52 2c 0a 20 20 50  INITIALIZER,.  P
2ec0: 54 48 52 45 41 44 5f 43 4f 4e 44 5f 49 4e 49 54  THREAD_COND_INIT
2ed0: 49 41 4c 49 5a 45 52 2c 0a 7d 3b 0a 0a 2f 2a 20  IALIZER,.};../* 
2ee0: 50 6f 73 73 69 62 6c 65 20 76 61 6c 75 65 73 20  Possible values 
2ef0: 6f 66 20 41 73 79 6e 63 57 72 69 74 65 2e 6f 70  of AsyncWrite.op
2f00: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 41 53 59 4e   */.#define ASYN
2f10: 43 5f 4e 4f 4f 50 20 20 20 20 20 20 20 20 20 20  C_NOOP          
2f20: 30 0a 23 64 65 66 69 6e 65 20 41 53 59 4e 43 5f  0.#define ASYNC_
2f30: 57 52 49 54 45 20 20 20 20 20 20 20 20 20 31 0a  WRITE         1.
2f40: 23 64 65 66 69 6e 65 20 41 53 59 4e 43 5f 53 59  #define ASYNC_SY
2f50: 4e 43 20 20 20 20 20 20 20 20 20 20 32 0a 23 64  NC          2.#d
2f60: 65 66 69 6e 65 20 41 53 59 4e 43 5f 54 52 55 4e  efine ASYNC_TRUN
2f70: 43 41 54 45 20 20 20 20 20 20 33 0a 23 64 65 66  CATE      3.#def
2f80: 69 6e 65 20 41 53 59 4e 43 5f 43 4c 4f 53 45 20  ine ASYNC_CLOSE 
2f90: 20 20 20 20 20 20 20 20 34 0a 23 64 65 66 69 6e          4.#defin
2fa0: 65 20 41 53 59 4e 43 5f 44 45 4c 45 54 45 20 20  e ASYNC_DELETE  
2fb0: 20 20 20 20 20 20 35 0a 23 64 65 66 69 6e 65 20        5.#define 
2fc0: 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53  ASYNC_OPENEXCLUS
2fd0: 49 56 45 20 36 0a 23 64 65 66 69 6e 65 20 41 53  IVE 6.#define AS
2fe0: 59 4e 43 5f 55 4e 4c 4f 43 4b 20 20 20 20 20 20  YNC_UNLOCK      
2ff0: 20 20 37 0a 0a 2f 2a 20 4e 61 6d 65 73 20 6f 66    7../* Names of
3000: 20 6f 70 63 6f 64 65 73 2e 20 20 55 73 65 64 20   opcodes.  Used 
3010: 66 6f 72 20 64 65 62 75 67 67 69 6e 67 20 6f 6e  for debugging on
3020: 6c 79 2e 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65  ly..** Make sure
3030: 20 74 68 65 73 65 20 73 74 61 79 20 69 6e 20 73   these stay in s
3040: 79 6e 63 20 77 69 74 68 20 74 68 65 20 6d 61 63  ync with the mac
3050: 72 6f 73 20 61 62 6f 76 65 21 0a 2a 2f 0a 73 74  ros above!.*/.st
3060: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
3070: 2a 61 7a 4f 70 63 6f 64 65 4e 61 6d 65 5b 5d 20  *azOpcodeName[] 
3080: 3d 20 7b 0a 20 20 22 4e 4f 4f 50 22 2c 20 22 57  = {.  "NOOP", "W
3090: 52 49 54 45 22 2c 20 22 53 59 4e 43 22 2c 20 22  RITE", "SYNC", "
30a0: 54 52 55 4e 43 41 54 45 22 2c 20 22 43 4c 4f 53  TRUNCATE", "CLOS
30b0: 45 22 2c 20 22 44 45 4c 45 54 45 22 2c 20 22 4f  E", "DELETE", "O
30c0: 50 45 4e 45 58 22 2c 20 22 55 4e 4c 4f 43 4b 22  PENEX", "UNLOCK"
30d0: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45 6e 74 72 69  .};../*.** Entri
30e0: 65 73 20 6f 6e 20 74 68 65 20 77 72 69 74 65 2d  es on the write-
30f0: 6f 70 20 71 75 65 75 65 20 61 72 65 20 69 6e 73  op queue are ins
3100: 74 61 6e 63 65 73 20 6f 66 20 74 68 65 20 41 73  tances of the As
3110: 79 6e 63 57 72 69 74 65 0a 2a 2a 20 73 74 72 75  yncWrite.** stru
3120: 63 74 75 72 65 2c 20 64 65 66 69 6e 65 64 20 68  cture, defined h
3130: 65 72 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69  ere..**.** The i
3140: 6e 74 65 72 70 72 65 74 61 74 69 6f 6e 20 6f 66  nterpretation of
3150: 20 74 68 65 20 69 4f 66 66 73 65 74 20 61 6e 64   the iOffset and
3160: 20 6e 42 79 74 65 20 76 61 72 69 61 62 6c 65 73   nByte variables
3170: 20 76 61 72 69 65 73 20 64 65 70 65 6e 64 69 6e   varies dependin
3180: 67 20 0a 2a 2a 20 6f 6e 20 74 68 65 20 76 61 6c  g .** on the val
3190: 75 65 20 6f 66 20 41 73 79 6e 63 57 72 69 74 65  ue of AsyncWrite
31a0: 2e 6f 70 3a 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43  .op:.**.** ASYNC
31b0: 5f 4e 4f 4f 50 3a 0a 2a 2a 20 20 20 20 20 4e 6f  _NOOP:.**     No
31c0: 20 76 61 6c 75 65 73 20 75 73 65 64 2e 0a 2a 2a   values used..**
31d0: 0a 2a 2a 20 41 53 59 4e 43 5f 57 52 49 54 45 3a  .** ASYNC_WRITE:
31e0: 0a 2a 2a 20 20 20 20 20 69 4f 66 66 73 65 74 20  .**     iOffset 
31f0: 2d 3e 20 4f 66 66 73 65 74 20 69 6e 20 66 69 6c  -> Offset in fil
3200: 65 20 74 6f 20 77 72 69 74 65 20 74 6f 2e 0a 2a  e to write to..*
3210: 2a 20 20 20 20 20 6e 42 79 74 65 20 20 20 2d 3e  *     nByte   ->
3220: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
3230: 20 6f 66 20 64 61 74 61 20 74 6f 20 77 72 69 74   of data to writ
3240: 65 20 28 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  e (pointed to by
3250: 20 7a 42 75 66 29 2e 0a 2a 2a 0a 2a 2a 20 41 53   zBuf)..**.** AS
3260: 59 4e 43 5f 53 59 4e 43 3a 0a 2a 2a 20 20 20 20  YNC_SYNC:.**    
3270: 20 6e 42 79 74 65 20 20 20 2d 3e 20 66 6c 61 67   nByte   -> flag
3280: 73 20 74 6f 20 70 61 73 73 20 74 6f 20 73 71 6c  s to pass to sql
3290: 69 74 65 33 4f 73 53 79 6e 63 28 29 2e 0a 2a 2a  ite3OsSync()..**
32a0: 0a 2a 2a 20 41 53 59 4e 43 5f 54 52 55 4e 43 41  .** ASYNC_TRUNCA
32b0: 54 45 3a 0a 2a 2a 20 20 20 20 20 69 4f 66 66 73  TE:.**     iOffs
32c0: 65 74 20 2d 3e 20 53 69 7a 65 20 74 6f 20 74 72  et -> Size to tr
32d0: 75 6e 63 61 74 65 20 66 69 6c 65 20 74 6f 2e 0a  uncate file to..
32e0: 2a 2a 20 20 20 20 20 6e 42 79 74 65 20 20 20 2d  **     nByte   -
32f0: 3e 20 55 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20  > Unused..**.** 
3300: 41 53 59 4e 43 5f 43 4c 4f 53 45 3a 0a 2a 2a 20  ASYNC_CLOSE:.** 
3310: 20 20 20 20 69 4f 66 66 73 65 74 20 2d 3e 20 55      iOffset -> U
3320: 6e 75 73 65 64 2e 0a 2a 2a 20 20 20 20 20 6e 42  nused..**     nB
3330: 79 74 65 20 20 20 2d 3e 20 55 6e 75 73 65 64 2e  yte   -> Unused.
3340: 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43 5f 44 45 4c  .**.** ASYNC_DEL
3350: 45 54 45 3a 0a 2a 2a 20 20 20 20 20 69 4f 66 66  ETE:.**     iOff
3360: 73 65 74 20 2d 3e 20 43 6f 6e 74 61 69 6e 73 20  set -> Contains 
3370: 74 68 65 20 22 73 79 6e 63 44 69 72 22 20 66 6c  the "syncDir" fl
3380: 61 67 2e 0a 2a 2a 20 20 20 20 20 6e 42 79 74 65  ag..**     nByte
3390: 20 20 20 2d 3e 20 4e 75 6d 62 65 72 20 6f 66 20     -> Number of 
33a0: 62 79 74 65 73 20 6f 66 20 7a 42 75 66 20 70 6f  bytes of zBuf po
33b0: 69 6e 74 73 20 74 6f 20 28 66 69 6c 65 20 6e 61  ints to (file na
33c0: 6d 65 29 2e 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43  me)..**.** ASYNC
33d0: 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56 45 3a 0a  _OPENEXCLUSIVE:.
33e0: 2a 2a 20 20 20 20 20 69 4f 66 66 73 65 74 20 2d  **     iOffset -
33f0: 3e 20 56 61 6c 75 65 20 6f 66 20 22 64 65 6c 66  > Value of "delf
3400: 6c 61 67 22 2e 0a 2a 2a 20 20 20 20 20 6e 42 79  lag"..**     nBy
3410: 74 65 20 20 20 2d 3e 20 4e 75 6d 62 65 72 20 6f  te   -> Number o
3420: 66 20 62 79 74 65 73 20 6f 66 20 7a 42 75 66 20  f bytes of zBuf 
3430: 70 6f 69 6e 74 73 20 74 6f 20 28 66 69 6c 65 20  points to (file 
3440: 6e 61 6d 65 29 2e 0a 2a 2a 0a 2a 2a 20 41 53 59  name)..**.** ASY
3450: 4e 43 5f 55 4e 4c 4f 43 4b 3a 0a 2a 2a 20 20 20  NC_UNLOCK:.**   
3460: 20 20 6e 42 79 74 65 20 20 20 2d 3e 20 41 72 67    nByte   -> Arg
3470: 75 6d 65 6e 74 20 74 6f 20 73 71 6c 69 74 65 33  ument to sqlite3
3480: 4f 73 55 6e 6c 6f 63 6b 28 29 2e 0a 2a 2a 0a 2a  OsUnlock()..**.*
3490: 2a 0a 2a 2a 20 46 6f 72 20 61 6e 20 41 53 59 4e  *.** For an ASYN
34a0: 43 5f 57 52 49 54 45 20 6f 70 65 72 61 74 69 6f  C_WRITE operatio
34b0: 6e 2c 20 7a 42 75 66 20 70 6f 69 6e 74 73 20 74  n, zBuf points t
34c0: 6f 20 74 68 65 20 64 61 74 61 20 74 6f 20 77 72  o the data to wr
34d0: 69 74 65 20 74 6f 20 74 68 65 20 66 69 6c 65 2e  ite to the file.
34e0: 20 0a 2a 2a 20 54 68 69 73 20 73 70 61 63 65 20   .** This space 
34f0: 69 73 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  is sqlite3_mallo
3500: 63 28 29 64 20 61 6c 6f 6e 67 20 77 69 74 68 20  c()d along with 
3510: 74 68 65 20 41 73 79 6e 63 57 72 69 74 65 20 73  the AsyncWrite s
3520: 74 72 75 63 74 75 72 65 20 69 6e 20 61 0a 2a 2a  tructure in a.**
3530: 20 73 69 6e 67 6c 65 20 62 6c 6f 62 2c 20 73 6f   single blob, so
3540: 20 69 73 20 64 65 6c 65 74 65 64 20 77 68 65 6e   is deleted when
3550: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20   sqlite3_free() 
3560: 69 73 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65  is called on the
3570: 20 70 61 72 65 6e 74 20 0a 2a 2a 20 73 74 72 75   parent .** stru
3580: 63 74 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74  cture..*/.struct
3590: 20 41 73 79 6e 63 57 72 69 74 65 20 7b 0a 20 20   AsyncWrite {.  
35a0: 41 73 79 6e 63 46 69 6c 65 44 61 74 61 20 2a 70  AsyncFileData *p
35b0: 46 69 6c 65 44 61 74 61 3b 20 20 20 20 2f 2a 20  FileData;    /* 
35c0: 46 69 6c 65 20 74 6f 20 77 72 69 74 65 20 64 61  File to write da
35d0: 74 61 20 74 6f 20 6f 72 20 73 79 6e 63 20 2a 2f  ta to or sync */
35e0: 0a 20 20 69 6e 74 20 6f 70 3b 20 20 20 20 20 20  .  int op;      
35f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3600: 2f 2a 20 4f 6e 65 20 6f 66 20 41 53 59 4e 43 5f  /* One of ASYNC_
3610: 78 78 78 20 65 74 63 2e 20 2a 2f 0a 20 20 73 71  xxx etc. */.  sq
3620: 6c 69 74 65 5f 69 6e 74 36 34 20 69 4f 66 66 73  lite_int64 iOffs
3630: 65 74 3b 20 20 20 20 20 20 20 20 2f 2a 20 53 65  et;        /* Se
3640: 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20 69 6e 74  e above */.  int
3650: 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20   nByte;         
3660: 20 2f 2a 20 53 65 65 20 61 62 6f 76 65 20 2a 2f   /* See above */
3670: 0a 20 20 63 68 61 72 20 2a 7a 42 75 66 3b 20 20  .  char *zBuf;  
3680: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 20 74         /* Data t
3690: 6f 20 77 72 69 74 65 20 74 6f 20 66 69 6c 65 20  o write to file 
36a0: 28 6f 72 20 4e 55 4c 4c 20 69 66 20 6f 70 21 3d  (or NULL if op!=
36b0: 41 53 59 4e 43 5f 57 52 49 54 45 29 20 2a 2f 0a  ASYNC_WRITE) */.
36c0: 20 20 41 73 79 6e 63 57 72 69 74 65 20 2a 70 4e    AsyncWrite *pN
36d0: 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 77 72  ext;  /* Next wr
36e0: 69 74 65 20 6f 70 65 72 61 74 69 6f 6e 20 28 74  ite operation (t
36f0: 6f 20 61 6e 79 20 66 69 6c 65 29 20 2a 2f 0a 7d  o any file) */.}
3700: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74  ;../*.** An inst
3710: 61 6e 63 65 20 6f 66 20 74 68 69 73 20 73 74 72  ance of this str
3720: 75 63 74 75 72 65 20 69 73 20 63 72 65 61 74 65  ucture is create
3730: 64 20 66 6f 72 20 65 61 63 68 20 64 69 73 74 69  d for each disti
3740: 6e 63 74 20 6f 70 65 6e 20 66 69 6c 65 20 0a 2a  nct open file .*
3750: 2a 20 28 69 2e 65 2e 20 69 66 20 74 77 6f 20 68  * (i.e. if two h
3760: 61 6e 64 6c 65 73 20 61 72 65 20 6f 70 65 6e 65  andles are opene
3770: 64 20 6f 6e 20 74 68 65 20 6f 6e 65 20 66 69 6c  d on the one fil
3780: 65 2c 20 6f 6e 6c 79 20 6f 6e 65 20 6f 66 20 74  e, only one of t
3790: 68 65 73 65 0a 2a 2a 20 73 74 72 75 63 74 75 72  hese.** structur
37a0: 65 73 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 29  es is allocated)
37b0: 20 61 6e 64 20 73 74 6f 72 65 64 20 69 6e 20 74   and stored in t
37c0: 68 65 20 61 73 79 6e 63 2e 61 4c 6f 63 6b 20 68  he async.aLock h
37d0: 61 73 68 20 74 61 62 6c 65 2e 20 54 68 65 0a 2a  ash table. The.*
37e0: 2a 20 6b 65 79 73 20 66 6f 72 20 61 73 79 6e 63  * keys for async
37f0: 2e 61 4c 6f 63 6b 20 61 72 65 20 74 68 65 20 66  .aLock are the f
3800: 75 6c 6c 20 70 61 74 68 6e 61 6d 65 73 20 6f 66  ull pathnames of
3810: 20 74 68 65 20 6f 70 65 6e 65 64 20 66 69 6c 65   the opened file
3820: 73 2e 0a 2a 2a 0a 2a 2a 20 41 73 79 6e 63 4c 6f  s..**.** AsyncLo
3830: 63 6b 2e 70 4c 69 73 74 20 70 6f 69 6e 74 73 20  ck.pList points 
3840: 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66 20 61  to the head of a
3850: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20   linked list of 
3860: 41 73 79 6e 63 46 69 6c 65 4c 6f 63 6b 0a 2a 2a  AsyncFileLock.**
3870: 20 73 74 72 75 63 74 75 72 65 73 2c 20 6f 6e 65   structures, one
3880: 20 66 6f 72 20 65 61 63 68 20 68 61 6e 64 6c 65   for each handle
3890: 20 63 75 72 72 65 6e 74 6c 79 20 6f 70 65 6e 20   currently open 
38a0: 6f 6e 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2a 0a  on the file..**.
38b0: 2a 2a 20 49 66 20 74 68 65 20 6f 70 65 6e 65 64  ** If the opened
38c0: 20 66 69 6c 65 20 69 73 20 6e 6f 74 20 61 20 6d   file is not a m
38d0: 61 69 6e 2d 64 61 74 61 62 61 73 65 20 28 74 68  ain-database (th
38e0: 65 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41  e SQLITE_OPEN_MA
38f0: 49 4e 5f 44 42 20 69 73 0a 2a 2a 20 6e 6f 74 20  IN_DB is.** not 
3900: 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 73 71  passed to the sq
3910: 6c 69 74 65 33 4f 73 4f 70 65 6e 28 29 20 63 61  lite3OsOpen() ca
3920: 6c 6c 29 2c 20 6f 72 20 69 66 20 45 4e 41 42 4c  ll), or if ENABL
3930: 45 5f 46 49 4c 45 5f 4c 4f 43 4b 49 4e 47 20 69  E_FILE_LOCKING i
3940: 73 20 0a 2a 2a 20 6e 6f 74 20 64 65 66 69 6e 65  s .** not define
3950: 64 20 61 74 20 63 6f 6d 70 69 6c 65 20 74 69 6d  d at compile tim
3960: 65 2c 20 76 61 72 69 61 62 6c 65 73 20 41 73 79  e, variables Asy
3970: 6e 63 4c 6f 63 6b 2e 70 46 69 6c 65 20 61 6e 64  ncLock.pFile and
3980: 20 0a 2a 2a 20 41 73 79 6e 63 4c 6f 63 6b 2e 65   .** AsyncLock.e
3990: 4c 6f 63 6b 20 61 72 65 20 6e 65 76 65 72 20 75  Lock are never u
39a0: 73 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  sed. Otherwise, 
39b0: 70 46 69 6c 65 20 69 73 20 61 20 66 69 6c 65 20  pFile is a file 
39c0: 68 61 6e 64 6c 65 0a 2a 2a 20 6f 70 65 6e 65 64  handle.** opened
39d0: 20 6f 6e 20 74 68 65 20 66 69 6c 65 20 69 6e 20   on the file in 
39e0: 71 75 65 73 74 69 6f 6e 20 61 6e 64 20 75 73 65  question and use
39f0: 64 20 74 6f 20 6f 62 74 61 69 6e 20 74 68 65 20  d to obtain the 
3a00: 66 69 6c 65 2d 73 79 73 74 65 6d 20 0a 2a 2a 20  file-system .** 
3a10: 6c 6f 63 6b 73 20 72 65 71 75 69 72 65 64 20 62  locks required b
3a20: 79 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65  y database conne
3a30: 63 74 69 6f 6e 73 20 77 69 74 68 69 6e 20 74 68  ctions within th
3a40: 69 73 20 70 72 6f 63 65 73 73 2e 0a 2a 2a 0a 2a  is process..**.*
3a50: 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61  * See comments a
3a60: 62 6f 76 65 20 74 68 65 20 61 73 79 6e 63 4c 6f  bove the asyncLo
3a70: 63 6b 28 29 20 66 75 6e 63 74 69 6f 6e 20 66 6f  ck() function fo
3a80: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 20 6f  r more details o
3a90: 6e 20 0a 2a 2a 20 74 68 65 20 69 6d 70 6c 65 6d  n .** the implem
3aa0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 64 61 74 61  entation of data
3ab0: 62 61 73 65 20 6c 6f 63 6b 69 6e 67 20 75 73 65  base locking use
3ac0: 64 20 62 79 20 74 68 69 73 20 62 61 63 6b 65 6e  d by this backen
3ad0: 64 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 41 73 79  d..*/.struct Asy
3ae0: 6e 63 4c 6f 63 6b 20 7b 0a 20 20 63 68 61 72 20  ncLock {.  char 
3af0: 2a 7a 46 69 6c 65 3b 0a 20 20 69 6e 74 20 6e 46  *zFile;.  int nF
3b00: 69 6c 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ile;.  sqlite3_f
3b10: 69 6c 65 20 2a 70 46 69 6c 65 3b 0a 20 20 69 6e  ile *pFile;.  in
3b20: 74 20 65 4c 6f 63 6b 3b 0a 20 20 41 73 79 6e 63  t eLock;.  Async
3b30: 46 69 6c 65 4c 6f 63 6b 20 2a 70 4c 69 73 74 3b  FileLock *pList;
3b40: 0a 20 20 41 73 79 6e 63 4c 6f 63 6b 20 2a 70 4e  .  AsyncLock *pN
3b50: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f  ext;           /
3b60: 2a 20 4e 65 78 74 20 69 6e 20 6c 69 6e 6b 65 64  * Next in linked
3b70: 20 6c 69 73 74 20 68 65 61 64 65 64 20 62 79 20   list headed by 
3b80: 61 73 79 6e 63 2e 70 4c 6f 63 6b 20 2a 2f 0a 7d  async.pLock */.}
3b90: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74  ;../*.** An inst
3ba0: 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ance of the foll
3bb0: 6f 77 69 6e 67 20 73 74 72 75 63 74 75 72 65 20  owing structure 
3bc0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 61 6c 6f  is allocated alo
3bd0: 6e 67 20 77 69 74 68 20 65 61 63 68 0a 2a 2a 20  ng with each.** 
3be0: 41 73 79 6e 63 46 69 6c 65 44 61 74 61 20 73 74  AsyncFileData st
3bf0: 72 75 63 74 75 72 65 20 28 73 65 65 20 41 73 79  ructure (see Asy
3c00: 6e 63 46 69 6c 65 44 61 74 61 2e 6c 6f 63 6b 29  ncFileData.lock)
3c10: 2c 20 62 75 74 20 69 73 20 6f 6e 6c 79 20 75 73  , but is only us
3c20: 65 64 20 69 66 20 74 68 65 0a 2a 2a 20 66 69 6c  ed if the.** fil
3c30: 65 20 77 61 73 20 6f 70 65 6e 65 64 20 77 69 74  e was opened wit
3c40: 68 20 74 68 65 20 53 51 4c 49 54 45 5f 4f 50 45  h the SQLITE_OPE
3c50: 4e 5f 4d 41 49 4e 5f 44 42 2e 0a 2a 2f 0a 73 74  N_MAIN_DB..*/.st
3c60: 72 75 63 74 20 41 73 79 6e 63 46 69 6c 65 4c 6f  ruct AsyncFileLo
3c70: 63 6b 20 7b 0a 20 20 69 6e 74 20 65 4c 6f 63 6b  ck {.  int eLock
3c80: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3c90: 20 2f 2a 20 49 6e 74 65 72 6e 61 6c 6c 79 20 76   /* Internally v
3ca0: 69 73 69 62 6c 65 20 6c 6f 63 6b 20 73 74 61 74  isible lock stat
3cb0: 65 20 28 73 71 6c 69 74 65 20 70 6f 76 29 20 2a  e (sqlite pov) *
3cc0: 2f 0a 20 20 69 6e 74 20 65 41 73 79 6e 63 4c 6f  /.  int eAsyncLo
3cd0: 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ck;           /*
3ce0: 20 4c 6f 63 6b 2d 73 74 61 74 65 20 77 69 74 68   Lock-state with
3cf0: 20 77 72 69 74 65 2d 71 75 65 75 65 20 75 6e 6c   write-queue unl
3d00: 6f 63 6b 20 2a 2f 0a 20 20 41 73 79 6e 63 46 69  ock */.  AsyncFi
3d10: 6c 65 4c 6f 63 6b 20 2a 70 4e 65 78 74 3b 0a 7d  leLock *pNext;.}
3d20: 3b 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 65 20 41 73  ;../* .** The As
3d30: 79 6e 63 46 69 6c 65 20 73 74 72 75 63 74 75 72  yncFile structur
3d40: 65 20 69 73 20 61 20 73 75 62 63 6c 61 73 73 20  e is a subclass 
3d50: 6f 66 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  of sqlite3_file 
3d60: 75 73 65 64 20 66 6f 72 20 0a 2a 2a 20 61 73 79  used for .** asy
3d70: 6e 63 68 72 6f 6e 6f 75 73 20 49 4f 2e 20 0a 2a  nchronous IO. .*
3d80: 2a 0a 2a 2a 20 41 6c 6c 20 6f 66 20 74 68 65 20  *.** All of the 
3d90: 61 63 74 75 61 6c 20 64 61 74 61 20 66 6f 72 20  actual data for 
3da0: 74 68 65 20 73 74 72 75 63 74 75 72 65 20 69 73  the structure is
3db0: 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 73   stored in the s
3dc0: 74 72 75 63 74 75 72 65 0a 2a 2a 20 70 6f 69 6e  tructure.** poin
3dd0: 74 65 64 20 74 6f 20 62 79 20 41 73 79 6e 63 46  ted to by AsyncF
3de0: 69 6c 65 2e 70 44 61 74 61 2c 20 77 68 69 63 68  ile.pData, which
3df0: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 61 73   is allocated as
3e00: 20 70 61 72 74 20 6f 66 20 74 68 65 0a 2a 2a 20   part of the.** 
3e10: 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 28 29 20  sqlite3OsOpen() 
3e20: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 6d 61  using sqlite3_ma
3e30: 6c 6c 6f 63 28 29 2e 20 54 68 65 20 72 65 61 73  lloc(). The reas
3e40: 6f 6e 20 66 6f 72 20 74 68 69 73 20 69 73 20 74  on for this is t
3e50: 68 61 74 20 74 68 65 0a 2a 2a 20 6c 69 66 65 74  hat the.** lifet
3e60: 69 6d 65 20 6f 66 20 74 68 65 20 41 73 79 6e 63  ime of the Async
3e70: 46 69 6c 65 20 73 74 72 75 63 74 75 72 65 20 69  File structure i
3e80: 73 20 65 6e 64 65 64 20 62 79 20 74 68 65 20 63  s ended by the c
3e90: 61 6c 6c 65 72 20 61 66 74 65 72 20 4f 73 43 6c  aller after OsCl
3ea0: 6f 73 65 28 29 0a 2a 2a 20 69 73 20 63 61 6c 6c  ose().** is call
3eb0: 65 64 2c 20 62 75 74 20 74 68 65 20 64 61 74 61  ed, but the data
3ec0: 20 69 6e 20 41 73 79 6e 63 46 69 6c 65 44 61 74   in AsyncFileDat
3ed0: 61 20 6d 61 79 20 62 65 20 72 65 71 75 69 72 65  a may be require
3ee0: 64 20 62 79 20 74 68 65 0a 2a 2a 20 77 72 69 74  d by the.** writ
3ef0: 65 72 20 74 68 72 65 61 64 20 61 66 74 65 72 20  er thread after 
3f00: 74 68 61 74 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 73  that point..*/.s
3f10: 74 72 75 63 74 20 41 73 79 6e 63 46 69 6c 65 20  truct AsyncFile 
3f20: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  {.  sqlite3_io_m
3f30: 65 74 68 6f 64 73 20 2a 70 4d 65 74 68 6f 64 3b  ethods *pMethod;
3f40: 0a 20 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61  .  AsyncFileData
3f50: 20 2a 70 44 61 74 61 3b 0a 7d 3b 0a 73 74 72 75   *pData;.};.stru
3f60: 63 74 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61  ct AsyncFileData
3f70: 20 7b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65   {.  char *zName
3f80: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3f90: 2f 2a 20 55 6e 64 65 72 6c 79 69 6e 67 20 4f 53  /* Underlying OS
3fa0: 20 66 69 6c 65 6e 61 6d 65 20 2d 20 75 73 65 64   filename - used
3fb0: 20 66 6f 72 20 64 65 62 75 67 67 69 6e 67 20 2a   for debugging *
3fc0: 2f 0a 20 20 69 6e 74 20 6e 4e 61 6d 65 3b 20 20  /.  int nName;  
3fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3fe0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 68 61 72  * Number of char
3ff0: 61 63 74 65 72 73 20 69 6e 20 7a 4e 61 6d 65 20  acters in zName 
4000: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
4010: 65 20 2a 70 42 61 73 65 52 65 61 64 3b 20 20 20  e *pBaseRead;   
4020: 2f 2a 20 52 65 61 64 20 68 61 6e 64 6c 65 20 74  /* Read handle t
4030: 6f 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  o the underlying
4040: 20 4f 73 20 66 69 6c 65 20 2a 2f 0a 20 20 73 71   Os file */.  sq
4050: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 42 61 73  lite3_file *pBas
4060: 65 57 72 69 74 65 3b 20 20 2f 2a 20 57 72 69 74  eWrite;  /* Writ
4070: 65 20 68 61 6e 64 6c 65 20 74 6f 20 74 68 65 20  e handle to the 
4080: 75 6e 64 65 72 6c 79 69 6e 67 20 4f 73 20 66 69  underlying Os fi
4090: 6c 65 20 2a 2f 0a 20 20 41 73 79 6e 63 46 69 6c  le */.  AsyncFil
40a0: 65 4c 6f 63 6b 20 6c 6f 63 6b 3b 20 20 20 20 20  eLock lock;     
40b0: 20 20 20 2f 2a 20 4c 6f 63 6b 20 73 74 61 74 65     /* Lock state
40c0: 20 66 6f 72 20 74 68 69 73 20 68 61 6e 64 6c 65   for this handle
40d0: 20 2a 2f 0a 20 20 41 73 79 6e 63 4c 6f 63 6b 20   */.  AsyncLock 
40e0: 2a 70 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20  *pLock;         
40f0: 20 2f 2a 20 41 73 79 6e 63 4c 6f 63 6b 20 6f 62   /* AsyncLock ob
4100: 6a 65 63 74 20 66 6f 72 20 74 68 69 73 20 66 69  ject for this fi
4110: 6c 65 20 73 79 73 74 65 6d 20 65 6e 74 72 79 20  le system entry 
4120: 2a 2f 0a 20 20 41 73 79 6e 63 57 72 69 74 65 20  */.  AsyncWrite 
4130: 63 6c 6f 73 65 4f 70 3b 20 20 20 20 20 20 20 20  closeOp;        
4140: 2f 2a 20 50 72 65 61 6c 6c 6f 63 61 74 65 64 20  /* Preallocated 
4150: 63 6c 6f 73 65 20 6f 70 65 72 61 74 69 6f 6e 20  close operation 
4160: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  */.};../*.** The
4170: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 73 79 6e 63   following async
4180: 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 73 20 61  _XXX functions a
4190: 72 65 20 64 65 62 75 67 67 69 6e 67 20 77 72 61  re debugging wra
41a0: 70 70 65 72 73 20 61 72 6f 75 6e 64 20 74 68 65  ppers around the
41b0: 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  .** correspondin
41c0: 67 20 70 74 68 72 65 61 64 5f 58 58 58 20 66 75  g pthread_XXX fu
41d0: 6e 63 74 69 6f 6e 73 3a 0a 2a 2a 0a 2a 2a 20 20  nctions:.**.**  
41e0: 20 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78     pthread_mutex
41f0: 5f 6c 6f 63 6b 28 29 3b 0a 2a 2a 20 20 20 20 20  _lock();.**     
4200: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
4210: 6c 6f 63 6b 28 29 3b 0a 2a 2a 20 20 20 20 20 70  lock();.**     p
4220: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 72 79  thread_mutex_try
4230: 6c 6f 63 6b 28 29 3b 0a 2a 2a 20 20 20 20 20 70  lock();.**     p
4240: 74 68 72 65 61 64 5f 63 6f 6e 64 5f 77 61 69 74  thread_cond_wait
4250: 28 29 3b 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73 20  ();.**.** It is 
4260: 69 6c 6c 65 67 61 6c 20 74 6f 20 70 61 73 73 20  illegal to pass 
4270: 61 6e 79 20 6d 75 74 65 78 20 6f 74 68 65 72 20  any mutex other 
4280: 74 68 61 6e 20 74 68 6f 73 65 20 73 74 6f 72 65  than those store
4290: 64 20 69 6e 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c  d in the.** foll
42a0: 6f 77 69 6e 67 20 67 6c 6f 62 61 6c 20 76 61 72  owing global var
42b0: 69 61 62 6c 65 73 20 6f 66 20 74 68 65 73 65 20  iables of these 
42c0: 66 75 6e 63 74 69 6f 6e 73 2e 0a 2a 2a 0a 2a 2a  functions..**.**
42d0: 20 20 20 20 20 61 73 79 6e 63 2e 71 75 65 75 65       async.queue
42e0: 4d 75 74 65 78 0a 2a 2a 20 20 20 20 20 61 73 79  Mutex.**     asy
42f0: 6e 63 2e 77 72 69 74 65 72 4d 75 74 65 78 0a 2a  nc.writerMutex.*
4300: 2a 20 20 20 20 20 61 73 79 6e 63 2e 6c 6f 63 6b  *     async.lock
4310: 4d 75 74 65 78 0a 2a 2a 0a 2a 2a 20 49 66 20 4e  Mutex.**.** If N
4320: 44 45 42 55 47 20 69 73 20 64 65 66 69 6e 65 64  DEBUG is defined
4330: 2c 20 74 68 65 73 65 20 77 72 61 70 70 65 72 73  , these wrappers
4340: 20 64 6f 20 6e 6f 74 68 69 6e 67 20 65 78 63 65   do nothing exce
4350: 70 74 20 63 61 6c 6c 20 74 68 65 20 0a 2a 2a 20  pt call the .** 
4360: 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 70 74  corresponding pt
4370: 68 72 65 61 64 73 20 66 75 6e 63 74 69 6f 6e 2e  hreads function.
4380: 20 49 66 20 4e 44 45 42 55 47 20 69 73 20 6e 6f   If NDEBUG is no
4390: 74 20 64 65 66 69 6e 65 64 2c 20 74 68 65 6e 20  t defined, then 
43a0: 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67  the.** following
43b0: 20 76 61 72 69 61 62 6c 65 73 20 61 72 65 20 75   variables are u
43c0: 73 65 64 20 74 6f 20 73 74 6f 72 65 20 74 68 65  sed to store the
43d0: 20 74 68 72 65 61 64 2d 69 64 20 28 61 73 20 72   thread-id (as r
43e0: 65 74 75 72 6e 65 64 0a 2a 2a 20 62 79 20 70 74  eturned.** by pt
43f0: 68 72 65 61 64 5f 73 65 6c 66 28 29 29 20 63 75  hread_self()) cu
4400: 72 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67 20  rrently holding 
4410: 74 68 65 20 6d 75 74 65 78 2c 20 6f 72 20 30 20  the mutex, or 0 
4420: 6f 74 68 65 72 77 69 73 65 3a 0a 2a 2a 0a 2a 2a  otherwise:.**.**
4430: 20 20 20 20 20 61 73 79 6e 63 64 65 62 75 67 2e       asyncdebug.
4440: 71 75 65 75 65 4d 75 74 65 78 48 6f 6c 64 65 72  queueMutexHolder
4450: 0a 2a 2a 20 20 20 20 20 61 73 79 6e 63 64 65 62  .**     asyncdeb
4460: 75 67 2e 77 72 69 74 65 72 4d 75 74 65 78 48 6f  ug.writerMutexHo
4470: 6c 64 65 72 0a 2a 2a 20 20 20 20 20 61 73 79 6e  lder.**     asyn
4480: 63 64 65 62 75 67 2e 6c 6f 63 6b 4d 75 74 65 78  cdebug.lockMutex
4490: 48 6f 6c 64 65 72 0a 2a 2a 0a 2a 2a 20 54 68 65  Holder.**.** The
44a0: 73 65 20 76 61 72 69 61 62 6c 65 73 20 61 72 65  se variables are
44b0: 20 75 73 65 64 20 62 79 20 73 6f 6d 65 20 61 73   used by some as
44c0: 73 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74  sert() statement
44d0: 73 20 74 68 61 74 20 76 65 72 69 66 79 0a 2a 2a  s that verify.**
44e0: 20 74 68 65 20 73 74 61 74 65 6d 65 6e 74 73 20   the statements 
44f0: 6d 61 64 65 20 69 6e 20 74 68 65 20 22 44 65 61  made in the "Dea
4500: 64 6c 6f 63 6b 20 50 72 65 76 65 6e 74 69 6f 6e  dlock Prevention
4510: 22 20 6e 6f 74 65 73 20 65 61 72 6c 69 65 72 0a  " notes earlier.
4520: 2a 2a 20 69 6e 20 74 68 69 73 20 66 69 6c 65 2e  ** in this file.
4530: 0a 2a 2f 0a 23 69 66 6e 64 65 66 20 4e 44 45 42  .*/.#ifndef NDEB
4540: 55 47 0a 0a 73 74 61 74 69 63 20 73 74 72 75 63  UG..static struc
4550: 74 20 54 65 73 74 41 73 79 6e 63 44 65 62 75 67  t TestAsyncDebug
4560: 44 61 74 61 20 7b 0a 20 20 70 74 68 72 65 61 64  Data {.  pthread
4570: 5f 74 20 6c 6f 63 6b 4d 75 74 65 78 48 6f 6c 64  _t lockMutexHold
4580: 65 72 3b 0a 20 20 70 74 68 72 65 61 64 5f 74 20  er;.  pthread_t 
4590: 71 75 65 75 65 4d 75 74 65 78 48 6f 6c 64 65 72  queueMutexHolder
45a0: 3b 0a 20 20 70 74 68 72 65 61 64 5f 74 20 77 72  ;.  pthread_t wr
45b0: 69 74 65 72 4d 75 74 65 78 48 6f 6c 64 65 72 3b  iterMutexHolder;
45c0: 0a 7d 20 61 73 79 6e 63 64 65 62 75 67 20 3d 20  .} asyncdebug = 
45d0: 7b 30 2c 20 30 2c 20 30 7d 3b 0a 0a 2f 2a 0a 2a  {0, 0, 0};../*.*
45e0: 2a 20 57 72 61 70 70 65 72 20 61 72 6f 75 6e 64  * Wrapper around
45f0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
4600: 6f 63 6b 28 29 2e 20 43 68 65 63 6b 73 20 74 68  ock(). Checks th
4610: 61 74 20 77 65 20 68 61 76 65 20 6e 6f 74 20 76  at we have not v
4620: 69 6f 6c 61 74 65 64 0a 2a 2a 20 74 68 65 20 61  iolated.** the a
4630: 6e 74 69 2d 64 65 61 64 6c 6f 63 6b 20 72 75 6c  nti-deadlock rul
4640: 65 73 20 28 73 65 65 20 22 44 65 61 64 6c 6f 63  es (see "Deadloc
4650: 6b 20 70 72 65 76 65 6e 74 69 6f 6e 22 20 61 62  k prevention" ab
4660: 6f 76 65 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ove)..*/.static 
4670: 69 6e 74 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f  int async_mutex_
4680: 6c 6f 63 6b 28 70 74 68 72 65 61 64 5f 6d 75 74  lock(pthread_mut
4690: 65 78 5f 74 20 2a 70 4d 75 74 65 78 29 7b 0a 20  ex_t *pMutex){. 
46a0: 20 69 6e 74 20 69 49 64 78 3b 0a 20 20 69 6e 74   int iIdx;.  int
46b0: 20 72 63 3b 0a 20 20 70 74 68 72 65 61 64 5f 6d   rc;.  pthread_m
46c0: 75 74 65 78 5f 74 20 2a 61 4d 75 74 65 78 20 3d  utex_t *aMutex =
46d0: 20 28 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f   (pthread_mutex_
46e0: 74 20 2a 29 28 26 61 73 79 6e 63 29 3b 0a 20 20  t *)(&async);.  
46f0: 70 74 68 72 65 61 64 5f 74 20 2a 61 48 6f 6c 64  pthread_t *aHold
4700: 65 72 20 3d 20 28 70 74 68 72 65 61 64 5f 74 20  er = (pthread_t 
4710: 2a 29 28 26 61 73 79 6e 63 64 65 62 75 67 29 3b  *)(&asyncdebug);
4720: 0a 0a 20 20 2f 2a 20 54 68 65 20 63 6f 64 65 20  ..  /* The code 
4730: 69 6e 20 74 68 69 73 20 27 69 66 6e 64 65 66 20  in this 'ifndef 
4740: 4e 44 45 42 55 47 27 20 62 6c 6f 63 6b 20 64 65  NDEBUG' block de
4750: 70 65 6e 64 73 20 6f 6e 20 61 20 63 65 72 74 61  pends on a certa
4760: 69 6e 20 61 6c 69 67 6e 6d 65 6e 74 0a 20 20 20  in alignment.   
4770: 2a 20 6f 66 20 74 68 65 20 76 61 72 69 61 62 6c  * of the variabl
4780: 65 73 20 69 6e 20 54 65 73 74 41 73 79 6e 63 53  es in TestAsyncS
4790: 74 61 74 69 63 44 61 74 61 20 61 6e 64 20 54 65  taticData and Te
47a0: 73 74 41 73 79 6e 63 44 65 62 75 67 44 61 74 61  stAsyncDebugData
47b0: 2e 20 54 68 65 0a 20 20 20 2a 20 66 6f 6c 6c 6f  . The.   * follo
47c0: 77 69 6e 67 20 61 73 73 65 72 74 28 29 20 73 74  wing assert() st
47d0: 61 74 65 6d 65 6e 74 73 20 63 68 65 63 6b 20 74  atements check t
47e0: 68 61 74 20 74 68 69 73 20 68 61 73 20 6e 6f 74  hat this has not
47f0: 20 62 65 65 6e 20 63 68 61 6e 67 65 64 2e 0a 20   been changed.. 
4800: 20 20 2a 0a 20 20 20 2a 20 52 65 61 6c 6c 79 2c    *.   * Really,
4810: 20 74 68 65 73 65 20 6f 6e 6c 79 20 6e 65 65 64   these only need
4820: 20 74 6f 20 62 65 20 72 75 6e 20 6f 6e 63 65 20   to be run once 
4830: 61 74 20 73 74 61 72 74 75 70 20 74 69 6d 65 2e  at startup time.
4840: 0a 20 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  .   */.  assert(
4850: 26 28 61 4d 75 74 65 78 5b 30 5d 29 3d 3d 26 61  &(aMutex[0])==&a
4860: 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b  sync.lockMutex);
4870: 0a 20 20 61 73 73 65 72 74 28 26 28 61 4d 75 74  .  assert(&(aMut
4880: 65 78 5b 31 5d 29 3d 3d 26 61 73 79 6e 63 2e 71  ex[1])==&async.q
4890: 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20 61 73  ueueMutex);.  as
48a0: 73 65 72 74 28 26 28 61 4d 75 74 65 78 5b 32 5d  sert(&(aMutex[2]
48b0: 29 3d 3d 26 61 73 79 6e 63 2e 77 72 69 74 65 72  )==&async.writer
48c0: 4d 75 74 65 78 29 3b 0a 20 20 61 73 73 65 72 74  Mutex);.  assert
48d0: 28 26 28 61 48 6f 6c 64 65 72 5b 30 5d 29 3d 3d  (&(aHolder[0])==
48e0: 26 61 73 79 6e 63 64 65 62 75 67 2e 6c 6f 63 6b  &asyncdebug.lock
48f0: 4d 75 74 65 78 48 6f 6c 64 65 72 29 3b 0a 20 20  MutexHolder);.  
4900: 61 73 73 65 72 74 28 26 28 61 48 6f 6c 64 65 72  assert(&(aHolder
4910: 5b 31 5d 29 3d 3d 26 61 73 79 6e 63 64 65 62 75  [1])==&asyncdebu
4920: 67 2e 71 75 65 75 65 4d 75 74 65 78 48 6f 6c 64  g.queueMutexHold
4930: 65 72 29 3b 0a 20 20 61 73 73 65 72 74 28 26 28  er);.  assert(&(
4940: 61 48 6f 6c 64 65 72 5b 32 5d 29 3d 3d 26 61 73  aHolder[2])==&as
4950: 79 6e 63 64 65 62 75 67 2e 77 72 69 74 65 72 4d  yncdebug.writerM
4960: 75 74 65 78 48 6f 6c 64 65 72 29 3b 0a 0a 20 20  utexHolder);..  
4970: 61 73 73 65 72 74 28 20 70 74 68 72 65 61 64 5f  assert( pthread_
4980: 73 65 6c 66 28 29 21 3d 30 20 29 3b 0a 20 20 66  self()!=0 );.  f
4990: 6f 72 28 69 49 64 78 3d 30 3b 20 69 49 64 78 3c  or(iIdx=0; iIdx<
49a0: 33 3b 20 69 49 64 78 2b 2b 29 7b 0a 20 20 20 20  3; iIdx++){.    
49b0: 69 66 28 20 70 4d 75 74 65 78 3d 3d 26 61 4d 75  if( pMutex==&aMu
49c0: 74 65 78 5b 69 49 64 78 5d 20 29 20 62 72 65 61  tex[iIdx] ) brea
49d0: 6b 3b 0a 0a 20 20 20 20 2f 2a 20 54 68 69 73 20  k;..    /* This 
49e0: 69 73 20 74 68 65 20 6b 65 79 20 61 73 73 65 72  is the key asser
49f0: 74 28 29 2e 20 48 65 72 65 20 77 65 20 61 72 65  t(). Here we are
4a00: 20 63 68 65 63 6b 69 6e 67 20 74 68 61 74 20 69   checking that i
4a10: 66 20 74 68 65 20 63 61 6c 6c 65 72 0a 20 20 20  f the caller.   
4a20: 20 20 2a 20 69 73 20 74 72 79 69 6e 67 20 74 6f    * is trying to
4a30: 20 62 6c 6f 63 6b 20 6f 6e 20 61 73 79 6e 63 2e   block on async.
4a40: 77 72 69 74 65 72 4d 75 74 65 78 2c 20 6e 65 69  writerMutex, nei
4a50: 74 68 65 72 20 6f 66 20 74 68 65 20 6f 74 68 65  ther of the othe
4a60: 72 20 74 77 6f 0a 20 20 20 20 20 2a 20 6d 75 74  r two.     * mut
4a70: 65 78 20 61 72 65 20 68 65 6c 64 2e 20 49 66 20  ex are held. If 
4a80: 74 68 65 20 63 61 6c 6c 65 72 20 69 73 20 74 72  the caller is tr
4a90: 79 69 6e 67 20 74 6f 20 62 6c 6f 63 6b 20 6f 6e  ying to block on
4aa0: 20 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65   async.queueMute
4ab0: 78 2c 0a 20 20 20 20 20 2a 20 6c 6f 63 6b 4d 75  x,.     * lockMu
4ac0: 74 65 78 20 69 73 20 6e 6f 74 20 68 65 6c 64 2e  tex is not held.
4ad0: 0a 20 20 20 20 20 2a 2f 0a 20 20 20 20 61 73 73  .     */.    ass
4ae0: 65 72 74 28 21 70 74 68 72 65 61 64 5f 65 71 75  ert(!pthread_equ
4af0: 61 6c 28 61 48 6f 6c 64 65 72 5b 69 49 64 78 5d  al(aHolder[iIdx]
4b00: 2c 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29  , pthread_self()
4b10: 29 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  ));.  }.  assert
4b20: 28 69 49 64 78 3c 33 29 3b 0a 0a 20 20 72 63 20  (iIdx<3);..  rc 
4b30: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
4b40: 6c 6f 63 6b 28 70 4d 75 74 65 78 29 3b 0a 20 20  lock(pMutex);.  
4b50: 69 66 28 20 72 63 3d 3d 30 20 29 7b 0a 20 20 20  if( rc==0 ){.   
4b60: 20 61 73 73 65 72 74 28 61 48 6f 6c 64 65 72 5b   assert(aHolder[
4b70: 69 49 64 78 5d 3d 3d 30 29 3b 0a 20 20 20 20 61  iIdx]==0);.    a
4b80: 48 6f 6c 64 65 72 5b 69 49 64 78 5d 20 3d 20 70  Holder[iIdx] = p
4b90: 74 68 72 65 61 64 5f 73 65 6c 66 28 29 3b 0a 20  thread_self();. 
4ba0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
4bb0: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 61 70 70 65 72  }../*.** Wrapper
4bc0: 20 61 72 6f 75 6e 64 20 70 74 68 72 65 61 64 5f   around pthread_
4bd0: 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 29 2e 0a  mutex_unlock()..
4be0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 73  */.static int as
4bf0: 79 6e 63 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b  ync_mutex_unlock
4c00: 28 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74  (pthread_mutex_t
4c10: 20 2a 70 4d 75 74 65 78 29 7b 0a 20 20 69 6e 74   *pMutex){.  int
4c20: 20 69 49 64 78 3b 0a 20 20 69 6e 74 20 72 63 3b   iIdx;.  int rc;
4c30: 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78  .  pthread_mutex
4c40: 5f 74 20 2a 61 4d 75 74 65 78 20 3d 20 28 70 74  _t *aMutex = (pt
4c50: 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 2a 29  hread_mutex_t *)
4c60: 28 26 61 73 79 6e 63 29 3b 0a 20 20 70 74 68 72  (&async);.  pthr
4c70: 65 61 64 5f 74 20 2a 61 48 6f 6c 64 65 72 20 3d  ead_t *aHolder =
4c80: 20 28 70 74 68 72 65 61 64 5f 74 20 2a 29 28 26   (pthread_t *)(&
4c90: 61 73 79 6e 63 64 65 62 75 67 29 3b 0a 0a 20 20  asyncdebug);..  
4ca0: 66 6f 72 28 69 49 64 78 3d 30 3b 20 69 49 64 78  for(iIdx=0; iIdx
4cb0: 3c 33 3b 20 69 49 64 78 2b 2b 29 7b 0a 20 20 20  <3; iIdx++){.   
4cc0: 20 69 66 28 20 70 4d 75 74 65 78 3d 3d 26 61 4d   if( pMutex==&aM
4cd0: 75 74 65 78 5b 69 49 64 78 5d 20 29 20 62 72 65  utex[iIdx] ) bre
4ce0: 61 6b 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  ak;.  }.  assert
4cf0: 28 69 49 64 78 3c 33 29 3b 0a 0a 20 20 61 73 73  (iIdx<3);..  ass
4d00: 65 72 74 28 70 74 68 72 65 61 64 5f 65 71 75 61  ert(pthread_equa
4d10: 6c 28 61 48 6f 6c 64 65 72 5b 69 49 64 78 5d 2c  l(aHolder[iIdx],
4d20: 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29   pthread_self())
4d30: 29 3b 0a 20 20 61 48 6f 6c 64 65 72 5b 69 49 64  );.  aHolder[iId
4d40: 78 5d 20 3d 20 30 3b 0a 20 20 72 63 20 3d 20 70  x] = 0;.  rc = p
4d50: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
4d60: 6f 63 6b 28 70 4d 75 74 65 78 29 3b 0a 20 20 61  ock(pMutex);.  a
4d70: 73 73 65 72 74 28 72 63 3d 3d 30 29 3b 0a 0a 20  ssert(rc==0);.. 
4d80: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a   return 0;.}../*
4d90: 0a 2a 2a 20 57 72 61 70 70 65 72 20 61 72 6f 75  .** Wrapper arou
4da0: 6e 64 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78  nd pthread_mutex
4db0: 5f 74 72 79 6c 6f 63 6b 28 29 2e 0a 2a 2f 0a 73  _trylock()..*/.s
4dc0: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 5f  tatic int async_
4dd0: 6d 75 74 65 78 5f 74 72 79 6c 6f 63 6b 28 70 74  mutex_trylock(pt
4de0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 2a 70  hread_mutex_t *p
4df0: 4d 75 74 65 78 29 7b 0a 20 20 69 6e 74 20 69 49  Mutex){.  int iI
4e00: 64 78 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  dx;.  int rc;.  
4e10: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20  pthread_mutex_t 
4e20: 2a 61 4d 75 74 65 78 20 3d 20 28 70 74 68 72 65  *aMutex = (pthre
4e30: 61 64 5f 6d 75 74 65 78 5f 74 20 2a 29 28 26 61  ad_mutex_t *)(&a
4e40: 73 79 6e 63 29 3b 0a 20 20 70 74 68 72 65 61 64  sync);.  pthread
4e50: 5f 74 20 2a 61 48 6f 6c 64 65 72 20 3d 20 28 70  _t *aHolder = (p
4e60: 74 68 72 65 61 64 5f 74 20 2a 29 28 26 61 73 79  thread_t *)(&asy
4e70: 6e 63 64 65 62 75 67 29 3b 0a 0a 20 20 66 6f 72  ncdebug);..  for
4e80: 28 69 49 64 78 3d 30 3b 20 69 49 64 78 3c 33 3b  (iIdx=0; iIdx<3;
4e90: 20 69 49 64 78 2b 2b 29 7b 0a 20 20 20 20 69 66   iIdx++){.    if
4ea0: 28 20 70 4d 75 74 65 78 3d 3d 26 61 4d 75 74 65  ( pMutex==&aMute
4eb0: 78 5b 69 49 64 78 5d 20 29 20 62 72 65 61 6b 3b  x[iIdx] ) break;
4ec0: 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 69 49  .  }.  assert(iI
4ed0: 64 78 3c 33 29 3b 0a 0a 20 20 72 63 20 3d 20 70  dx<3);..  rc = p
4ee0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 72 79  thread_mutex_try
4ef0: 6c 6f 63 6b 28 70 4d 75 74 65 78 29 3b 0a 20 20  lock(pMutex);.  
4f00: 69 66 28 20 72 63 3d 3d 30 20 29 7b 0a 20 20 20  if( rc==0 ){.   
4f10: 20 61 73 73 65 72 74 28 61 48 6f 6c 64 65 72 5b   assert(aHolder[
4f20: 69 49 64 78 5d 3d 3d 30 29 3b 0a 20 20 20 20 61  iIdx]==0);.    a
4f30: 48 6f 6c 64 65 72 5b 69 49 64 78 5d 20 3d 20 70  Holder[iIdx] = p
4f40: 74 68 72 65 61 64 5f 73 65 6c 66 28 29 3b 0a 20  thread_self();. 
4f50: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
4f60: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 61 70 70 65 72  }../*.** Wrapper
4f70: 20 61 72 6f 75 6e 64 20 70 74 68 72 65 61 64 5f   around pthread_
4f80: 63 6f 6e 64 5f 77 61 69 74 28 29 2e 0a 2a 2f 0a  cond_wait()..*/.
4f90: 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63  static int async
4fa0: 5f 63 6f 6e 64 5f 77 61 69 74 28 70 74 68 72 65  _cond_wait(pthre
4fb0: 61 64 5f 63 6f 6e 64 5f 74 20 2a 70 43 6f 6e 64  ad_cond_t *pCond
4fc0: 2c 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  , pthread_mutex_
4fd0: 74 20 2a 70 4d 75 74 65 78 29 7b 0a 20 20 69 6e  t *pMutex){.  in
4fe0: 74 20 69 49 64 78 3b 0a 20 20 69 6e 74 20 72 63  t iIdx;.  int rc
4ff0: 3b 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65  ;.  pthread_mute
5000: 78 5f 74 20 2a 61 4d 75 74 65 78 20 3d 20 28 70  x_t *aMutex = (p
5010: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 2a  thread_mutex_t *
5020: 29 28 26 61 73 79 6e 63 29 3b 0a 20 20 70 74 68  )(&async);.  pth
5030: 72 65 61 64 5f 74 20 2a 61 48 6f 6c 64 65 72 20  read_t *aHolder 
5040: 3d 20 28 70 74 68 72 65 61 64 5f 74 20 2a 29 28  = (pthread_t *)(
5050: 26 61 73 79 6e 63 64 65 62 75 67 29 3b 0a 0a 20  &asyncdebug);.. 
5060: 20 66 6f 72 28 69 49 64 78 3d 30 3b 20 69 49 64   for(iIdx=0; iId
5070: 78 3c 33 3b 20 69 49 64 78 2b 2b 29 7b 0a 20 20  x<3; iIdx++){.  
5080: 20 20 69 66 28 20 70 4d 75 74 65 78 3d 3d 26 61    if( pMutex==&a
5090: 4d 75 74 65 78 5b 69 49 64 78 5d 20 29 20 62 72  Mutex[iIdx] ) br
50a0: 65 61 6b 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72  eak;.  }.  asser
50b0: 74 28 69 49 64 78 3c 33 29 3b 0a 0a 20 20 61 73  t(iIdx<3);..  as
50c0: 73 65 72 74 28 70 74 68 72 65 61 64 5f 65 71 75  sert(pthread_equ
50d0: 61 6c 28 61 48 6f 6c 64 65 72 5b 69 49 64 78 5d  al(aHolder[iIdx]
50e0: 2c 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29  ,pthread_self())
50f0: 29 3b 0a 20 20 61 48 6f 6c 64 65 72 5b 69 49 64  );.  aHolder[iId
5100: 78 5d 20 3d 20 30 3b 0a 20 20 72 63 20 3d 20 70  x] = 0;.  rc = p
5110: 74 68 72 65 61 64 5f 63 6f 6e 64 5f 77 61 69 74  thread_cond_wait
5120: 28 70 43 6f 6e 64 2c 20 70 4d 75 74 65 78 29 3b  (pCond, pMutex);
5130: 0a 20 20 69 66 28 20 72 63 3d 3d 30 20 29 7b 0a  .  if( rc==0 ){.
5140: 20 20 20 20 61 48 6f 6c 64 65 72 5b 69 49 64 78      aHolder[iIdx
5150: 5d 20 3d 20 70 74 68 72 65 61 64 5f 73 65 6c 66  ] = pthread_self
5160: 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ();.  }.  return
5170: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 73   rc;.}../*.** As
5180: 73 65 72 74 20 74 68 61 74 20 74 68 65 20 6d 75  sert that the mu
5190: 74 65 78 20 69 73 20 68 65 6c 64 20 62 79 20 74  tex is held by t
51a0: 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61  he current threa
51b0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
51c0: 64 20 61 73 73 65 72 74 5f 6d 75 74 65 78 5f 69  d assert_mutex_i
51d0: 73 5f 68 65 6c 64 28 70 74 68 72 65 61 64 5f 6d  s_held(pthread_m
51e0: 75 74 65 78 5f 74 20 2a 70 4d 75 74 65 78 29 7b  utex_t *pMutex){
51f0: 0a 20 20 69 6e 74 20 69 49 64 78 3b 0a 20 20 70  .  int iIdx;.  p
5200: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 2a  thread_mutex_t *
5210: 61 4d 75 74 65 78 20 3d 20 28 70 74 68 72 65 61  aMutex = (pthrea
5220: 64 5f 6d 75 74 65 78 5f 74 20 2a 29 28 26 61 73  d_mutex_t *)(&as
5230: 79 6e 63 29 3b 0a 20 20 70 74 68 72 65 61 64 5f  ync);.  pthread_
5240: 74 20 2a 61 48 6f 6c 64 65 72 20 3d 20 28 70 74  t *aHolder = (pt
5250: 68 72 65 61 64 5f 74 20 2a 29 28 26 61 73 79 6e  hread_t *)(&asyn
5260: 63 64 65 62 75 67 29 3b 0a 0a 20 20 66 6f 72 28  cdebug);..  for(
5270: 69 49 64 78 3d 30 3b 20 69 49 64 78 3c 33 3b 20  iIdx=0; iIdx<3; 
5280: 69 49 64 78 2b 2b 29 7b 0a 20 20 20 20 69 66 28  iIdx++){.    if(
5290: 20 70 4d 75 74 65 78 3d 3d 26 61 4d 75 74 65 78   pMutex==&aMutex
52a0: 5b 69 49 64 78 5d 20 29 20 62 72 65 61 6b 3b 0a  [iIdx] ) break;.
52b0: 20 20 7d 0a 20 20 61 73 73 65 72 74 28 69 49 64    }.  assert(iId
52c0: 78 3c 33 29 3b 0a 20 20 61 73 73 65 72 74 28 20  x<3);.  assert( 
52d0: 61 48 6f 6c 64 65 72 5b 69 49 64 78 5d 3d 3d 70  aHolder[iIdx]==p
52e0: 74 68 72 65 61 64 5f 73 65 6c 66 28 29 20 29 3b  thread_self() );
52f0: 0a 7d 0a 0a 2f 2a 20 43 61 6c 6c 20 6f 75 72 20  .}../* Call our 
5300: 61 73 79 6e 63 5f 58 58 20 77 72 61 70 70 65 72  async_XX wrapper
5310: 73 20 69 6e 73 74 65 61 64 20 6f 66 20 73 65 6c  s instead of sel
5320: 65 63 74 65 64 20 70 74 68 72 65 61 64 5f 58 58  ected pthread_XX
5330: 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 23 64   functions */.#d
5340: 65 66 69 6e 65 20 70 74 68 72 65 61 64 5f 6d 75  efine pthread_mu
5350: 74 65 78 5f 6c 6f 63 6b 20 20 20 20 61 73 79 6e  tex_lock    asyn
5360: 63 5f 6d 75 74 65 78 5f 6c 6f 63 6b 0a 23 64 65  c_mutex_lock.#de
5370: 66 69 6e 65 20 70 74 68 72 65 61 64 5f 6d 75 74  fine pthread_mut
5380: 65 78 5f 75 6e 6c 6f 63 6b 20 20 61 73 79 6e 63  ex_unlock  async
5390: 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 0a 23 64  _mutex_unlock.#d
53a0: 65 66 69 6e 65 20 70 74 68 72 65 61 64 5f 6d 75  efine pthread_mu
53b0: 74 65 78 5f 74 72 79 6c 6f 63 6b 20 61 73 79 6e  tex_trylock asyn
53c0: 63 5f 6d 75 74 65 78 5f 74 72 79 6c 6f 63 6b 0a  c_mutex_trylock.
53d0: 23 64 65 66 69 6e 65 20 70 74 68 72 65 61 64 5f  #define pthread_
53e0: 63 6f 6e 64 5f 77 61 69 74 20 20 20 20 20 61 73  cond_wait     as
53f0: 79 6e 63 5f 63 6f 6e 64 5f 77 61 69 74 0a 0a 23  ync_cond_wait..#
5400: 65 6c 73 65 20 20 20 20 2f 2a 20 69 66 20 64 65  else    /* if de
5410: 66 69 6e 65 64 28 4e 44 45 42 55 47 29 20 2a 2f  fined(NDEBUG) */
5420: 0a 0a 23 64 65 66 69 6e 65 20 61 73 73 65 72 74  ..#define assert
5430: 5f 6d 75 74 65 78 5f 69 73 5f 68 65 6c 64 28 58  _mutex_is_held(X
5440: 29 20 20 20 20 2f 2a 20 41 20 6e 6f 2d 6f 70 20  )    /* A no-op 
5450: 77 68 65 6e 20 6e 6f 74 20 64 65 62 75 67 67 69  when not debuggi
5460: 6e 67 20 2a 2f 0a 0a 23 65 6e 64 69 66 20 20 20  ng */..#endif   
5470: 2f 2a 20 21 64 65 66 69 6e 65 64 28 4e 44 45 42  /* !defined(NDEB
5480: 55 47 29 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 64  UG) */../*.** Ad
5490: 64 20 61 6e 20 65 6e 74 72 79 20 74 6f 20 74 68  d an entry to th
54a0: 65 20 65 6e 64 20 6f 66 20 74 68 65 20 67 6c 6f  e end of the glo
54b0: 62 61 6c 20 77 72 69 74 65 2d 6f 70 20 6c 69 73  bal write-op lis
54c0: 74 2e 20 70 57 72 69 74 65 20 73 68 6f 75 6c 64  t. pWrite should
54d0: 20 70 6f 69 6e 74 20 0a 2a 2a 20 74 6f 20 61 6e   point .** to an
54e0: 20 41 73 79 6e 63 57 72 69 74 65 20 73 74 72 75   AsyncWrite stru
54f0: 63 74 75 72 65 20 61 6c 6c 6f 63 61 74 65 64 20  cture allocated 
5500: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 6d 61  using sqlite3_ma
5510: 6c 6c 6f 63 28 29 2e 20 20 54 68 65 20 77 72 69  lloc().  The wri
5520: 74 65 72 0a 2a 2a 20 74 68 72 65 61 64 20 77 69  ter.** thread wi
5530: 6c 6c 20 63 61 6c 6c 20 73 71 6c 69 74 65 33 5f  ll call sqlite3_
5540: 66 72 65 65 28 29 20 74 6f 20 66 72 65 65 20 74  free() to free t
5550: 68 65 20 73 74 72 75 63 74 75 72 65 20 61 66 74  he structure aft
5560: 65 72 20 74 68 65 20 73 70 65 63 69 66 69 65 64  er the specified
5570: 0a 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 20 68 61  .** operation ha
5580: 73 20 62 65 65 6e 20 63 6f 6d 70 6c 65 74 65 64  s been completed
5590: 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 63 65 20 61 6e 20  ..**.** Once an 
55a0: 41 73 79 6e 63 57 72 69 74 65 20 73 74 72 75 63  AsyncWrite struc
55b0: 74 75 72 65 20 68 61 73 20 62 65 65 6e 20 61 64  ture has been ad
55c0: 64 65 64 20 74 6f 20 74 68 65 20 6c 69 73 74 2c  ded to the list,
55d0: 20 69 74 20 62 65 63 6f 6d 65 73 20 74 68 65 0a   it becomes the.
55e0: 2a 2a 20 70 72 6f 70 65 72 74 79 20 6f 66 20 74  ** property of t
55f0: 68 65 20 77 72 69 74 65 72 20 74 68 72 65 61 64  he writer thread
5600: 20 61 6e 64 20 6d 75 73 74 20 6e 6f 74 20 62 65   and must not be
5610: 20 72 65 61 64 20 6f 72 20 6d 6f 64 69 66 69 65   read or modifie
5620: 64 20 62 79 20 74 68 65 0a 2a 2a 20 63 61 6c 6c  d by the.** call
5630: 65 72 2e 20 20 0a 2a 2f 0a 73 74 61 74 69 63 20  er.  .*/.static 
5640: 76 6f 69 64 20 61 64 64 41 73 79 6e 63 57 72 69  void addAsyncWri
5650: 74 65 28 41 73 79 6e 63 57 72 69 74 65 20 2a 70  te(AsyncWrite *p
5660: 57 72 69 74 65 29 7b 0a 20 20 2f 2a 20 57 65 20  Write){.  /* We 
5670: 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20 71 75  must hold the qu
5680: 65 75 65 20 6d 75 74 65 78 20 69 6e 20 6f 72 64  eue mutex in ord
5690: 65 72 20 74 6f 20 6d 6f 64 69 66 79 20 74 68 65  er to modify the
56a0: 20 71 75 65 75 65 20 70 6f 69 6e 74 65 72 73 20   queue pointers 
56b0: 2a 2f 0a 20 20 69 66 28 20 70 57 72 69 74 65 2d  */.  if( pWrite-
56c0: 3e 6f 70 21 3d 41 53 59 4e 43 5f 55 4e 4c 4f 43  >op!=ASYNC_UNLOC
56d0: 4b 20 29 7b 0a 20 20 20 20 70 74 68 72 65 61 64  K ){.    pthread
56e0: 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79  _mutex_lock(&asy
56f0: 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a  nc.queueMutex);.
5700: 20 20 7d 0a 0a 20 20 2f 2a 20 41 64 64 20 74 68    }..  /* Add th
5710: 65 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65 20  e record to the 
5720: 65 6e 64 20 6f 66 20 74 68 65 20 77 72 69 74 65  end of the write
5730: 2d 6f 70 20 71 75 65 75 65 20 2a 2f 0a 20 20 61  -op queue */.  a
5740: 73 73 65 72 74 28 20 21 70 57 72 69 74 65 2d 3e  ssert( !pWrite->
5750: 70 4e 65 78 74 20 29 3b 0a 20 20 69 66 28 20 61  pNext );.  if( a
5760: 73 79 6e 63 2e 70 51 75 65 75 65 4c 61 73 74 20  sync.pQueueLast 
5770: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 61  ){.    assert( a
5780: 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74  sync.pQueueFirst
5790: 20 29 3b 0a 20 20 20 20 61 73 79 6e 63 2e 70 51   );.    async.pQ
57a0: 75 65 75 65 4c 61 73 74 2d 3e 70 4e 65 78 74 20  ueueLast->pNext 
57b0: 3d 20 70 57 72 69 74 65 3b 0a 20 20 7d 65 6c 73  = pWrite;.  }els
57c0: 65 7b 0a 20 20 20 20 61 73 79 6e 63 2e 70 51 75  e{.    async.pQu
57d0: 65 75 65 46 69 72 73 74 20 3d 20 70 57 72 69 74  eueFirst = pWrit
57e0: 65 3b 0a 20 20 7d 0a 20 20 61 73 79 6e 63 2e 70  e;.  }.  async.p
57f0: 51 75 65 75 65 4c 61 73 74 20 3d 20 70 57 72 69  QueueLast = pWri
5800: 74 65 3b 0a 20 20 41 53 59 4e 43 5f 54 52 41 43  te;.  ASYNC_TRAC
5810: 45 28 28 22 50 55 53 48 20 25 70 20 28 25 73 20  E(("PUSH %p (%s 
5820: 25 73 20 25 64 29 5c 6e 22 2c 20 70 57 72 69 74  %s %d)\n", pWrit
5830: 65 2c 20 61 7a 4f 70 63 6f 64 65 4e 61 6d 65 5b  e, azOpcodeName[
5840: 70 57 72 69 74 65 2d 3e 6f 70 5d 2c 0a 20 20 20  pWrite->op],.   
5850: 20 20 20 20 20 20 70 57 72 69 74 65 2d 3e 70 46        pWrite->pF
5860: 69 6c 65 44 61 74 61 20 3f 20 70 57 72 69 74 65  ileData ? pWrite
5870: 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61  ->pFileData->zNa
5880: 6d 65 20 3a 20 22 2d 22 2c 20 70 57 72 69 74 65  me : "-", pWrite
5890: 2d 3e 69 4f 66 66 73 65 74 29 29 3b 0a 0a 20 20  ->iOffset));..  
58a0: 69 66 28 20 70 57 72 69 74 65 2d 3e 6f 70 3d 3d  if( pWrite->op==
58b0: 41 53 59 4e 43 5f 43 4c 4f 53 45 20 29 7b 0a 20  ASYNC_CLOSE ){. 
58c0: 20 20 20 61 73 79 6e 63 2e 6e 46 69 6c 65 2d 2d     async.nFile--
58d0: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 72 6f 70  ;.  }..  /* Drop
58e0: 20 74 68 65 20 71 75 65 75 65 20 6d 75 74 65 78   the queue mutex
58f0: 20 2a 2f 0a 20 20 69 66 28 20 70 57 72 69 74 65   */.  if( pWrite
5900: 2d 3e 6f 70 21 3d 41 53 59 4e 43 5f 55 4e 4c 4f  ->op!=ASYNC_UNLO
5910: 43 4b 20 29 7b 0a 20 20 20 20 70 74 68 72 65 61  CK ){.    pthrea
5920: 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26  d_mutex_unlock(&
5930: 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78  async.queueMutex
5940: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65  );.  }..  /* The
5950: 20 77 72 69 74 65 72 20 74 68 72 65 61 64 20 6d   writer thread m
5960: 69 67 68 74 20 68 61 76 65 20 62 65 65 6e 20 69  ight have been i
5970: 64 6c 65 20 62 65 63 61 75 73 65 20 74 68 65 72  dle because ther
5980: 65 20 77 61 73 20 6e 6f 74 68 69 6e 67 0a 20 20  e was nothing.  
5990: 2a 2a 20 6f 6e 20 74 68 65 20 77 72 69 74 65 2d  ** on the write-
59a0: 6f 70 20 71 75 65 75 65 20 66 6f 72 20 69 74 20  op queue for it 
59b0: 74 6f 20 64 6f 2e 20 20 53 6f 20 77 61 6b 65 20  to do.  So wake 
59c0: 69 74 20 75 70 2e 20 2a 2f 0a 20 20 70 74 68 72  it up. */.  pthr
59d0: 65 61 64 5f 63 6f 6e 64 5f 73 69 67 6e 61 6c 28  ead_cond_signal(
59e0: 26 61 73 79 6e 63 2e 71 75 65 75 65 53 69 67 6e  &async.queueSign
59f0: 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e  al);.}../*.** In
5a00: 63 72 65 6d 65 6e 74 20 61 73 79 6e 63 2e 6e 46  crement async.nF
5a10: 69 6c 65 20 69 6e 20 61 20 74 68 72 65 61 64 2d  ile in a thread-
5a20: 73 61 66 65 20 6d 61 6e 6e 65 72 2e 0a 2a 2f 0a  safe manner..*/.
5a30: 73 74 61 74 69 63 20 76 6f 69 64 20 69 6e 63 72  static void incr
5a40: 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74 28 29 7b  OpenFileCount(){
5a50: 0a 20 20 2f 2a 20 57 65 20 6d 75 73 74 20 68 6f  .  /* We must ho
5a60: 6c 64 20 74 68 65 20 71 75 65 75 65 20 6d 75 74  ld the queue mut
5a70: 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 6d  ex in order to m
5a80: 6f 64 69 66 79 20 61 73 79 6e 63 2e 6e 46 69 6c  odify async.nFil
5a90: 65 20 2a 2f 0a 20 20 70 74 68 72 65 61 64 5f 6d  e */.  pthread_m
5aa0: 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e 63  utex_lock(&async
5ab0: 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20  .queueMutex);.  
5ac0: 69 66 28 20 61 73 79 6e 63 2e 6e 46 69 6c 65 3d  if( async.nFile=
5ad0: 3d 30 20 29 7b 0a 20 20 20 20 61 73 79 6e 63 2e  =0 ){.    async.
5ae0: 69 6f 45 72 72 6f 72 20 3d 20 53 51 4c 49 54 45  ioError = SQLITE
5af0: 5f 4f 4b 3b 0a 20 20 7d 0a 20 20 61 73 79 6e 63  _OK;.  }.  async
5b00: 2e 6e 46 69 6c 65 2b 2b 3b 0a 20 20 70 74 68 72  .nFile++;.  pthr
5b10: 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b  ead_mutex_unlock
5b20: 28 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74  (&async.queueMut
5b30: 65 78 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  ex);.}../*.** Th
5b40: 69 73 20 69 73 20 61 20 75 74 69 6c 69 74 79 20  is is a utility 
5b50: 66 75 6e 63 74 69 6f 6e 20 74 6f 20 61 6c 6c 6f  function to allo
5b60: 63 61 74 65 20 61 6e 64 20 70 6f 70 75 6c 61 74  cate and populat
5b70: 65 20 61 20 6e 65 77 20 41 73 79 6e 63 57 72 69  e a new AsyncWri
5b80: 74 65 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 20  te.** structure 
5b90: 61 6e 64 20 69 6e 73 65 72 74 20 69 74 20 28 76  and insert it (v
5ba0: 69 61 20 61 64 64 41 73 79 6e 63 57 72 69 74 65  ia addAsyncWrite
5bb0: 28 29 20 29 20 69 6e 74 6f 20 74 68 65 20 67 6c  () ) into the gl
5bc0: 6f 62 61 6c 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74  obal list..*/.st
5bd0: 61 74 69 63 20 69 6e 74 20 61 64 64 4e 65 77 41  atic int addNewA
5be0: 73 79 6e 63 57 72 69 74 65 28 0a 20 20 41 73 79  syncWrite(.  Asy
5bf0: 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 46 69 6c  ncFileData *pFil
5c00: 65 44 61 74 61 2c 20 0a 20 20 69 6e 74 20 6f 70  eData, .  int op
5c10: 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  , .  sqlite3_int
5c20: 36 34 20 69 4f 66 66 73 65 74 2c 20 0a 20 20 69  64 iOffset, .  i
5c30: 6e 74 20 6e 42 79 74 65 2c 0a 20 20 63 6f 6e 73  nt nByte,.  cons
5c40: 74 20 63 68 61 72 20 2a 7a 42 79 74 65 0a 29 7b  t char *zByte.){
5c50: 0a 20 20 41 73 79 6e 63 57 72 69 74 65 20 2a 70  .  AsyncWrite *p
5c60: 3b 0a 20 20 69 66 28 20 6f 70 21 3d 41 53 59 4e  ;.  if( op!=ASYN
5c70: 43 5f 43 4c 4f 53 45 20 26 26 20 61 73 79 6e 63  C_CLOSE && async
5c80: 2e 69 6f 45 72 72 6f 72 20 29 7b 0a 20 20 20 20  .ioError ){.    
5c90: 72 65 74 75 72 6e 20 61 73 79 6e 63 2e 69 6f 45  return async.ioE
5ca0: 72 72 6f 72 3b 0a 20 20 7d 0a 20 20 70 20 3d 20  rror;.  }.  p = 
5cb0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
5cc0: 69 7a 65 6f 66 28 41 73 79 6e 63 57 72 69 74 65  izeof(AsyncWrite
5cd0: 29 20 2b 20 28 7a 42 79 74 65 3f 6e 42 79 74 65  ) + (zByte?nByte
5ce0: 3a 30 29 29 3b 0a 20 20 69 66 28 20 21 70 20 29  :0));.  if( !p )
5cf0: 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 75 70 70  {.    /* The upp
5d00: 65 72 20 6c 61 79 65 72 20 64 6f 65 73 20 6e 6f  er layer does no
5d10: 74 20 65 78 70 65 63 74 20 6f 70 65 72 61 74 69  t expect operati
5d20: 6f 6e 73 20 6c 69 6b 65 20 4f 73 57 72 69 74 65  ons like OsWrite
5d30: 28 29 20 74 6f 0a 20 20 20 20 2a 2a 20 72 65 74  () to.    ** ret
5d40: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
5d50: 2e 20 54 68 69 73 20 69 73 20 70 61 72 74 6c 79  . This is partly
5d60: 20 62 65 63 61 75 73 65 20 75 6e 64 65 72 20 6e   because under n
5d70: 6f 72 6d 61 6c 20 63 6f 6e 64 69 74 69 6f 6e 73  ormal conditions
5d80: 0a 20 20 20 20 2a 2a 20 53 51 4c 69 74 65 20 69  .    ** SQLite i
5d90: 73 20 72 65 71 75 69 72 65 64 20 74 6f 20 64 6f  s required to do
5da0: 20 72 6f 6c 6c 62 61 63 6b 20 77 69 74 68 6f 75   rollback withou
5db0: 74 20 63 61 6c 6c 69 6e 67 20 6d 61 6c 6c 6f 63  t calling malloc
5dc0: 28 29 2e 20 53 6f 0a 20 20 20 20 2a 2a 20 69 66  (). So.    ** if
5dd0: 20 6d 61 6c 6c 6f 63 28 29 20 66 61 69 6c 73 20   malloc() fails 
5de0: 68 65 72 65 2c 20 74 72 65 61 74 20 69 74 20 61  here, treat it a
5df0: 73 20 61 6e 20 49 2f 4f 20 65 72 72 6f 72 2e 20  s an I/O error. 
5e00: 54 68 65 20 61 62 6f 76 65 0a 20 20 20 20 2a 2a  The above.    **
5e10: 20 6c 61 79 65 72 20 6b 6e 6f 77 73 20 68 6f 77   layer knows how
5e20: 20 74 6f 20 68 61 6e 64 6c 65 20 74 68 61 74 2e   to handle that.
5e30: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 65 74 75  .    */.    retu
5e40: 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b  rn SQLITE_IOERR;
5e50: 0a 20 20 7d 0a 20 20 70 2d 3e 6f 70 20 3d 20 6f  .  }.  p->op = o
5e60: 70 3b 0a 20 20 70 2d 3e 69 4f 66 66 73 65 74 20  p;.  p->iOffset 
5e70: 3d 20 69 4f 66 66 73 65 74 3b 0a 20 20 70 2d 3e  = iOffset;.  p->
5e80: 6e 42 79 74 65 20 3d 20 6e 42 79 74 65 3b 0a 20  nByte = nByte;. 
5e90: 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 20 3d 20   p->pFileData = 
5ea0: 70 46 69 6c 65 44 61 74 61 3b 0a 20 20 70 2d 3e  pFileData;.  p->
5eb0: 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 69 66 28  pNext = 0;.  if(
5ec0: 20 7a 42 79 74 65 20 29 7b 0a 20 20 20 20 70 2d   zByte ){.    p-
5ed0: 3e 7a 42 75 66 20 3d 20 28 63 68 61 72 20 2a 29  >zBuf = (char *)
5ee0: 26 70 5b 31 5d 3b 0a 20 20 20 20 6d 65 6d 63 70  &p[1];.    memcp
5ef0: 79 28 70 2d 3e 7a 42 75 66 2c 20 7a 42 79 74 65  y(p->zBuf, zByte
5f00: 2c 20 6e 42 79 74 65 29 3b 0a 20 20 7d 65 6c 73  , nByte);.  }els
5f10: 65 7b 0a 20 20 20 20 70 2d 3e 7a 42 75 66 20 3d  e{.    p->zBuf =
5f20: 20 30 3b 0a 20 20 7d 0a 20 20 61 64 64 41 73 79   0;.  }.  addAsy
5f30: 6e 63 57 72 69 74 65 28 70 29 3b 0a 20 20 72 65  ncWrite(p);.  re
5f40: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
5f50: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74  }../*.** Close t
5f60: 68 65 20 66 69 6c 65 2e 20 54 68 69 73 20 6a 75  he file. This ju
5f70: 73 74 20 61 64 64 73 20 61 6e 20 65 6e 74 72 79  st adds an entry
5f80: 20 74 6f 20 74 68 65 20 77 72 69 74 65 2d 6f 70   to the write-op
5f90: 20 6c 69 73 74 2c 20 74 68 65 20 66 69 6c 65 20   list, the file 
5fa0: 69 73 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61 6c  is.** not actual
5fb0: 6c 79 20 63 6c 6f 73 65 64 2e 0a 2a 2f 0a 73 74  ly closed..*/.st
5fc0: 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 43 6c  atic int asyncCl
5fd0: 6f 73 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ose(sqlite3_file
5fe0: 20 2a 70 46 69 6c 65 29 7b 0a 20 20 41 73 79 6e   *pFile){.  Asyn
5ff0: 63 46 69 6c 65 44 61 74 61 20 2a 70 20 3d 20 28  cFileData *p = (
6000: 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 70 46 69  (AsyncFile *)pFi
6010: 6c 65 29 2d 3e 70 44 61 74 61 3b 0a 0a 20 20 2f  le)->pData;..  /
6020: 2a 20 55 6e 6c 6f 63 6b 20 74 68 65 20 66 69 6c  * Unlock the fil
6030: 65 2c 20 69 66 20 69 74 20 69 73 20 6c 6f 63 6b  e, if it is lock
6040: 65 64 20 2a 2f 0a 20 20 70 74 68 72 65 61 64 5f  ed */.  pthread_
6050: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e  mutex_lock(&asyn
6060: 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20 20  c.lockMutex);.  
6070: 70 2d 3e 6c 6f 63 6b 2e 65 4c 6f 63 6b 20 3d 20  p->lock.eLock = 
6080: 30 3b 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74  0;.  pthread_mut
6090: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63  ex_unlock(&async
60a0: 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 0a 20 20  .lockMutex);..  
60b0: 61 64 64 41 73 79 6e 63 57 72 69 74 65 28 26 70  addAsyncWrite(&p
60c0: 2d 3e 63 6c 6f 73 65 4f 70 29 3b 0a 20 20 72 65  ->closeOp);.  re
60d0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
60e0: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
60f0: 6e 74 61 74 69 6f 6e 20 6f 66 20 73 71 6c 69 74  ntation of sqlit
6100: 65 33 4f 73 57 72 69 74 65 28 29 20 66 6f 72 20  e3OsWrite() for 
6110: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 66 69 6c  asynchronous fil
6120: 65 73 2e 20 49 6e 73 74 65 61 64 20 6f 66 20 0a  es. Instead of .
6130: 2a 2a 20 77 72 69 74 69 6e 67 20 74 6f 20 74 68  ** writing to th
6140: 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 66 69 6c  e underlying fil
6150: 65 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  e, this function
6160: 20 61 64 64 73 20 61 6e 20 65 6e 74 72 79 20 74   adds an entry t
6170: 6f 20 74 68 65 20 65 6e 64 20 6f 66 0a 2a 2a 20  o the end of.** 
6180: 74 68 65 20 67 6c 6f 62 61 6c 20 41 73 79 6e 63  the global Async
6190: 57 72 69 74 65 20 6c 69 73 74 2e 20 45 69 74 68  Write list. Eith
61a0: 65 72 20 53 51 4c 49 54 45 5f 4f 4b 20 6f 72 20  er SQLITE_OK or 
61b0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 6d 61 79  SQLITE_NOMEM may
61c0: 20 62 65 0a 2a 2a 20 72 65 74 75 72 6e 65 64 2e   be.** returned.
61d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .*/.static int a
61e0: 73 79 6e 63 57 72 69 74 65 28 0a 20 20 73 71 6c  syncWrite(.  sql
61f0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
6200: 2c 20 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20  , .  const void 
6210: 2a 70 42 75 66 2c 20 0a 20 20 69 6e 74 20 61 6d  *pBuf, .  int am
6220: 74 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e  t, .  sqlite3_in
6230: 74 36 34 20 69 4f 66 66 0a 29 7b 0a 20 20 41 73  t64 iOff.){.  As
6240: 79 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 20 3d  yncFileData *p =
6250: 20 28 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 70   ((AsyncFile *)p
6260: 46 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a 20 20  File)->pData;.  
6270: 72 65 74 75 72 6e 20 61 64 64 4e 65 77 41 73 79  return addNewAsy
6280: 6e 63 57 72 69 74 65 28 70 2c 20 41 53 59 4e 43  ncWrite(p, ASYNC
6290: 5f 57 52 49 54 45 2c 20 69 4f 66 66 2c 20 61 6d  _WRITE, iOff, am
62a0: 74 2c 20 70 42 75 66 29 3b 0a 7d 0a 0a 2f 2a 0a  t, pBuf);.}../*.
62b0: 2a 2a 20 52 65 61 64 20 64 61 74 61 20 66 72 6f  ** Read data fro
62c0: 6d 20 74 68 65 20 66 69 6c 65 2e 20 46 69 72 73  m the file. Firs
62d0: 74 20 77 65 20 72 65 61 64 20 66 72 6f 6d 20 74  t we read from t
62e0: 68 65 20 66 69 6c 65 73 79 73 74 65 6d 2c 20 74  he filesystem, t
62f0: 68 65 6e 20 61 64 6a 75 73 74 20 0a 2a 2a 20 74  hen adjust .** t
6300: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
6310: 68 65 20 62 75 66 66 65 72 20 62 61 73 65 64 20  he buffer based 
6320: 6f 6e 20 41 53 59 4e 43 5f 57 52 49 54 45 20 6f  on ASYNC_WRITE o
6330: 70 65 72 61 74 69 6f 6e 73 20 69 6e 20 74 68 65  perations in the
6340: 20 0a 2a 2a 20 77 72 69 74 65 2d 6f 70 20 71 75   .** write-op qu
6350: 65 75 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  eue..**.** This 
6360: 6d 65 74 68 6f 64 20 68 6f 6c 64 73 20 74 68 65  method holds the
6370: 20 6d 75 74 65 78 20 66 72 6f 6d 20 73 74 61 72   mutex from star
6380: 74 20 74 6f 20 66 69 6e 69 73 68 2e 0a 2a 2f 0a  t to finish..*/.
6390: 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63  static int async
63a0: 52 65 61 64 28 0a 20 20 73 71 6c 69 74 65 33 5f  Read(.  sqlite3_
63b0: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 0a 20 20  file *pFile, .  
63c0: 76 6f 69 64 20 2a 7a 4f 75 74 2c 20 0a 20 20 69  void *zOut, .  i
63d0: 6e 74 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69  nt iAmt, .  sqli
63e0: 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 66 73 65  te3_int64 iOffse
63f0: 74 0a 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65  t.){.  AsyncFile
6400: 44 61 74 61 20 2a 70 20 3d 20 28 28 41 73 79 6e  Data *p = ((Asyn
6410: 63 46 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d 3e  cFile *)pFile)->
6420: 70 44 61 74 61 3b 0a 20 20 69 6e 74 20 72 63 20  pData;.  int rc 
6430: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 73  = SQLITE_OK;.  s
6440: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 66 69 6c  qlite3_int64 fil
6450: 65 73 69 7a 65 3b 0a 20 20 69 6e 74 20 6e 52 65  esize;.  int nRe
6460: 61 64 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  ad;.  sqlite3_fi
6470: 6c 65 20 2a 70 42 61 73 65 20 3d 20 70 2d 3e 70  le *pBase = p->p
6480: 42 61 73 65 52 65 61 64 3b 0a 0a 20 20 2f 2a 20  BaseRead;..  /* 
6490: 47 72 61 62 20 74 68 65 20 77 72 69 74 65 20 71  Grab the write q
64a0: 75 65 75 65 20 6d 75 74 65 78 20 66 6f 72 20 74  ueue mutex for t
64b0: 68 65 20 64 75 72 61 74 69 6f 6e 20 6f 66 20 74  he duration of t
64c0: 68 65 20 63 61 6c 6c 20 2a 2f 0a 20 20 70 74 68  he call */.  pth
64d0: 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28  read_mutex_lock(
64e0: 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65  &async.queueMute
64f0: 78 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e 20  x);..  /* If an 
6500: 49 2f 4f 20 65 72 72 6f 72 20 68 61 73 20 70 72  I/O error has pr
6510: 65 76 69 6f 75 73 6c 79 20 6f 63 63 75 72 72 65  eviously occurre
6520: 64 20 69 6e 20 74 68 69 73 20 76 69 72 74 75 61  d in this virtua
6530: 6c 20 66 69 6c 65 20 0a 20 20 2a 2a 20 73 79 73  l file .  ** sys
6540: 74 65 6d 2c 20 74 68 65 6e 20 61 6c 6c 20 73 75  tem, then all su
6550: 62 73 65 71 75 65 6e 74 20 6f 70 65 72 61 74 69  bsequent operati
6560: 6f 6e 73 20 66 61 69 6c 2e 0a 20 20 2a 2f 0a 20  ons fail..  */. 
6570: 20 69 66 28 20 61 73 79 6e 63 2e 69 6f 45 72 72   if( async.ioErr
6580: 6f 72 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  or!=SQLITE_OK ){
6590: 0a 20 20 20 20 72 63 20 3d 20 61 73 79 6e 63 2e  .    rc = async.
65a0: 69 6f 45 72 72 6f 72 3b 0a 20 20 20 20 67 6f 74  ioError;.    got
65b0: 6f 20 61 73 79 6e 63 72 65 61 64 5f 6f 75 74 3b  o asyncread_out;
65c0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 42 61 73  .  }..  if( pBas
65d0: 65 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b 0a 20  e->pMethods ){. 
65e0: 20 20 20 72 63 20 3d 20 70 42 61 73 65 2d 3e 70     rc = pBase->p
65f0: 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53 69  Methods->xFileSi
6600: 7a 65 28 70 42 61 73 65 2c 20 26 66 69 6c 65 73  ze(pBase, &files
6610: 69 7a 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ize);.    if( rc
6620: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
6630: 20 20 20 20 20 67 6f 74 6f 20 61 73 79 6e 63 72       goto asyncr
6640: 65 61 64 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20  ead_out;.    }. 
6650: 20 20 20 6e 52 65 61 64 20 3d 20 4d 49 4e 28 66     nRead = MIN(f
6660: 69 6c 65 73 69 7a 65 20 2d 20 69 4f 66 66 73 65  ilesize - iOffse
6670: 74 2c 20 69 41 6d 74 29 3b 0a 20 20 20 20 69 66  t, iAmt);.    if
6680: 28 20 6e 52 65 61 64 3e 30 20 29 7b 0a 20 20 20  ( nRead>0 ){.   
6690: 20 20 20 72 63 20 3d 20 70 42 61 73 65 2d 3e 70     rc = pBase->p
66a0: 4d 65 74 68 6f 64 73 2d 3e 78 52 65 61 64 28 70  Methods->xRead(p
66b0: 42 61 73 65 2c 20 7a 4f 75 74 2c 20 6e 52 65 61  Base, zOut, nRea
66c0: 64 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20  d, iOffset);.   
66d0: 20 20 20 41 53 59 4e 43 5f 54 52 41 43 45 28 28     ASYNC_TRACE((
66e0: 22 52 45 41 44 20 25 73 20 25 64 20 62 79 74 65  "READ %s %d byte
66f0: 73 20 61 74 20 25 64 5c 6e 22 2c 20 70 2d 3e 7a  s at %d\n", p->z
6700: 4e 61 6d 65 2c 20 6e 52 65 61 64 2c 20 69 4f 66  Name, nRead, iOf
6710: 66 73 65 74 29 29 3b 0a 20 20 20 20 7d 0a 20 20  fset));.    }.  
6720: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
6730: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 41 73  ITE_OK ){.    As
6740: 79 6e 63 57 72 69 74 65 20 2a 70 57 72 69 74 65  yncWrite *pWrite
6750: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d  ;.    char *zNam
6760: 65 20 3d 20 70 2d 3e 7a 4e 61 6d 65 3b 0a 0a 20  e = p->zName;.. 
6770: 20 20 20 66 6f 72 28 70 57 72 69 74 65 3d 61 73     for(pWrite=as
6780: 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74 3b  ync.pQueueFirst;
6790: 20 70 57 72 69 74 65 3b 20 70 57 72 69 74 65 20   pWrite; pWrite 
67a0: 3d 20 70 57 72 69 74 65 2d 3e 70 4e 65 78 74 29  = pWrite->pNext)
67b0: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 57 72 69  {.      if( pWri
67c0: 74 65 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f 57 52  te->op==ASYNC_WR
67d0: 49 54 45 20 26 26 20 28 0a 20 20 20 20 20 20 20  ITE && (.       
67e0: 20 28 70 57 72 69 74 65 2d 3e 70 46 69 6c 65 44   (pWrite->pFileD
67f0: 61 74 61 3d 3d 70 29 20 7c 7c 0a 20 20 20 20 20  ata==p) ||.     
6800: 20 20 20 28 7a 4e 61 6d 65 20 26 26 20 70 57 72     (zName && pWr
6810: 69 74 65 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e  ite->pFileData->
6820: 7a 4e 61 6d 65 3d 3d 7a 4e 61 6d 65 29 0a 20 20  zName==zName).  
6830: 20 20 20 20 29 29 7b 0a 20 20 20 20 20 20 20 20      )){.        
6840: 69 6e 74 20 69 42 65 67 69 6e 4f 75 74 20 3d 20  int iBeginOut = 
6850: 28 70 57 72 69 74 65 2d 3e 69 4f 66 66 73 65 74  (pWrite->iOffset
6860: 2d 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20  -iOffset);.     
6870: 20 20 20 69 6e 74 20 69 42 65 67 69 6e 49 6e 20     int iBeginIn 
6880: 3d 20 2d 69 42 65 67 69 6e 4f 75 74 3b 0a 20 20  = -iBeginOut;.  
6890: 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 3b        int nCopy;
68a0: 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 42  ..        if( iB
68b0: 65 67 69 6e 49 6e 3c 30 20 29 20 69 42 65 67 69  eginIn<0 ) iBegi
68c0: 6e 49 6e 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  nIn = 0;.       
68d0: 20 69 66 28 20 69 42 65 67 69 6e 4f 75 74 3c 30   if( iBeginOut<0
68e0: 20 29 20 69 42 65 67 69 6e 4f 75 74 20 3d 20 30   ) iBeginOut = 0
68f0: 3b 0a 20 20 20 20 20 20 20 20 6e 43 6f 70 79 20  ;.        nCopy 
6900: 3d 20 4d 49 4e 28 70 57 72 69 74 65 2d 3e 6e 42  = MIN(pWrite->nB
6910: 79 74 65 2d 69 42 65 67 69 6e 49 6e 2c 20 69 41  yte-iBeginIn, iA
6920: 6d 74 2d 69 42 65 67 69 6e 4f 75 74 29 3b 0a 0a  mt-iBeginOut);..
6930: 20 20 20 20 20 20 20 20 69 66 28 20 6e 43 6f 70          if( nCop
6940: 79 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  y>0 ){.         
6950: 20 6d 65 6d 63 70 79 28 26 28 28 63 68 61 72 20   memcpy(&((char 
6960: 2a 29 7a 4f 75 74 29 5b 69 42 65 67 69 6e 4f 75  *)zOut)[iBeginOu
6970: 74 5d 2c 20 26 70 57 72 69 74 65 2d 3e 7a 42 75  t], &pWrite->zBu
6980: 66 5b 69 42 65 67 69 6e 49 6e 5d 2c 20 6e 43 6f  f[iBeginIn], nCo
6990: 70 79 29 3b 0a 20 20 20 20 20 20 20 20 20 20 41  py);.          A
69a0: 53 59 4e 43 5f 54 52 41 43 45 28 28 22 4f 56 45  SYNC_TRACE(("OVE
69b0: 52 52 45 41 44 20 25 64 20 62 79 74 65 73 20 61  RREAD %d bytes a
69c0: 74 20 25 64 5c 6e 22 2c 20 6e 43 6f 70 79 2c 20  t %d\n", nCopy, 
69d0: 69 42 65 67 69 6e 4f 75 74 2b 69 4f 66 66 73 65  iBeginOut+iOffse
69e0: 74 29 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  t));.        }. 
69f0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
6a00: 0a 0a 61 73 79 6e 63 72 65 61 64 5f 6f 75 74 3a  ..asyncread_out:
6a10: 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78  .  pthread_mutex
6a20: 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 71  _unlock(&async.q
6a30: 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20 72 65  ueueMutex);.  re
6a40: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
6a50: 2a 20 54 72 75 6e 63 61 74 65 20 74 68 65 20 66  * Truncate the f
6a60: 69 6c 65 20 74 6f 20 6e 42 79 74 65 20 62 79 74  ile to nByte byt
6a70: 65 73 20 69 6e 20 6c 65 6e 67 74 68 2e 20 54 68  es in length. Th
6a80: 69 73 20 6a 75 73 74 20 61 64 64 73 20 61 6e 20  is just adds an 
6a90: 65 6e 74 72 79 20 74 6f 20 0a 2a 2a 20 74 68 65  entry to .** the
6aa0: 20 77 72 69 74 65 2d 6f 70 20 6c 69 73 74 2c 20   write-op list, 
6ab0: 6e 6f 20 49 4f 20 61 63 74 75 61 6c 6c 79 20 74  no IO actually t
6ac0: 61 6b 65 73 20 70 6c 61 63 65 2e 0a 2a 2f 0a 73  akes place..*/.s
6ad0: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 54  tatic int asyncT
6ae0: 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f  runcate(sqlite3_
6af0: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73 71 6c  file *pFile, sql
6b00: 69 74 65 33 5f 69 6e 74 36 34 20 6e 42 79 74 65  ite3_int64 nByte
6b10: 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 44 61  ){.  AsyncFileDa
6b20: 74 61 20 2a 70 20 3d 20 28 28 41 73 79 6e 63 46  ta *p = ((AsyncF
6b30: 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d 3e 70 44  ile *)pFile)->pD
6b40: 61 74 61 3b 0a 20 20 72 65 74 75 72 6e 20 61 64  ata;.  return ad
6b50: 64 4e 65 77 41 73 79 6e 63 57 72 69 74 65 28 70  dNewAsyncWrite(p
6b60: 2c 20 41 53 59 4e 43 5f 54 52 55 4e 43 41 54 45  , ASYNC_TRUNCATE
6b70: 2c 20 6e 42 79 74 65 2c 20 30 2c 20 30 29 3b 0a  , nByte, 0, 0);.
6b80: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 74 68  }../*.** Sync th
6b90: 65 20 66 69 6c 65 2e 20 54 68 69 73 20 6a 75 73  e file. This jus
6ba0: 74 20 61 64 64 73 20 61 6e 20 65 6e 74 72 79 20  t adds an entry 
6bb0: 74 6f 20 74 68 65 20 77 72 69 74 65 2d 6f 70 20  to the write-op 
6bc0: 6c 69 73 74 2c 20 74 68 65 20 0a 2a 2a 20 73 79  list, the .** sy
6bd0: 6e 63 28 29 20 69 73 20 64 6f 6e 65 20 6c 61 74  nc() is done lat
6be0: 65 72 20 62 79 20 73 71 6c 69 74 65 33 5f 61 73  er by sqlite3_as
6bf0: 79 6e 63 5f 66 6c 75 73 68 28 29 2e 0a 2a 2f 0a  ync_flush()..*/.
6c00: 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63  static int async
6c10: 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 66 69 6c  Sync(sqlite3_fil
6c20: 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 66 6c  e *pFile, int fl
6c30: 61 67 73 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c  ags){.  AsyncFil
6c40: 65 44 61 74 61 20 2a 70 20 3d 20 28 28 41 73 79  eData *p = ((Asy
6c50: 6e 63 46 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d  ncFile *)pFile)-
6c60: 3e 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72 6e  >pData;.  return
6c70: 20 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69 74   addNewAsyncWrit
6c80: 65 28 70 2c 20 41 53 59 4e 43 5f 53 59 4e 43 2c  e(p, ASYNC_SYNC,
6c90: 20 30 2c 20 66 6c 61 67 73 2c 20 30 29 3b 0a 7d   0, flags, 0);.}
6ca0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 74 68 65  ../*.** Read the
6cb0: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c   size of the fil
6cc0: 65 2e 20 46 69 72 73 74 20 77 65 20 72 65 61 64  e. First we read
6cd0: 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
6ce0: 20 66 69 6c 65 20 73 79 73 74 65 6d 20 0a 2a 2a   file system .**
6cf0: 20 65 6e 74 72 79 2c 20 74 68 65 6e 20 61 64 6a   entry, then adj
6d00: 75 73 74 20 66 6f 72 20 61 6e 79 20 41 53 59 4e  ust for any ASYN
6d10: 43 5f 57 52 49 54 45 20 6f 72 20 41 53 59 4e 43  C_WRITE or ASYNC
6d20: 5f 54 52 55 4e 43 41 54 45 20 6f 70 65 72 61 74  _TRUNCATE operat
6d30: 69 6f 6e 73 20 0a 2a 2a 20 63 75 72 72 65 6e 74  ions .** current
6d40: 6c 79 20 69 6e 20 74 68 65 20 77 72 69 74 65 2d  ly in the write-
6d50: 6f 70 20 6c 69 73 74 2e 20 0a 2a 2a 0a 2a 2a 20  op list. .**.** 
6d60: 54 68 69 73 20 6d 65 74 68 6f 64 20 68 6f 6c 64  This method hold
6d70: 73 20 74 68 65 20 6d 75 74 65 78 20 66 72 6f 6d  s the mutex from
6d80: 20 73 74 61 72 74 20 74 6f 20 66 69 6e 69 73 68   start to finish
6d90: 2e 0a 2a 2f 0a 69 6e 74 20 61 73 79 6e 63 46 69  ..*/.int asyncFi
6da0: 6c 65 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66  leSize(sqlite3_f
6db0: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73 71 6c 69  ile *pFile, sqli
6dc0: 74 65 33 5f 69 6e 74 36 34 20 2a 70 69 53 69 7a  te3_int64 *piSiz
6dd0: 65 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 44  e){.  AsyncFileD
6de0: 61 74 61 20 2a 70 20 3d 20 28 28 41 73 79 6e 63  ata *p = ((Async
6df0: 46 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d 3e 70  File *)pFile)->p
6e00: 44 61 74 61 3b 0a 20 20 69 6e 74 20 72 63 20 3d  Data;.  int rc =
6e10: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 73 71   SQLITE_OK;.  sq
6e20: 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 20 3d 20  lite3_int64 s = 
6e30: 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  0;.  sqlite3_fil
6e40: 65 20 2a 70 42 61 73 65 3b 0a 0a 20 20 70 74 68  e *pBase;..  pth
6e50: 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28  read_mutex_lock(
6e60: 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65  &async.queueMute
6e70: 78 29 3b 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74  x);..  /* Read t
6e80: 68 65 20 66 69 6c 65 73 79 73 74 65 6d 20 73 69  he filesystem si
6e90: 7a 65 20 66 72 6f 6d 20 74 68 65 20 62 61 73 65  ze from the base
6ea0: 20 66 69 6c 65 2e 20 49 66 20 70 42 61 73 65 52   file. If pBaseR
6eb0: 65 61 64 20 69 73 20 4e 55 4c 4c 2c 20 74 68 69  ead is NULL, thi
6ec0: 73 0a 20 20 2a 2a 20 6d 65 61 6e 73 20 74 68 65  s.  ** means the
6ed0: 20 66 69 6c 65 20 68 61 73 6e 27 74 20 62 65 65   file hasn't bee
6ee0: 6e 20 6f 70 65 6e 65 64 20 79 65 74 2e 20 49 6e  n opened yet. In
6ef0: 20 74 68 69 73 20 63 61 73 65 20 61 6c 6c 20 72   this case all r
6f00: 65 6c 65 76 61 6e 74 20 64 61 74 61 20 0a 20 20  elevant data .  
6f10: 2a 2a 20 6d 75 73 74 20 62 65 20 69 6e 20 74 68  ** must be in th
6f20: 65 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75 65  e write-op queue
6f30: 20 61 6e 79 77 61 79 2c 20 73 6f 20 77 65 20 63   anyway, so we c
6f40: 61 6e 20 6f 6d 69 74 20 72 65 61 64 69 6e 67 20  an omit reading 
6f50: 66 72 6f 6d 20 74 68 65 0a 20 20 2a 2a 20 66 69  from the.  ** fi
6f60: 6c 65 2d 73 79 73 74 65 6d 2e 0a 20 20 2a 2f 0a  le-system..  */.
6f70: 20 20 70 42 61 73 65 20 3d 20 70 2d 3e 70 42 61    pBase = p->pBa
6f80: 73 65 52 65 61 64 3b 0a 20 20 69 66 28 20 70 42  seRead;.  if( pB
6f90: 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b  ase->pMethods ){
6fa0: 0a 20 20 20 20 72 63 20 3d 20 70 42 61 73 65 2d  .    rc = pBase-
6fb0: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65  >pMethods->xFile
6fc0: 53 69 7a 65 28 70 42 61 73 65 2c 20 26 73 29 3b  Size(pBase, &s);
6fd0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
6fe0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
6ff0: 20 41 73 79 6e 63 57 72 69 74 65 20 2a 70 57 72   AsyncWrite *pWr
7000: 69 74 65 3b 0a 20 20 20 20 66 6f 72 28 70 57 72  ite;.    for(pWr
7010: 69 74 65 3d 61 73 79 6e 63 2e 70 51 75 65 75 65  ite=async.pQueue
7020: 46 69 72 73 74 3b 20 70 57 72 69 74 65 3b 20 70  First; pWrite; p
7030: 57 72 69 74 65 20 3d 20 70 57 72 69 74 65 2d 3e  Write = pWrite->
7040: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 69 66  pNext){.      if
7050: 28 20 70 57 72 69 74 65 2d 3e 6f 70 3d 3d 41 53  ( pWrite->op==AS
7060: 59 4e 43 5f 44 45 4c 45 54 45 20 0a 20 20 20 20  YNC_DELETE .    
7070: 20 20 20 26 26 20 70 2d 3e 7a 4e 61 6d 65 20 0a     && p->zName .
7080: 20 20 20 20 20 20 20 26 26 20 73 74 72 63 6d 70         && strcmp
7090: 28 70 2d 3e 7a 4e 61 6d 65 2c 20 70 57 72 69 74  (p->zName, pWrit
70a0: 65 2d 3e 7a 42 75 66 29 3d 3d 30 20 0a 20 20 20  e->zBuf)==0 .   
70b0: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 73 20     ){.        s 
70c0: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  = 0;.      }else
70d0: 20 69 66 28 20 70 57 72 69 74 65 2d 3e 70 46 69   if( pWrite->pFi
70e0: 6c 65 44 61 74 61 20 26 26 20 28 0a 20 20 20 20  leData && (.    
70f0: 20 20 20 20 20 20 28 70 57 72 69 74 65 2d 3e 70        (pWrite->p
7100: 46 69 6c 65 44 61 74 61 3d 3d 70 29 20 0a 20 20  FileData==p) .  
7110: 20 20 20 20 20 7c 7c 20 28 70 2d 3e 7a 4e 61 6d       || (p->zNam
7120: 65 20 26 26 20 70 57 72 69 74 65 2d 3e 70 46 69  e && pWrite->pFi
7130: 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65 3d 3d 70  leData->zName==p
7140: 2d 3e 7a 4e 61 6d 65 29 20 0a 20 20 20 20 20 20  ->zName) .      
7150: 29 29 7b 0a 20 20 20 20 20 20 20 20 73 77 69 74  )){.        swit
7160: 63 68 28 20 70 57 72 69 74 65 2d 3e 6f 70 20 29  ch( pWrite->op )
7170: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 61 73 65  {.          case
7180: 20 41 53 59 4e 43 5f 57 52 49 54 45 3a 0a 20 20   ASYNC_WRITE:.  
7190: 20 20 20 20 20 20 20 20 20 20 73 20 3d 20 4d 41            s = MA
71a0: 58 28 70 57 72 69 74 65 2d 3e 69 4f 66 66 73 65  X(pWrite->iOffse
71b0: 74 20 2b 20 28 73 71 6c 69 74 65 33 5f 69 6e 74  t + (sqlite3_int
71c0: 36 34 29 28 70 57 72 69 74 65 2d 3e 6e 42 79 74  64)(pWrite->nByt
71d0: 65 29 2c 20 73 29 3b 0a 20 20 20 20 20 20 20 20  e), s);.        
71e0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
71f0: 20 20 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f       case ASYNC_
7200: 54 52 55 4e 43 41 54 45 3a 0a 20 20 20 20 20 20  TRUNCATE:.      
7210: 20 20 20 20 20 20 73 20 3d 20 4d 49 4e 28 73 2c        s = MIN(s,
7220: 20 70 57 72 69 74 65 2d 3e 69 4f 66 66 73 65 74   pWrite->iOffset
7230: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 62  );.            b
7240: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a  reak;.        }.
7250: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
7260: 20 20 2a 70 69 53 69 7a 65 20 3d 20 73 3b 0a 20    *piSize = s;. 
7270: 20 7d 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74   }.  pthread_mut
7280: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63  ex_unlock(&async
7290: 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20  .queueMutex);.  
72a0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
72b0: 0a 2a 2a 20 4c 6f 63 6b 20 6f 72 20 75 6e 6c 6f  .** Lock or unlo
72c0: 63 6b 20 74 68 65 20 61 63 74 75 61 6c 20 66 69  ck the actual fi
72d0: 6c 65 2d 73 79 73 74 65 6d 20 65 6e 74 72 79 2e  le-system entry.
72e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67  .*/.static int g
72f0: 65 74 46 69 6c 65 4c 6f 63 6b 28 41 73 79 6e 63  etFileLock(Async
7300: 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 29 7b 0a 20 20  Lock *pLock){.  
7310: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
7320: 4f 4b 3b 0a 20 20 41 73 79 6e 63 46 69 6c 65 4c  OK;.  AsyncFileL
7330: 6f 63 6b 20 2a 70 49 74 65 72 3b 0a 20 20 69 6e  ock *pIter;.  in
7340: 74 20 65 52 65 71 75 69 72 65 64 20 3d 20 30 3b  t eRequired = 0;
7350: 0a 0a 20 20 69 66 28 20 70 4c 6f 63 6b 2d 3e 70  ..  if( pLock->p
7360: 46 69 6c 65 20 29 7b 0a 20 20 20 20 66 6f 72 28  File ){.    for(
7370: 70 49 74 65 72 3d 70 4c 6f 63 6b 2d 3e 70 4c 69  pIter=pLock->pLi
7380: 73 74 3b 20 70 49 74 65 72 3b 20 70 49 74 65 72  st; pIter; pIter
7390: 3d 70 49 74 65 72 2d 3e 70 4e 65 78 74 29 7b 0a  =pIter->pNext){.
73a0: 20 20 20 20 20 20 61 73 73 65 72 74 28 70 49 74        assert(pIt
73b0: 65 72 2d 3e 65 41 73 79 6e 63 4c 6f 63 6b 3e 3d  er->eAsyncLock>=
73c0: 70 49 74 65 72 2d 3e 65 4c 6f 63 6b 29 3b 0a 20  pIter->eLock);. 
73d0: 20 20 20 20 20 69 66 28 20 70 49 74 65 72 2d 3e       if( pIter->
73e0: 65 41 73 79 6e 63 4c 6f 63 6b 3e 65 52 65 71 75  eAsyncLock>eRequ
73f0: 69 72 65 64 20 29 7b 0a 20 20 20 20 20 20 20 20  ired ){.        
7400: 65 52 65 71 75 69 72 65 64 20 3d 20 70 49 74 65  eRequired = pIte
7410: 72 2d 3e 65 41 73 79 6e 63 4c 6f 63 6b 3b 0a 20  r->eAsyncLock;. 
7420: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 65 52         assert(eR
7430: 65 71 75 69 72 65 64 3e 3d 30 20 26 26 20 65 52  equired>=0 && eR
7440: 65 71 75 69 72 65 64 3c 3d 53 51 4c 49 54 45 5f  equired<=SQLITE_
7450: 4c 4f 43 4b 5f 45 58 43 4c 55 53 49 56 45 29 3b  LOCK_EXCLUSIVE);
7460: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
7470: 20 20 20 20 69 66 28 20 65 52 65 71 75 69 72 65      if( eRequire
7480: 64 3e 70 4c 6f 63 6b 2d 3e 65 4c 6f 63 6b 20 29  d>pLock->eLock )
7490: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70 4c 6f  {.      rc = pLo
74a0: 63 6b 2d 3e 70 46 69 6c 65 2d 3e 70 4d 65 74 68  ck->pFile->pMeth
74b0: 6f 64 73 2d 3e 78 4c 6f 63 6b 28 70 4c 6f 63 6b  ods->xLock(pLock
74c0: 2d 3e 70 46 69 6c 65 2c 20 65 52 65 71 75 69 72  ->pFile, eRequir
74d0: 65 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  ed);.      if( r
74e0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
74f0: 20 20 20 20 20 20 20 20 70 4c 6f 63 6b 2d 3e 65          pLock->e
7500: 4c 6f 63 6b 20 3d 20 65 52 65 71 75 69 72 65 64  Lock = eRequired
7510: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
7520: 20 20 20 20 65 6c 73 65 20 69 66 28 20 65 52 65      else if( eRe
7530: 71 75 69 72 65 64 3c 70 4c 6f 63 6b 2d 3e 65 4c  quired<pLock->eL
7540: 6f 63 6b 20 26 26 20 65 52 65 71 75 69 72 65 64  ock && eRequired
7550: 3c 3d 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f 53 48  <=SQLITE_LOCK_SH
7560: 41 52 45 44 20 29 7b 0a 20 20 20 20 20 20 72 63  ARED ){.      rc
7570: 20 3d 20 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65 2d   = pLock->pFile-
7580: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 55 6e 6c 6f  >pMethods->xUnlo
7590: 63 6b 28 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65 2c  ck(pLock->pFile,
75a0: 20 65 52 65 71 75 69 72 65 64 29 3b 0a 20 20 20   eRequired);.   
75b0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
75c0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
75d0: 70 4c 6f 63 6b 2d 3e 65 4c 6f 63 6b 20 3d 20 65  pLock->eLock = e
75e0: 52 65 71 75 69 72 65 64 3b 0a 20 20 20 20 20 20  Required;.      
75f0: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  }.    }.  }..  r
7600: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
7610: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 41 73  ** Return the As
7620: 79 6e 63 4c 6f 63 6b 20 73 74 72 75 63 74 75 72  yncLock structur
7630: 65 20 66 72 6f 6d 20 74 68 65 20 67 6c 6f 62 61  e from the globa
7640: 6c 20 61 73 79 6e 63 2e 70 4c 6f 63 6b 20 6c 69  l async.pLock li
7650: 73 74 20 0a 2a 2a 20 61 73 73 6f 63 69 61 74 65  st .** associate
7660: 64 20 77 69 74 68 20 74 68 65 20 66 69 6c 65 2d  d with the file-
7670: 73 79 73 74 65 6d 20 65 6e 74 72 79 20 69 64 65  system entry ide
7680: 6e 74 69 66 69 65 64 20 62 79 20 70 61 74 68 20  ntified by path 
7690: 7a 4e 61 6d 65 20 0a 2a 2a 20 28 61 20 73 74 72  zName .** (a str
76a0: 69 6e 67 20 6f 66 20 6e 4e 61 6d 65 20 62 79 74  ing of nName byt
76b0: 65 73 29 2e 20 49 66 20 6e 6f 20 73 75 63 68 20  es). If no such 
76c0: 73 74 72 75 63 74 75 72 65 20 65 78 69 73 74 73  structure exists
76d0: 2c 20 72 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a 73  , return 0..*/.s
76e0: 74 61 74 69 63 20 41 73 79 6e 63 4c 6f 63 6b 20  tatic AsyncLock 
76f0: 2a 66 69 6e 64 4c 6f 63 6b 28 63 6f 6e 73 74 20  *findLock(const 
7700: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74  char *zName, int
7710: 20 6e 4e 61 6d 65 29 7b 0a 20 20 41 73 79 6e 63   nName){.  Async
7720: 4c 6f 63 6b 20 2a 70 20 3d 20 61 73 79 6e 63 2e  Lock *p = async.
7730: 70 4c 6f 63 6b 3b 0a 20 20 77 68 69 6c 65 28 20  pLock;.  while( 
7740: 70 20 26 26 20 28 70 2d 3e 6e 46 69 6c 65 21 3d  p && (p->nFile!=
7750: 6e 4e 61 6d 65 20 7c 7c 20 6d 65 6d 63 6d 70 28  nName || memcmp(
7760: 70 2d 3e 7a 46 69 6c 65 2c 20 7a 4e 61 6d 65 2c  p->zFile, zName,
7770: 20 6e 4e 61 6d 65 29 29 20 29 7b 0a 20 20 20 20   nName)) ){.    
7780: 70 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  p = p->pNext;.  
7790: 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a  }.  return p;.}.
77a0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f  ./*.** The follo
77b0: 77 69 6e 67 20 74 77 6f 20 6d 65 74 68 6f 64 73  wing two methods
77c0: 20 2d 20 61 73 79 6e 63 4c 6f 63 6b 28 29 20 61   - asyncLock() a
77d0: 6e 64 20 61 73 79 6e 63 55 6e 6c 6f 63 6b 28 29  nd asyncUnlock()
77e0: 20 2d 20 61 72 65 20 75 73 65 64 0a 2a 2a 20 74   - are used.** t
77f0: 6f 20 6f 62 74 61 69 6e 20 61 6e 64 20 72 65 6c  o obtain and rel
7800: 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 64 61  ease locks on da
7810: 74 61 62 61 73 65 20 66 69 6c 65 73 20 6f 70 65  tabase files ope
7820: 6e 65 64 20 77 69 74 68 20 74 68 65 0a 2a 2a 20  ned with the.** 
7830: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 62 61 63  asynchronous bac
7840: 6b 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  kend..*/.static 
7850: 69 6e 74 20 61 73 79 6e 63 4c 6f 63 6b 28 73 71  int asyncLock(sq
7860: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
7870: 65 2c 20 69 6e 74 20 65 4c 6f 63 6b 29 7b 0a 20  e, int eLock){. 
7880: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
7890: 5f 4f 4b 3b 0a 20 20 41 73 79 6e 63 46 69 6c 65  _OK;.  AsyncFile
78a0: 44 61 74 61 20 2a 70 20 3d 20 28 28 41 73 79 6e  Data *p = ((Asyn
78b0: 63 46 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d 3e  cFile *)pFile)->
78c0: 70 44 61 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d  pData;..  if( p-
78d0: 3e 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 70 74  >zName ){.    pt
78e0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
78f0: 28 26 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65  (&async.lockMute
7900: 78 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 6c  x);.    if( p->l
7910: 6f 63 6b 2e 65 4c 6f 63 6b 3c 65 4c 6f 63 6b 20  ock.eLock<eLock 
7920: 29 7b 0a 20 20 20 20 20 20 41 73 79 6e 63 4c 6f  ){.      AsyncLo
7930: 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 70 2d 3e 70  ck *pLock = p->p
7940: 4c 6f 63 6b 3b 0a 20 20 20 20 20 20 41 73 79 6e  Lock;.      Asyn
7950: 63 46 69 6c 65 4c 6f 63 6b 20 2a 70 49 74 65 72  cFileLock *pIter
7960: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 70  ;.      assert(p
7970: 4c 6f 63 6b 20 26 26 20 70 4c 6f 63 6b 2d 3e 70  Lock && pLock->p
7980: 4c 69 73 74 29 3b 0a 20 20 20 20 20 20 66 6f 72  List);.      for
7990: 28 70 49 74 65 72 3d 70 4c 6f 63 6b 2d 3e 70 4c  (pIter=pLock->pL
79a0: 69 73 74 3b 20 70 49 74 65 72 3b 20 70 49 74 65  ist; pIter; pIte
79b0: 72 3d 70 49 74 65 72 2d 3e 70 4e 65 78 74 29 7b  r=pIter->pNext){
79c0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 49 74  .        if( pIt
79d0: 65 72 21 3d 26 70 2d 3e 6c 6f 63 6b 20 26 26 20  er!=&p->lock && 
79e0: 28 0a 20 20 20 20 20 20 20 20 20 20 28 65 4c 6f  (.          (eLo
79f0: 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f  ck==SQLITE_LOCK_
7a00: 45 58 43 4c 55 53 49 56 45 20 26 26 20 70 49 74  EXCLUSIVE && pIt
7a10: 65 72 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c 49 54  er->eLock>=SQLIT
7a20: 45 5f 4c 4f 43 4b 5f 53 48 41 52 45 44 29 20 7c  E_LOCK_SHARED) |
7a30: 7c 0a 20 20 20 20 20 20 20 20 20 20 28 65 4c 6f  |.          (eLo
7a40: 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f  ck==SQLITE_LOCK_
7a50: 50 45 4e 44 49 4e 47 20 26 26 20 70 49 74 65 72  PENDING && pIter
7a60: 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c 49 54 45 5f  ->eLock>=SQLITE_
7a70: 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 20 7c  LOCK_RESERVED) |
7a80: 7c 0a 20 20 20 20 20 20 20 20 20 20 28 65 4c 6f  |.          (eLo
7a90: 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f  ck==SQLITE_LOCK_
7aa0: 52 45 53 45 52 56 45 44 20 26 26 20 70 49 74 65  RESERVED && pIte
7ab0: 72 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c 49 54 45  r->eLock>=SQLITE
7ac0: 5f 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 20  _LOCK_RESERVED) 
7ad0: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 28 65 4c  ||.          (eL
7ae0: 6f 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f 43 4b  ock==SQLITE_LOCK
7af0: 5f 53 48 41 52 45 44 20 26 26 20 70 49 74 65 72  _SHARED && pIter
7b00: 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c 49 54 45 5f  ->eLock>=SQLITE_
7b10: 4c 4f 43 4b 5f 50 45 4e 44 49 4e 47 29 0a 20 20  LOCK_PENDING).  
7b20: 20 20 20 20 20 20 29 29 7b 0a 20 20 20 20 20 20        )){.      
7b30: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
7b40: 42 55 53 59 3b 0a 20 20 20 20 20 20 20 20 7d 0a  BUSY;.        }.
7b50: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
7b60: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7b70: 29 7b 0a 20 20 20 20 20 20 20 20 70 2d 3e 6c 6f  ){.        p->lo
7b80: 63 6b 2e 65 4c 6f 63 6b 20 3d 20 65 4c 6f 63 6b  ck.eLock = eLock
7b90: 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 6c 6f 63  ;.        p->loc
7ba0: 6b 2e 65 41 73 79 6e 63 4c 6f 63 6b 20 3d 20 4d  k.eAsyncLock = M
7bb0: 41 58 28 70 2d 3e 6c 6f 63 6b 2e 65 41 73 79 6e  AX(p->lock.eAsyn
7bc0: 63 4c 6f 63 6b 2c 20 65 4c 6f 63 6b 29 3b 0a 20  cLock, eLock);. 
7bd0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73       }.      ass
7be0: 65 72 74 28 70 2d 3e 6c 6f 63 6b 2e 65 41 73 79  ert(p->lock.eAsy
7bf0: 6e 63 4c 6f 63 6b 3e 3d 70 2d 3e 6c 6f 63 6b 2e  ncLock>=p->lock.
7c00: 65 4c 6f 63 6b 29 3b 0a 20 20 20 20 20 20 69 66  eLock);.      if
7c10: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7c20: 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
7c30: 67 65 74 46 69 6c 65 4c 6f 63 6b 28 70 4c 6f 63  getFileLock(pLoc
7c40: 6b 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  k);.      }.    
7c50: 7d 0a 20 20 20 20 70 74 68 72 65 61 64 5f 6d 75  }.    pthread_mu
7c60: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e  tex_unlock(&asyn
7c70: 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20 20  c.lockMutex);.  
7c80: 7d 0a 0a 20 20 41 53 59 4e 43 5f 54 52 41 43 45  }..  ASYNC_TRACE
7c90: 28 28 22 4c 4f 43 4b 20 25 64 20 28 25 73 29 20  (("LOCK %d (%s) 
7ca0: 72 63 3d 25 64 5c 6e 22 2c 20 65 4c 6f 63 6b 2c  rc=%d\n", eLock,
7cb0: 20 70 2d 3e 7a 4e 61 6d 65 2c 20 72 63 29 29 3b   p->zName, rc));
7cc0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7cd0: 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63  static int async
7ce0: 55 6e 6c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  Unlock(sqlite3_f
7cf0: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
7d00: 65 4c 6f 63 6b 29 7b 0a 20 20 69 6e 74 20 72 63  eLock){.  int rc
7d10: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
7d20: 41 73 79 6e 63 46 69 6c 65 44 61 74 61 20 2a 70  AsyncFileData *p
7d30: 20 3d 20 28 28 41 73 79 6e 63 46 69 6c 65 20 2a   = ((AsyncFile *
7d40: 29 70 46 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a  )pFile)->pData;.
7d50: 20 20 69 66 28 20 70 2d 3e 7a 4e 61 6d 65 20 29    if( p->zName )
7d60: 7b 0a 20 20 20 20 41 73 79 6e 63 46 69 6c 65 4c  {.    AsyncFileL
7d70: 6f 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 26 70 2d  ock *pLock = &p-
7d80: 3e 6c 6f 63 6b 3b 0a 20 20 20 20 70 74 68 72 65  >lock;.    pthre
7d90: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
7da0: 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29  sync.queueMutex)
7db0: 3b 0a 20 20 20 20 70 74 68 72 65 61 64 5f 6d 75  ;.    pthread_mu
7dc0: 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e 63 2e  tex_lock(&async.
7dd0: 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20 20 20 20  lockMutex);.    
7de0: 70 4c 6f 63 6b 2d 3e 65 4c 6f 63 6b 20 3d 20 4d  pLock->eLock = M
7df0: 49 4e 28 70 4c 6f 63 6b 2d 3e 65 4c 6f 63 6b 2c  IN(pLock->eLock,
7e00: 20 65 4c 6f 63 6b 29 3b 0a 20 20 20 20 72 63 20   eLock);.    rc 
7e10: 3d 20 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69  = addNewAsyncWri
7e20: 74 65 28 70 2c 20 41 53 59 4e 43 5f 55 4e 4c 4f  te(p, ASYNC_UNLO
7e30: 43 4b 2c 20 30 2c 20 65 4c 6f 63 6b 2c 20 30 29  CK, 0, eLock, 0)
7e40: 3b 0a 20 20 20 20 70 74 68 72 65 61 64 5f 6d 75  ;.    pthread_mu
7e50: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e  tex_unlock(&asyn
7e60: 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20 20  c.lockMutex);.  
7e70: 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f    pthread_mutex_
7e80: 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 71 75  unlock(&async.qu
7e90: 65 75 65 4d 75 74 65 78 29 3b 0a 20 20 7d 0a 20  eueMutex);.  }. 
7ea0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
7eb0: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
7ec0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65  on is called whe
7ed0: 6e 20 74 68 65 20 70 61 67 65 72 20 6c 61 79 65  n the pager laye
7ee0: 72 20 66 69 72 73 74 20 6f 70 65 6e 73 20 61 20  r first opens a 
7ef0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 0a 2a 2a  database file.**
7f00: 20 61 6e 64 20 69 73 20 63 68 65 63 6b 69 6e 67   and is checking
7f10: 20 66 6f 72 20 61 20 68 6f 74 2d 6a 6f 75 72 6e   for a hot-journ
7f20: 61 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  al..*/.static in
7f30: 74 20 61 73 79 6e 63 43 68 65 63 6b 52 65 73 65  t asyncCheckRese
7f40: 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74 65 33  rvedLock(sqlite3
7f50: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e  _file *pFile, in
7f60: 74 20 2a 70 52 65 73 4f 75 74 29 7b 0a 20 20 69  t *pResOut){.  i
7f70: 6e 74 20 72 65 74 20 3d 20 30 3b 0a 20 20 41 73  nt ret = 0;.  As
7f80: 79 6e 63 46 69 6c 65 4c 6f 63 6b 20 2a 70 49 74  yncFileLock *pIt
7f90: 65 72 3b 0a 20 20 41 73 79 6e 63 46 69 6c 65 44  er;.  AsyncFileD
7fa0: 61 74 61 20 2a 70 20 3d 20 28 28 41 73 79 6e 63  ata *p = ((Async
7fb0: 46 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d 3e 70  File *)pFile)->p
7fc0: 44 61 74 61 3b 0a 0a 20 20 70 74 68 72 65 61 64  Data;..  pthread
7fd0: 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79  _mutex_lock(&asy
7fe0: 6e 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20  nc.lockMutex);. 
7ff0: 20 66 6f 72 28 70 49 74 65 72 3d 70 2d 3e 70 4c   for(pIter=p->pL
8000: 6f 63 6b 2d 3e 70 4c 69 73 74 3b 20 70 49 74 65  ock->pList; pIte
8010: 72 3b 20 70 49 74 65 72 3d 70 49 74 65 72 2d 3e  r; pIter=pIter->
8020: 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20  pNext){.    if( 
8030: 70 49 74 65 72 2d 3e 65 4c 6f 63 6b 3e 3d 53 51  pIter->eLock>=SQ
8040: 4c 49 54 45 5f 4c 4f 43 4b 5f 52 45 53 45 52 56  LITE_LOCK_RESERV
8050: 45 44 20 29 7b 0a 20 20 20 20 20 20 72 65 74 20  ED ){.      ret 
8060: 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  = 1;.    }.  }. 
8070: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75   pthread_mutex_u
8080: 6e 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 6c 6f 63  nlock(&async.loc
8090: 6b 4d 75 74 65 78 29 3b 0a 0a 20 20 41 53 59 4e  kMutex);..  ASYN
80a0: 43 5f 54 52 41 43 45 28 28 22 43 48 45 43 4b 2d  C_TRACE(("CHECK-
80b0: 4c 4f 43 4b 20 25 64 20 28 25 73 29 5c 6e 22 2c  LOCK %d (%s)\n",
80c0: 20 72 65 74 2c 20 70 2d 3e 7a 4e 61 6d 65 29 29   ret, p->zName))
80d0: 3b 0a 20 20 2a 70 52 65 73 4f 75 74 20 3d 20 72  ;.  *pResOut = r
80e0: 65 74 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  et;.  return SQL
80f0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  ITE_OK;.}../* .*
8100: 2a 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 5f 63  * sqlite3_file_c
8110: 6f 6e 74 72 6f 6c 28 29 20 69 6d 70 6c 65 6d 65  ontrol() impleme
8120: 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  ntation..*/.stat
8130: 69 63 20 69 6e 74 20 61 73 79 6e 63 46 69 6c 65  ic int asyncFile
8140: 43 6f 6e 74 72 6f 6c 28 73 71 6c 69 74 65 33 5f  Control(sqlite3_
8150: 66 69 6c 65 20 2a 69 64 2c 20 69 6e 74 20 6f 70  file *id, int op
8160: 2c 20 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a 20  , void *pArg){. 
8170: 20 73 77 69 74 63 68 28 20 6f 70 20 29 7b 0a 20   switch( op ){. 
8180: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 46     case SQLITE_F
8190: 43 4e 54 4c 5f 4c 4f 43 4b 53 54 41 54 45 3a 20  CNTL_LOCKSTATE: 
81a0: 7b 0a 20 20 20 20 20 20 70 74 68 72 65 61 64 5f  {.      pthread_
81b0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e  mutex_lock(&asyn
81c0: 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20 20  c.lockMutex);.  
81d0: 20 20 20 20 2a 28 69 6e 74 2a 29 70 41 72 67 20      *(int*)pArg 
81e0: 3d 20 28 28 41 73 79 6e 63 46 69 6c 65 2a 29 69  = ((AsyncFile*)i
81f0: 64 29 2d 3e 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e  d)->pData->lock.
8200: 65 4c 6f 63 6b 3b 0a 20 20 20 20 20 20 70 74 68  eLock;.      pth
8210: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
8220: 6b 28 26 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74  k(&async.lockMut
8230: 65 78 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  ex);.      retur
8240: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20  n SQLITE_OK;.   
8250: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
8260: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 7d 0a  SQLITE_ERROR;.}.
8270: 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ./* .** Return t
8280: 68 65 20 64 65 76 69 63 65 20 63 68 61 72 61 63  he device charac
8290: 74 65 72 69 73 74 69 63 73 20 61 6e 64 20 73 65  teristics and se
82a0: 63 74 6f 72 2d 73 69 7a 65 20 6f 66 20 74 68 65  ctor-size of the
82b0: 20 64 65 76 69 63 65 2e 20 49 74 0a 2a 2a 20 69   device. It.** i
82c0: 73 20 6e 6f 74 20 74 72 69 63 6b 79 20 74 6f 20  s not tricky to 
82d0: 69 6d 70 6c 65 6d 65 6e 74 20 74 68 65 73 65 20  implement these 
82e0: 63 6f 72 72 65 63 74 6c 79 2c 20 61 73 20 74 68  correctly, as th
82f0: 69 73 20 62 61 63 6b 65 6e 64 20 6d 69 67 68 74  is backend might
8300: 20 0a 2a 2a 20 6e 6f 74 20 68 61 76 65 20 61 6e   .** not have an
8310: 20 6f 70 65 6e 20 66 69 6c 65 20 68 61 6e 64 6c   open file handl
8320: 65 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e  e at this point.
8330: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .*/.static int a
8340: 73 79 6e 63 53 65 63 74 6f 72 53 69 7a 65 28 73  syncSectorSize(s
8350: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
8360: 6c 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 35 31  le){.  return 51
8370: 32 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  2;.}.static int 
8380: 61 73 79 6e 63 44 65 76 69 63 65 43 68 61 72 61  asyncDeviceChara
8390: 63 74 65 72 69 73 74 69 63 73 28 73 71 6c 69 74  cteristics(sqlit
83a0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b  e3_file *pFile){
83b0: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
83c0: 73 74 61 74 69 63 20 69 6e 74 20 75 6e 6c 69 6e  static int unlin
83d0: 6b 41 73 79 6e 63 46 69 6c 65 28 41 73 79 6e 63  kAsyncFile(Async
83e0: 46 69 6c 65 44 61 74 61 20 2a 70 44 61 74 61 29  FileData *pData)
83f0: 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 4c 6f 63  {.  AsyncFileLoc
8400: 6b 20 2a 2a 70 70 49 74 65 72 3b 0a 20 20 69 6e  k **ppIter;.  in
8410: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
8420: 3b 0a 0a 20 20 69 66 28 20 70 44 61 74 61 2d 3e  ;..  if( pData->
8430: 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 41 73 79  zName ){.    Asy
8440: 6e 63 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20  ncLock *pLock = 
8450: 70 44 61 74 61 2d 3e 70 4c 6f 63 6b 3b 0a 20 20  pData->pLock;.  
8460: 20 20 66 6f 72 28 70 70 49 74 65 72 3d 26 70 4c    for(ppIter=&pL
8470: 6f 63 6b 2d 3e 70 4c 69 73 74 3b 20 2a 70 70 49  ock->pList; *ppI
8480: 74 65 72 3b 20 70 70 49 74 65 72 3d 26 28 28 2a  ter; ppIter=&((*
8490: 70 70 49 74 65 72 29 2d 3e 70 4e 65 78 74 29 29  ppIter)->pNext))
84a0: 7b 0a 20 20 20 20 20 20 69 66 28 20 28 2a 70 70  {.      if( (*pp
84b0: 49 74 65 72 29 3d 3d 26 70 44 61 74 61 2d 3e 6c  Iter)==&pData->l
84c0: 6f 63 6b 20 29 7b 0a 20 20 20 20 20 20 20 20 2a  ock ){.        *
84d0: 70 70 49 74 65 72 20 3d 20 70 44 61 74 61 2d 3e  ppIter = pData->
84e0: 6c 6f 63 6b 2e 70 4e 65 78 74 3b 0a 20 20 20 20  lock.pNext;.    
84f0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
8500: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28   }.    }.    if(
8510: 20 21 70 4c 6f 63 6b 2d 3e 70 4c 69 73 74 20 29   !pLock->pList )
8520: 7b 0a 20 20 20 20 20 20 41 73 79 6e 63 4c 6f 63  {.      AsyncLoc
8530: 6b 20 2a 2a 70 70 3b 0a 20 20 20 20 20 20 69 66  k **pp;.      if
8540: 28 20 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65 20 29  ( pLock->pFile )
8550: 7b 0a 20 20 20 20 20 20 20 20 70 4c 6f 63 6b 2d  {.        pLock-
8560: 3e 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73  >pFile->pMethods
8570: 2d 3e 78 43 6c 6f 73 65 28 70 4c 6f 63 6b 2d 3e  ->xClose(pLock->
8580: 70 46 69 6c 65 29 3b 0a 20 20 20 20 20 20 7d 0a  pFile);.      }.
8590: 20 20 20 20 20 20 66 6f 72 28 70 70 3d 26 61 73        for(pp=&as
85a0: 79 6e 63 2e 70 4c 6f 63 6b 3b 20 2a 70 70 21 3d  ync.pLock; *pp!=
85b0: 70 4c 6f 63 6b 3b 20 70 70 3d 26 28 28 2a 70 70  pLock; pp=&((*pp
85c0: 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20  )->pNext));.    
85d0: 20 20 2a 70 70 20 3d 20 70 4c 6f 63 6b 2d 3e 70    *pp = pLock->p
85e0: 4e 65 78 74 3b 0a 20 20 20 20 20 20 73 71 6c 69  Next;.      sqli
85f0: 74 65 33 5f 66 72 65 65 28 70 4c 6f 63 6b 29 3b  te3_free(pLock);
8600: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
8610: 20 20 72 63 20 3d 20 67 65 74 46 69 6c 65 4c 6f    rc = getFileLo
8620: 63 6b 28 70 4c 6f 63 6b 29 3b 0a 20 20 20 20 7d  ck(pLock);.    }
8630: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
8640: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  c;.}../*.** The 
8650: 70 61 72 61 6d 65 74 65 72 20 70 61 73 73 65 64  parameter passed
8660: 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f   to this functio
8670: 6e 20 69 73 20 61 20 63 6f 70 79 20 6f 66 20 61  n is a copy of a
8680: 20 27 66 6c 61 67 73 27 20 70 61 72 61 6d 65 74   'flags' paramet
8690: 65 72 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f 20  er.** passed to 
86a0: 74 68 69 73 20 6d 6f 64 75 6c 65 73 20 78 4f 70  this modules xOp
86b0: 65 6e 28 29 20 6d 65 74 68 6f 64 2e 20 54 68 69  en() method. Thi
86c0: 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  s function retur
86d0: 6e 73 20 74 72 75 65 0a 2a 2a 20 69 66 20 74 68  ns true.** if th
86e0: 65 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 62 65  e file should be
86f0: 20 6f 70 65 6e 65 64 20 61 73 79 6e 63 68 72 6f   opened asynchro
8700: 6e 6f 75 73 6c 79 2c 20 6f 72 20 66 61 6c 73 65  nously, or false
8710: 20 69 66 20 69 74 20 73 68 6f 75 6c 64 0a 2a 2a   if it should.**
8720: 20 62 65 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64   be opened immed
8730: 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 49 66  iately..**.** If
8740: 20 74 68 65 20 66 69 6c 65 20 69 73 20 74 6f 20   the file is to 
8750: 62 65 20 6f 70 65 6e 65 64 20 61 73 79 6e 63 68  be opened asynch
8760: 72 6f 6e 6f 75 73 6c 79 2c 20 74 68 65 6e 20 61  ronously, then a
8770: 73 79 6e 63 4f 70 65 6e 28 29 20 77 69 6c 6c 20  syncOpen() will 
8780: 61 64 64 0a 2a 2a 20 61 6e 20 65 6e 74 72 79 20  add.** an entry 
8790: 74 6f 20 74 68 65 20 65 76 65 6e 74 20 71 75 65  to the event que
87a0: 75 65 20 61 6e 64 20 74 68 65 20 66 69 6c 65 20  ue and the file 
87b0: 77 69 6c 6c 20 6e 6f 74 20 61 63 74 75 61 6c 6c  will not actuall
87c0: 79 20 62 65 20 6f 70 65 6e 65 64 0a 2a 2a 20 75  y be opened.** u
87d0: 6e 74 69 6c 20 74 68 65 20 65 76 65 6e 74 20 69  ntil the event i
87e0: 73 20 70 72 6f 63 65 73 73 65 64 2e 20 4f 74 68  s processed. Oth
87f0: 65 72 77 69 73 65 2c 20 74 68 65 20 66 69 6c 65  erwise, the file
8800: 20 69 73 20 6f 70 65 6e 65 64 20 64 69 72 65 63   is opened direc
8810: 74 6c 79 0a 2a 2a 20 62 79 20 74 68 65 20 63 61  tly.** by the ca
8820: 6c 6c 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ller..*/.static 
8830: 69 6e 74 20 64 6f 41 73 79 6e 63 68 72 6f 6e 6f  int doAsynchrono
8840: 75 73 4f 70 65 6e 28 69 6e 74 20 66 6c 61 67 73  usOpen(int flags
8850: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 66 6c 61  ){.  return (fla
8860: 67 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43  gs&SQLITE_OPEN_C
8870: 52 45 41 54 45 29 20 26 26 20 28 0a 20 20 20 20  REATE) && (.    
8880: 20 20 28 66 6c 61 67 73 26 53 51 4c 49 54 45 5f    (flags&SQLITE_
8890: 4f 50 45 4e 5f 4d 41 49 4e 5f 4a 4f 55 52 4e 41  OPEN_MAIN_JOURNA
88a0: 4c 29 20 7c 7c 0a 20 20 20 20 20 20 28 66 6c 61  L) ||.      (fla
88b0: 67 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 54  gs&SQLITE_OPEN_T
88c0: 45 4d 50 5f 4a 4f 55 52 4e 41 4c 29 20 7c 7c 0a  EMP_JOURNAL) ||.
88d0: 20 20 20 20 20 20 28 66 6c 61 67 73 26 53 51 4c        (flags&SQL
88e0: 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45 4f  ITE_OPEN_DELETEO
88f0: 4e 43 4c 4f 53 45 29 0a 20 20 29 3b 0a 7d 0a 0a  NCLOSE).  );.}..
8900: 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20 66 69 6c  /*.** Open a fil
8910: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
8920: 20 61 73 79 6e 63 4f 70 65 6e 28 0a 20 20 73 71   asyncOpen(.  sq
8930: 6c 69 74 65 33 5f 76 66 73 20 2a 70 41 73 79 6e  lite3_vfs *pAsyn
8940: 63 56 66 73 2c 0a 20 20 63 6f 6e 73 74 20 63 68  cVfs,.  const ch
8950: 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 73 71 6c  ar *zName,.  sql
8960: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
8970: 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73 2c 0a 20  ,.  int flags,. 
8980: 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61 67 73 0a   int *pOutFlags.
8990: 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c 69  ){.  static sqli
89a0: 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 61  te3_io_methods a
89b0: 73 79 6e 63 5f 6d 65 74 68 6f 64 73 20 3d 20 7b  sync_methods = {
89c0: 0a 20 20 20 20 31 2c 20 20 20 20 20 20 20 20 20  .    1,         
89d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
89e0: 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f        /* iVersio
89f0: 6e 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 43 6c  n */.    asyncCl
8a00: 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ose,            
8a10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c            /* xCl
8a20: 6f 73 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63  ose */.    async
8a30: 52 65 61 64 2c 20 20 20 20 20 20 20 20 20 20 20  Read,           
8a40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8a50: 52 65 61 64 20 2a 2f 0a 20 20 20 20 61 73 79 6e  Read */.    asyn
8a60: 63 57 72 69 74 65 2c 20 20 20 20 20 20 20 20 20  cWrite,         
8a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8a80: 78 57 72 69 74 65 20 2a 2f 0a 20 20 20 20 61 73  xWrite */.    as
8a90: 79 6e 63 54 72 75 6e 63 61 74 65 2c 20 20 20 20  yncTruncate,    
8aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8ab0: 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20  * xTruncate */. 
8ac0: 20 20 20 61 73 79 6e 63 53 79 6e 63 2c 20 20 20     asyncSync,   
8ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ae0: 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a      /* xSync */.
8af0: 20 20 20 20 61 73 79 6e 63 46 69 6c 65 53 69 7a      asyncFileSiz
8b00: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
8b10: 20 20 20 20 20 2f 2a 20 78 46 69 6c 65 53 69 7a       /* xFileSiz
8b20: 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 4c 6f  e */.    asyncLo
8b30: 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ck,             
8b40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4c 6f            /* xLo
8b50: 63 6b 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 55  ck */.    asyncU
8b60: 6e 6c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20  nlock,          
8b70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55             /* xU
8b80: 6e 6c 6f 63 6b 20 2a 2f 0a 20 20 20 20 61 73 79  nlock */.    asy
8b90: 6e 63 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c  ncCheckReservedL
8ba0: 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  ock,          /*
8bb0: 20 78 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c   xCheckReservedL
8bc0: 6f 63 6b 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63  ock */.    async
8bd0: 46 69 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20  FileControl,    
8be0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8bf0: 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20  FileControl */. 
8c00: 20 20 20 61 73 79 6e 63 53 65 63 74 6f 72 53 69     asyncSectorSi
8c10: 7a 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ze,             
8c20: 20 20 20 20 2f 2a 20 78 53 65 63 74 6f 72 53 69      /* xSectorSi
8c30: 7a 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 44  ze */.    asyncD
8c40: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
8c50: 74 69 63 73 20 20 20 20 20 20 20 2f 2a 20 78 44  tics       /* xD
8c60: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
8c70: 74 69 63 73 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20  tics */.  };..  
8c80: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
8c90: 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73  s = (sqlite3_vfs
8ca0: 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41   *)pAsyncVfs->pA
8cb0: 70 70 44 61 74 61 3b 0a 20 20 41 73 79 6e 63 46  ppData;.  AsyncF
8cc0: 69 6c 65 20 2a 70 20 3d 20 28 41 73 79 6e 63 46  ile *p = (AsyncF
8cd0: 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 69  ile *)pFile;.  i
8ce0: 6e 74 20 6e 4e 61 6d 65 20 3d 20 30 3b 0a 20 20  nt nName = 0;.  
8cf0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
8d00: 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b  OK;.  int nByte;
8d10: 0a 20 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61  .  AsyncFileData
8d20: 20 2a 70 44 61 74 61 3b 0a 20 20 41 73 79 6e 63   *pData;.  Async
8d30: 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 30 3b  Lock *pLock = 0;
8d40: 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 69 6e  .  char *z;.  in
8d50: 74 20 69 73 41 73 79 6e 63 4f 70 65 6e 20 3d 20  t isAsyncOpen = 
8d60: 64 6f 41 73 79 6e 63 68 72 6f 6e 6f 75 73 4f 70  doAsynchronousOp
8d70: 65 6e 28 66 6c 61 67 73 29 3b 0a 0a 20 20 2f 2a  en(flags);..  /*
8d80: 20 49 66 20 7a 4e 61 6d 65 20 69 73 20 4e 55 4c   If zName is NUL
8d90: 4c 2c 20 74 68 65 6e 20 74 68 65 20 75 70 70 65  L, then the uppe
8da0: 72 20 6c 61 79 65 72 20 69 73 20 72 65 71 75 65  r layer is reque
8db0: 73 74 69 6e 67 20 61 6e 20 61 6e 6f 6e 79 6d 6f  sting an anonymo
8dc0: 75 73 20 66 69 6c 65 20 2a 2f 0a 20 20 69 66 28  us file */.  if(
8dd0: 20 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 6e 4e   zName ){.    nN
8de0: 61 6d 65 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61  ame = strlen(zNa
8df0: 6d 65 29 2b 31 3b 0a 20 20 7d 0a 0a 20 20 6e 42  me)+1;.  }..  nB
8e00: 79 74 65 20 3d 20 28 0a 20 20 20 20 73 69 7a 65  yte = (.    size
8e10: 6f 66 28 41 73 79 6e 63 46 69 6c 65 44 61 74 61  of(AsyncFileData
8e20: 29 20 2b 20 20 20 20 20 20 20 20 2f 2a 20 41 73  ) +        /* As
8e30: 79 6e 63 46 69 6c 65 44 61 74 61 20 73 74 72 75  yncFileData stru
8e40: 63 74 75 72 65 20 2a 2f 0a 20 20 20 20 32 20 2a  cture */.    2 *
8e50: 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 20   pVfs->szOsFile 
8e60: 2b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41  +           /* A
8e70: 73 79 6e 63 46 69 6c 65 44 61 74 61 2e 70 42 61  syncFileData.pBa
8e80: 73 65 52 65 61 64 20 61 6e 64 20 70 42 61 73 65  seRead and pBase
8e90: 57 72 69 74 65 20 2a 2f 0a 20 20 20 20 6e 4e 61  Write */.    nNa
8ea0: 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20  me              
8eb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
8ec0: 73 79 6e 63 46 69 6c 65 44 61 74 61 2e 7a 4e 61  syncFileData.zNa
8ed0: 6d 65 20 2a 2f 0a 20 20 29 3b 20 0a 20 20 7a 20  me */.  ); .  z 
8ee0: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
8ef0: 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 21  (nByte);.  if( !
8f00: 7a 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  z ){.    return 
8f10: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
8f20: 7d 0a 20 20 6d 65 6d 73 65 74 28 7a 2c 20 30 2c  }.  memset(z, 0,
8f30: 20 6e 42 79 74 65 29 3b 0a 20 20 70 44 61 74 61   nByte);.  pData
8f40: 20 3d 20 28 41 73 79 6e 63 46 69 6c 65 44 61 74   = (AsyncFileDat
8f50: 61 2a 29 7a 3b 0a 20 20 7a 20 2b 3d 20 73 69 7a  a*)z;.  z += siz
8f60: 65 6f 66 28 70 44 61 74 61 5b 30 5d 29 3b 0a 20  eof(pData[0]);. 
8f70: 20 70 44 61 74 61 2d 3e 70 42 61 73 65 52 65 61   pData->pBaseRea
8f80: 64 20 3d 20 28 73 71 6c 69 74 65 33 5f 66 69 6c  d = (sqlite3_fil
8f90: 65 2a 29 7a 3b 0a 20 20 7a 20 2b 3d 20 70 56 66  e*)z;.  z += pVf
8fa0: 73 2d 3e 73 7a 4f 73 46 69 6c 65 3b 0a 20 20 70  s->szOsFile;.  p
8fb0: 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74 65  Data->pBaseWrite
8fc0: 20 3d 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65   = (sqlite3_file
8fd0: 2a 29 7a 3b 0a 20 20 70 44 61 74 61 2d 3e 63 6c  *)z;.  pData->cl
8fe0: 6f 73 65 4f 70 2e 70 46 69 6c 65 44 61 74 61 20  oseOp.pFileData 
8ff0: 3d 20 70 44 61 74 61 3b 0a 20 20 70 44 61 74 61  = pData;.  pData
9000: 2d 3e 63 6c 6f 73 65 4f 70 2e 6f 70 20 3d 20 41  ->closeOp.op = A
9010: 53 59 4e 43 5f 43 4c 4f 53 45 3b 0a 0a 20 20 69  SYNC_CLOSE;..  i
9020: 66 28 20 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20  f( zName ){.    
9030: 7a 20 2b 3d 20 70 56 66 73 2d 3e 73 7a 4f 73 46  z += pVfs->szOsF
9040: 69 6c 65 3b 0a 20 20 20 20 70 44 61 74 61 2d 3e  ile;.    pData->
9050: 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 20 70  zName = z;.    p
9060: 44 61 74 61 2d 3e 6e 4e 61 6d 65 20 3d 20 6e 4e  Data->nName = nN
9070: 61 6d 65 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28  ame;.    memcpy(
9080: 70 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e  pData->zName, zN
9090: 61 6d 65 2c 20 6e 4e 61 6d 65 29 3b 0a 20 20 7d  ame, nName);.  }
90a0: 0a 0a 20 20 69 66 28 20 21 69 73 41 73 79 6e 63  ..  if( !isAsync
90b0: 4f 70 65 6e 20 29 7b 0a 20 20 20 20 69 6e 74 20  Open ){.    int 
90c0: 66 6c 61 67 73 6f 75 74 3b 0a 20 20 20 20 72 63  flagsout;.    rc
90d0: 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65 6e 28 70   = pVfs->xOpen(p
90e0: 56 66 73 2c 20 7a 4e 61 6d 65 2c 20 70 44 61 74  Vfs, zName, pDat
90f0: 61 2d 3e 70 42 61 73 65 52 65 61 64 2c 20 66 6c  a->pBaseRead, fl
9100: 61 67 73 2c 20 26 66 6c 61 67 73 6f 75 74 29 3b  ags, &flagsout);
9110: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
9120: 49 54 45 5f 4f 4b 20 26 26 20 28 66 6c 61 67 73  ITE_OK && (flags
9130: 6f 75 74 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  out&SQLITE_OPEN_
9140: 52 45 41 44 57 52 49 54 45 29 20 29 7b 0a 20 20  READWRITE) ){.  
9150: 20 20 20 20 72 63 20 3d 20 70 56 66 73 2d 3e 78      rc = pVfs->x
9160: 4f 70 65 6e 28 70 56 66 73 2c 20 7a 4e 61 6d 65  Open(pVfs, zName
9170: 2c 20 70 44 61 74 61 2d 3e 70 42 61 73 65 57 72  , pData->pBaseWr
9180: 69 74 65 2c 20 66 6c 61 67 73 2c 20 30 29 3b 0a  ite, flags, 0);.
9190: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 4f      }.    if( pO
91a0: 75 74 46 6c 61 67 73 20 29 7b 0a 20 20 20 20 20  utFlags ){.     
91b0: 20 2a 70 4f 75 74 46 6c 61 67 73 20 3d 20 66 6c   *pOutFlags = fl
91c0: 61 67 73 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20  agsout;.    }.  
91d0: 7d 0a 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74  }..  pthread_mut
91e0: 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 6c  ex_lock(&async.l
91f0: 6f 63 6b 4d 75 74 65 78 29 3b 0a 0a 20 20 69 66  ockMutex);..  if
9200: 28 20 7a 4e 61 6d 65 20 26 26 20 72 63 3d 3d 53  ( zName && rc==S
9210: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
9220: 70 4c 6f 63 6b 20 3d 20 66 69 6e 64 4c 6f 63 6b  pLock = findLock
9230: 28 70 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 70  (pData->zName, p
9240: 44 61 74 61 2d 3e 6e 4e 61 6d 65 29 3b 0a 20 20  Data->nName);.  
9250: 20 20 69 66 28 20 21 70 4c 6f 63 6b 20 29 7b 0a    if( !pLock ){.
9260: 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20        int nByte 
9270: 3d 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65  = pVfs->szOsFile
9280: 20 2b 20 73 69 7a 65 6f 66 28 41 73 79 6e 63 4c   + sizeof(AsyncL
9290: 6f 63 6b 29 20 2b 20 70 44 61 74 61 2d 3e 6e 4e  ock) + pData->nN
92a0: 61 6d 65 20 2b 20 31 3b 20 0a 20 20 20 20 20 20  ame + 1; .      
92b0: 70 4c 6f 63 6b 20 3d 20 28 41 73 79 6e 63 4c 6f  pLock = (AsyncLo
92c0: 63 6b 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  ck *)sqlite3_mal
92d0: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
92e0: 20 20 69 66 28 20 70 4c 6f 63 6b 20 29 7b 0a 20    if( pLock ){. 
92f0: 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 4c         memset(pL
9300: 6f 63 6b 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a  ock, 0, nByte);.
9310: 23 69 66 64 65 66 20 45 4e 41 42 4c 45 5f 46 49  #ifdef ENABLE_FI
9320: 4c 45 5f 4c 4f 43 4b 49 4e 47 0a 20 20 20 20 20  LE_LOCKING.     
9330: 20 20 20 69 66 28 20 66 6c 61 67 73 26 53 51 4c     if( flags&SQL
9340: 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42  ITE_OPEN_MAIN_DB
9350: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 4c   ){.          pL
9360: 6f 63 6b 2d 3e 70 46 69 6c 65 20 3d 20 28 73 71  ock->pFile = (sq
9370: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29 26 70 4c  lite3_file *)&pL
9380: 6f 63 6b 5b 31 5d 3b 0a 20 20 20 20 20 20 20 20  ock[1];.        
9390: 20 20 72 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70    rc = pVfs->xOp
93a0: 65 6e 28 70 56 66 73 2c 20 7a 4e 61 6d 65 2c 20  en(pVfs, zName, 
93b0: 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65 2c 20 66 6c  pLock->pFile, fl
93c0: 61 67 73 2c 20 30 29 3b 0a 20 20 20 20 20 20 20  ags, 0);.       
93d0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
93e0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
93f0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
9400: 28 70 4c 6f 63 6b 29 3b 0a 20 20 20 20 20 20 20  (pLock);.       
9410: 20 20 20 20 20 70 4c 6f 63 6b 20 3d 20 30 3b 0a       pLock = 0;.
9420: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
9430: 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20      }.#endif.   
9440: 20 20 20 20 20 69 66 28 20 70 4c 6f 63 6b 20 29       if( pLock )
9450: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 4c 6f 63  {.          pLoc
9460: 6b 2d 3e 6e 46 69 6c 65 20 3d 20 70 44 61 74 61  k->nFile = pData
9470: 2d 3e 6e 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20  ->nName;.       
9480: 20 20 20 70 4c 6f 63 6b 2d 3e 7a 46 69 6c 65 20     pLock->zFile 
9490: 3d 20 26 28 28 63 68 61 72 20 2a 29 28 26 70 4c  = &((char *)(&pL
94a0: 6f 63 6b 5b 31 5d 29 29 5b 70 56 66 73 2d 3e 73  ock[1]))[pVfs->s
94b0: 7a 4f 73 46 69 6c 65 5d 3b 0a 20 20 20 20 20 20  zOsFile];.      
94c0: 20 20 20 20 6d 65 6d 63 70 79 28 70 4c 6f 63 6b      memcpy(pLock
94d0: 2d 3e 7a 46 69 6c 65 2c 20 70 44 61 74 61 2d 3e  ->zFile, pData->
94e0: 7a 4e 61 6d 65 2c 20 70 4c 6f 63 6b 2d 3e 6e 46  zName, pLock->nF
94f0: 69 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ile);.          
9500: 70 4c 6f 63 6b 2d 3e 70 4e 65 78 74 20 3d 20 61  pLock->pNext = a
9510: 73 79 6e 63 2e 70 4c 6f 63 6b 3b 0a 20 20 20 20  sync.pLock;.    
9520: 20 20 20 20 20 20 61 73 79 6e 63 2e 70 4c 6f 63        async.pLoc
9530: 6b 20 3d 20 70 4c 6f 63 6b 3b 0a 20 20 20 20 20  k = pLock;.     
9540: 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65     }.      }else
9550: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  {.        rc = S
9560: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
9570: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
9580: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
9590: 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 2d 3e 70 4d  _OK ){.    p->pM
95a0: 65 74 68 6f 64 20 3d 20 26 61 73 79 6e 63 5f 6d  ethod = &async_m
95b0: 65 74 68 6f 64 73 3b 0a 20 20 20 20 70 2d 3e 70  ethods;.    p->p
95c0: 44 61 74 61 20 3d 20 70 44 61 74 61 3b 0a 0a 20  Data = pData;.. 
95d0: 20 20 20 2f 2a 20 4c 69 6e 6b 20 41 73 79 6e 63     /* Link Async
95e0: 46 69 6c 65 44 61 74 61 2e 6c 6f 63 6b 20 69 6e  FileData.lock in
95f0: 74 6f 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69  to the linked li
9600: 73 74 20 6f 66 20 0a 20 20 20 20 2a 2a 20 41 73  st of .    ** As
9610: 79 6e 63 46 69 6c 65 4c 6f 63 6b 20 73 74 72 75  yncFileLock stru
9620: 63 74 75 72 65 73 20 66 6f 72 20 74 68 69 73 20  ctures for this 
9630: 66 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  file..    */.   
9640: 20 69 66 28 20 7a 4e 61 6d 65 20 29 7b 0a 20 20   if( zName ){.  
9650: 20 20 20 20 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e      pData->lock.
9660: 70 4e 65 78 74 20 3d 20 70 4c 6f 63 6b 2d 3e 70  pNext = pLock->p
9670: 4c 69 73 74 3b 0a 20 20 20 20 20 20 70 4c 6f 63  List;.      pLoc
9680: 6b 2d 3e 70 4c 69 73 74 20 3d 20 26 70 44 61 74  k->pList = &pDat
9690: 61 2d 3e 6c 6f 63 6b 3b 0a 20 20 20 20 20 20 70  a->lock;.      p
96a0: 44 61 74 61 2d 3e 7a 4e 61 6d 65 20 3d 20 70 4c  Data->zName = pL
96b0: 6f 63 6b 2d 3e 7a 46 69 6c 65 3b 0a 20 20 20 20  ock->zFile;.    
96c0: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  }.  }else{.    i
96d0: 66 28 20 70 44 61 74 61 2d 3e 70 42 61 73 65 52  f( pData->pBaseR
96e0: 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b  ead->pMethods ){
96f0: 0a 20 20 20 20 20 20 70 44 61 74 61 2d 3e 70 42  .      pData->pB
9700: 61 73 65 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64  aseRead->pMethod
9710: 73 2d 3e 78 43 6c 6f 73 65 28 70 44 61 74 61 2d  s->xClose(pData-
9720: 3e 70 42 61 73 65 52 65 61 64 29 3b 0a 20 20 20  >pBaseRead);.   
9730: 20 7d 0a 20 20 20 20 69 66 28 20 70 44 61 74 61   }.    if( pData
9740: 2d 3e 70 42 61 73 65 57 72 69 74 65 2d 3e 70 4d  ->pBaseWrite->pM
9750: 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 20 20  ethods ){.      
9760: 70 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74  pData->pBaseWrit
9770: 65 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43 6c  e->pMethods->xCl
9780: 6f 73 65 28 70 44 61 74 61 2d 3e 70 42 61 73 65  ose(pData->pBase
9790: 57 72 69 74 65 29 3b 0a 20 20 20 20 7d 0a 20 20  Write);.    }.  
97a0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
97b0: 44 61 74 61 29 3b 0a 20 20 7d 0a 0a 20 20 70 74  Data);.  }..  pt
97c0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
97d0: 63 6b 28 26 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75  ck(&async.lockMu
97e0: 74 65 78 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  tex);..  if( rc=
97f0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
9800: 20 20 69 6e 63 72 4f 70 65 6e 46 69 6c 65 43 6f    incrOpenFileCo
9810: 75 6e 74 28 29 3b 0a 20 20 20 20 70 44 61 74 61  unt();.    pData
9820: 2d 3e 70 4c 6f 63 6b 20 3d 20 70 4c 6f 63 6b 3b  ->pLock = pLock;
9830: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
9840: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 73 41  SQLITE_OK && isA
9850: 73 79 6e 63 4f 70 65 6e 20 29 7b 0a 20 20 20 20  syncOpen ){.    
9860: 72 63 20 3d 20 61 64 64 4e 65 77 41 73 79 6e 63  rc = addNewAsync
9870: 57 72 69 74 65 28 70 44 61 74 61 2c 20 41 53 59  Write(pData, ASY
9880: 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56 45  NC_OPENEXCLUSIVE
9890: 2c 20 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  , (sqlite3_int64
98a0: 29 66 6c 61 67 73 2c 30 2c 30 29 3b 0a 20 20 20  )flags,0,0);.   
98b0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
98c0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  OK ){.      if( 
98d0: 70 4f 75 74 46 6c 61 67 73 20 29 20 2a 70 4f 75  pOutFlags ) *pOu
98e0: 74 46 6c 61 67 73 20 3d 20 66 6c 61 67 73 3b 0a  tFlags = flags;.
98f0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
9900: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
9910: 6f 63 6b 28 26 61 73 79 6e 63 2e 6c 6f 63 6b 4d  ock(&async.lockM
9920: 75 74 65 78 29 3b 0a 20 20 20 20 20 20 75 6e 6c  utex);.      unl
9930: 69 6e 6b 41 73 79 6e 63 46 69 6c 65 28 70 44 61  inkAsyncFile(pDa
9940: 74 61 29 3b 0a 20 20 20 20 20 20 70 74 68 72 65  ta);.      pthre
9950: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
9960: 26 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65 78  &async.lockMutex
9970: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
9980: 5f 66 72 65 65 28 70 44 61 74 61 29 3b 0a 20 20  _free(pData);.  
9990: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63    }.  }.  if( rc
99a0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
99b0: 20 20 20 70 2d 3e 70 4d 65 74 68 6f 64 20 3d 20     p->pMethod = 
99c0: 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  0;.  }.  return 
99d0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  rc;.}../*.** Imp
99e0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73  lementation of s
99f0: 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 2e 20  qlite3OsDelete. 
9a00: 41 64 64 20 61 6e 20 65 6e 74 72 79 20 74 6f 20  Add an entry to 
9a10: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 0a  the end of the .
9a20: 2a 2a 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75  ** write-op queu
9a30: 65 20 74 6f 20 70 65 72 66 6f 72 6d 20 74 68 65  e to perform the
9a40: 20 64 65 6c 65 74 65 2e 0a 2a 2f 0a 73 74 61 74   delete..*/.stat
9a50: 69 63 20 69 6e 74 20 61 73 79 6e 63 44 65 6c 65  ic int asyncDele
9a60: 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  te(sqlite3_vfs *
9a70: 70 41 73 79 6e 63 56 66 73 2c 20 63 6f 6e 73 74  pAsyncVfs, const
9a80: 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 73 79   char *z, int sy
9a90: 6e 63 44 69 72 29 7b 0a 20 20 72 65 74 75 72 6e  ncDir){.  return
9aa0: 20 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69 74   addNewAsyncWrit
9ab0: 65 28 30 2c 20 41 53 59 4e 43 5f 44 45 4c 45 54  e(0, ASYNC_DELET
9ac0: 45 2c 20 73 79 6e 63 44 69 72 2c 20 73 74 72 6c  E, syncDir, strl
9ad0: 65 6e 28 7a 29 2b 31 2c 20 7a 29 3b 0a 7d 0a 0a  en(z)+1, z);.}..
9ae0: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
9af0: 74 69 6f 6e 20 6f 66 20 73 71 6c 69 74 65 33 4f  tion of sqlite3O
9b00: 73 41 63 63 65 73 73 2e 20 54 68 69 73 20 6d 65  sAccess. This me
9b10: 74 68 6f 64 20 68 6f 6c 64 73 20 74 68 65 20 6d  thod holds the m
9b20: 75 74 65 78 20 66 72 6f 6d 0a 2a 2a 20 73 74 61  utex from.** sta
9b30: 72 74 20 74 6f 20 66 69 6e 69 73 68 2e 0a 2a 2f  rt to finish..*/
9b40: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e  .static int asyn
9b50: 63 41 63 63 65 73 73 28 0a 20 20 73 71 6c 69 74  cAccess(.  sqlit
9b60: 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66  e3_vfs *pAsyncVf
9b70: 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  s, .  const char
9b80: 20 2a 7a 4e 61 6d 65 2c 20 0a 20 20 69 6e 74 20   *zName, .  int 
9b90: 66 6c 61 67 73 2c 0a 20 20 69 6e 74 20 2a 70 52  flags,.  int *pR
9ba0: 65 73 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20 72  esOut.){.  int r
9bb0: 63 3b 0a 20 20 69 6e 74 20 72 65 74 3b 0a 20 20  c;.  int ret;.  
9bc0: 41 73 79 6e 63 57 72 69 74 65 20 2a 70 3b 0a 20  AsyncWrite *p;. 
9bd0: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
9be0: 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66  fs = (sqlite3_vf
9bf0: 73 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70  s *)pAsyncVfs->p
9c00: 41 70 70 44 61 74 61 3b 0a 0a 20 20 61 73 73 65  AppData;..  asse
9c10: 72 74 28 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45  rt(flags==SQLITE
9c20: 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52 49 54  _ACCESS_READWRIT
9c30: 45 20 0a 20 20 20 20 20 20 7c 7c 20 66 6c 61 67  E .      || flag
9c40: 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45 53 53  s==SQLITE_ACCESS
9c50: 5f 52 45 41 44 20 0a 20 20 20 20 20 20 7c 7c 20  _READ .      || 
9c60: 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43  flags==SQLITE_AC
9c70: 43 45 53 53 5f 45 58 49 53 54 53 20 0a 20 20 29  CESS_EXISTS .  )
9c80: 3b 0a 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74  ;..  pthread_mut
9c90: 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 71  ex_lock(&async.q
9ca0: 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20 72 63  ueueMutex);.  rc
9cb0: 20 3d 20 70 56 66 73 2d 3e 78 41 63 63 65 73 73   = pVfs->xAccess
9cc0: 28 70 56 66 73 2c 20 7a 4e 61 6d 65 2c 20 66 6c  (pVfs, zName, fl
9cd0: 61 67 73 2c 20 26 72 65 74 29 3b 0a 20 20 69 66  ags, &ret);.  if
9ce0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
9cf0: 26 26 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45  && flags==SQLITE
9d00: 5f 41 43 43 45 53 53 5f 45 58 49 53 54 53 20 29  _ACCESS_EXISTS )
9d10: 7b 0a 20 20 20 20 66 6f 72 28 70 3d 61 73 79 6e  {.    for(p=asyn
9d20: 63 2e 70 51 75 65 75 65 46 69 72 73 74 3b 20 70  c.pQueueFirst; p
9d30: 3b 20 70 20 3d 20 70 2d 3e 70 4e 65 78 74 29 7b  ; p = p->pNext){
9d40: 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e 6f 70  .      if( p->op
9d50: 3d 3d 41 53 59 4e 43 5f 44 45 4c 45 54 45 20 26  ==ASYNC_DELETE &
9d60: 26 20 30 3d 3d 73 74 72 63 6d 70 28 70 2d 3e 7a  & 0==strcmp(p->z
9d70: 42 75 66 2c 20 7a 4e 61 6d 65 29 20 29 7b 0a 20  Buf, zName) ){. 
9d80: 20 20 20 20 20 20 20 72 65 74 20 3d 20 30 3b 0a         ret = 0;.
9d90: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
9da0: 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f 4f 50 45  p->op==ASYNC_OPE
9db0: 4e 45 58 43 4c 55 53 49 56 45 20 0a 20 20 20 20  NEXCLUSIVE .    
9dc0: 20 20 20 20 20 20 20 20 20 26 26 20 70 2d 3e 70           && p->p
9dd0: 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65 0a  FileData->zName.
9de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 26 26 20               && 
9df0: 30 3d 3d 73 74 72 63 6d 70 28 70 2d 3e 70 46 69  0==strcmp(p->pFi
9e00: 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 7a  leData->zName, z
9e10: 4e 61 6d 65 29 20 0a 20 20 20 20 20 20 29 7b 0a  Name) .      ){.
9e20: 20 20 20 20 20 20 20 20 72 65 74 20 3d 20 31 3b          ret = 1;
9e30: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
9e40: 20 7d 0a 20 20 41 53 59 4e 43 5f 54 52 41 43 45   }.  ASYNC_TRACE
9e50: 28 28 22 41 43 43 45 53 53 28 25 73 29 3a 20 25  (("ACCESS(%s): %
9e60: 73 20 3d 20 25 64 5c 6e 22 2c 20 0a 20 20 20 20  s = %d\n", .    
9e70: 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43  flags==SQLITE_AC
9e80: 43 45 53 53 5f 52 45 41 44 57 52 49 54 45 3f 22  CESS_READWRITE?"
9e90: 72 65 61 64 2d 77 72 69 74 65 22 3a 0a 20 20 20  read-write":.   
9ea0: 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41   flags==SQLITE_A
9eb0: 43 43 45 53 53 5f 52 45 41 44 3f 22 72 65 61 64  CCESS_READ?"read
9ec0: 22 3a 22 65 78 69 73 74 73 22 0a 20 20 20 20 2c  ":"exists".    ,
9ed0: 20 7a 4e 61 6d 65 2c 20 72 65 74 29 0a 20 20 29   zName, ret).  )
9ee0: 3b 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65  ;.  pthread_mute
9ef0: 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79 6e 63 2e  x_unlock(&async.
9f00: 71 75 65 75 65 4d 75 74 65 78 29 3b 0a 20 20 2a  queueMutex);.  *
9f10: 70 52 65 73 4f 75 74 20 3d 20 72 65 74 3b 0a 20  pResOut = ret;. 
9f20: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
9f30: 2a 0a 2a 2a 20 46 69 6c 6c 20 69 6e 20 7a 50 61  *.** Fill in zPa
9f40: 74 68 4f 75 74 20 77 69 74 68 20 74 68 65 20 66  thOut with the f
9f50: 75 6c 6c 20 70 61 74 68 20 74 6f 20 74 68 65 20  ull path to the 
9f60: 66 69 6c 65 20 69 64 65 6e 74 69 66 69 65 64 20  file identified 
9f70: 62 79 20 7a 50 61 74 68 2e 0a 2a 2f 0a 73 74 61  by zPath..*/.sta
9f80: 74 69 63 20 69 6e 74 20 61 73 79 6e 63 46 75 6c  tic int asyncFul
9f90: 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 73 71 6c  lPathname(.  sql
9fa0: 69 74 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63  ite3_vfs *pAsync
9fb0: 56 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  Vfs, .  const ch
9fc0: 61 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e  ar *zPath, .  in
9fd0: 74 20 6e 50 61 74 68 4f 75 74 2c 0a 20 20 63 68  t nPathOut,.  ch
9fe0: 61 72 20 2a 7a 50 61 74 68 4f 75 74 0a 29 7b 0a  ar *zPathOut.){.
9ff0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69    int rc;.  sqli
a000: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20 3d 20  te3_vfs *pVfs = 
a010: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 29 70  (sqlite3_vfs *)p
a020: 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70 44 61  AsyncVfs->pAppDa
a030: 74 61 3b 0a 20 20 72 63 20 3d 20 70 56 66 73 2d  ta;.  rc = pVfs-
a040: 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 70  >xFullPathname(p
a050: 56 66 73 2c 20 7a 50 61 74 68 2c 20 6e 50 61 74  Vfs, zPath, nPat
a060: 68 4f 75 74 2c 20 7a 50 61 74 68 4f 75 74 29 3b  hOut, zPathOut);
a070: 0a 0a 20 20 2f 2a 20 42 65 63 61 75 73 65 20 6f  ..  /* Because o
a080: 66 20 74 68 65 20 77 61 79 20 69 6e 74 72 61 2d  f the way intra-
a090: 70 72 6f 63 65 73 73 20 66 69 6c 65 20 6c 6f 63  process file loc
a0a0: 6b 69 6e 67 20 77 6f 72 6b 73 2c 20 74 68 69 73  king works, this
a0b0: 20 62 61 63 6b 65 6e 64 0a 20 20 2a 2a 20 6e 65   backend.  ** ne
a0c0: 65 64 73 20 74 6f 20 72 65 74 75 72 6e 20 61 20  eds to return a 
a0d0: 63 61 6e 6f 6e 69 63 61 6c 20 70 61 74 68 2e 20  canonical path. 
a0e0: 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c  The following bl
a0f0: 6f 63 6b 20 61 73 73 75 6d 65 73 20 74 68 65 0a  ock assumes the.
a100: 20 20 2a 2a 20 66 69 6c 65 2d 73 79 73 74 65 6d    ** file-system
a110: 20 75 73 65 73 20 75 6e 69 78 20 73 74 79 6c 65   uses unix style
a120: 20 70 61 74 68 73 2e 20 0a 20 20 2a 2f 0a 20 20   paths. .  */.  
a130: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
a140: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20  K ){.    int i, 
a150: 6a 3b 0a 20 20 20 20 69 6e 74 20 6e 20 3d 20 6e  j;.    int n = n
a160: 50 61 74 68 4f 75 74 3b 0a 20 20 20 20 63 68 61  PathOut;.    cha
a170: 72 20 2a 7a 20 3d 20 7a 50 61 74 68 4f 75 74 3b  r *z = zPathOut;
a180: 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 3e 31 20  .    while( n>1 
a190: 26 26 20 7a 5b 6e 2d 31 5d 3d 3d 27 2f 27 20 29  && z[n-1]=='/' )
a1a0: 7b 20 6e 2d 2d 3b 20 7d 0a 20 20 20 20 66 6f 72  { n--; }.    for
a1b0: 28 69 3d 6a 3d 30 3b 20 69 3c 6e 3b 20 69 2b 2b  (i=j=0; i<n; i++
a1c0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a 5b 69  ){.      if( z[i
a1d0: 5d 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20 20  ]=='/' ){.      
a1e0: 20 20 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2f    if( z[i+1]=='/
a1f0: 27 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20  ' ) continue;.  
a200: 20 20 20 20 20 20 69 66 28 20 7a 5b 69 2b 31 5d        if( z[i+1]
a210: 3d 3d 27 2e 27 20 26 26 20 69 2b 32 3c 6e 20 26  =='.' && i+2<n &
a220: 26 20 7a 5b 69 2b 32 5d 3d 3d 27 2f 27 20 29 7b  & z[i+2]=='/' ){
a230: 0a 20 20 20 20 20 20 20 20 20 20 69 20 2b 3d 20  .          i += 
a240: 31 3b 0a 20 20 20 20 20 20 20 20 20 20 63 6f 6e  1;.          con
a250: 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 7d  tinue;.        }
a260: 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b 69  .        if( z[i
a270: 2b 31 5d 3d 3d 27 2e 27 20 26 26 20 69 2b 33 3c  +1]=='.' && i+3<
a280: 6e 20 26 26 20 7a 5b 69 2b 32 5d 3d 3d 27 2e 27  n && z[i+2]=='.'
a290: 20 26 26 20 7a 5b 69 2b 33 5d 3d 3d 27 2f 27 20   && z[i+3]=='/' 
a2a0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 77 68 69  ){.          whi
a2b0: 6c 65 28 20 6a 3e 30 20 26 26 20 7a 5b 6a 2d 31  le( j>0 && z[j-1
a2c0: 5d 21 3d 27 2f 27 20 29 7b 20 6a 2d 2d 3b 20 7d  ]!='/' ){ j--; }
a2d0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 6a  .          if( j
a2e0: 3e 30 20 29 7b 20 6a 2d 2d 3b 20 7d 0a 20 20 20  >0 ){ j--; }.   
a2f0: 20 20 20 20 20 20 20 69 20 2b 3d 20 32 3b 0a 20         i += 2;. 
a300: 20 20 20 20 20 20 20 20 20 63 6f 6e 74 69 6e 75           continu
a310: 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  e;.        }.   
a320: 20 20 20 7d 0a 20 20 20 20 20 20 7a 5b 6a 2b 2b     }.      z[j++
a330: 5d 20 3d 20 7a 5b 69 5d 3b 0a 20 20 20 20 7d 0a  ] = z[i];.    }.
a340: 20 20 20 20 7a 5b 6a 5d 20 3d 20 30 3b 0a 20 20      z[j] = 0;.  
a350: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
a360: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 61  }.static void *a
a370: 73 79 6e 63 44 6c 4f 70 65 6e 28 73 71 6c 69 74  syncDlOpen(sqlit
a380: 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66  e3_vfs *pAsyncVf
a390: 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  s, const char *z
a3a0: 50 61 74 68 29 7b 0a 20 20 73 71 6c 69 74 65 33  Path){.  sqlite3
a3b0: 5f 76 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71  _vfs *pVfs = (sq
a3c0: 6c 69 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79  lite3_vfs *)pAsy
a3d0: 6e 63 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  ncVfs->pAppData;
a3e0: 0a 20 20 72 65 74 75 72 6e 20 70 56 66 73 2d 3e  .  return pVfs->
a3f0: 78 44 6c 4f 70 65 6e 28 70 56 66 73 2c 20 7a 50  xDlOpen(pVfs, zP
a400: 61 74 68 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76  ath);.}.static v
a410: 6f 69 64 20 61 73 79 6e 63 44 6c 45 72 72 6f 72  oid asyncDlError
a420: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 41  (sqlite3_vfs *pA
a430: 73 79 6e 63 56 66 73 2c 20 69 6e 74 20 6e 42 79  syncVfs, int nBy
a440: 74 65 2c 20 63 68 61 72 20 2a 7a 45 72 72 4d 73  te, char *zErrMs
a450: 67 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  g){.  sqlite3_vf
a460: 73 20 2a 70 56 66 73 20 3d 20 28 73 71 6c 69 74  s *pVfs = (sqlit
a470: 65 33 5f 76 66 73 20 2a 29 70 41 73 79 6e 63 56  e3_vfs *)pAsyncV
a480: 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20  fs->pAppData;.  
a490: 70 56 66 73 2d 3e 78 44 6c 45 72 72 6f 72 28 70  pVfs->xDlError(p
a4a0: 56 66 73 2c 20 6e 42 79 74 65 2c 20 7a 45 72 72  Vfs, nByte, zErr
a4b0: 4d 73 67 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76  Msg);.}.static v
a4c0: 6f 69 64 20 28 2a 61 73 79 6e 63 44 6c 53 79 6d  oid (*asyncDlSym
a4d0: 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  (.  sqlite3_vfs 
a4e0: 2a 70 41 73 79 6e 63 56 66 73 2c 20 0a 20 20 76  *pAsyncVfs, .  v
a4f0: 6f 69 64 20 2a 70 48 61 6e 64 6c 65 2c 20 0a 20  oid *pHandle, . 
a500: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 79   const char *zSy
a510: 6d 62 6f 6c 0a 29 29 28 76 6f 69 64 29 7b 0a 20  mbol.))(void){. 
a520: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
a530: 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66  fs = (sqlite3_vf
a540: 73 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70  s *)pAsyncVfs->p
a550: 41 70 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72  AppData;.  retur
a560: 6e 20 70 56 66 73 2d 3e 78 44 6c 53 79 6d 28 70  n pVfs->xDlSym(p
a570: 56 66 73 2c 20 70 48 61 6e 64 6c 65 2c 20 7a 53  Vfs, pHandle, zS
a580: 79 6d 62 6f 6c 29 3b 0a 7d 0a 73 74 61 74 69 63  ymbol);.}.static
a590: 20 76 6f 69 64 20 61 73 79 6e 63 44 6c 43 6c 6f   void asyncDlClo
a5a0: 73 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  se(sqlite3_vfs *
a5b0: 70 41 73 79 6e 63 56 66 73 2c 20 76 6f 69 64 20  pAsyncVfs, void 
a5c0: 2a 70 48 61 6e 64 6c 65 29 7b 0a 20 20 73 71 6c  *pHandle){.  sql
a5d0: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20 3d  ite3_vfs *pVfs =
a5e0: 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 29   (sqlite3_vfs *)
a5f0: 70 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70 44  pAsyncVfs->pAppD
a600: 61 74 61 3b 0a 20 20 70 56 66 73 2d 3e 78 44 6c  ata;.  pVfs->xDl
a610: 43 6c 6f 73 65 28 70 56 66 73 2c 20 70 48 61 6e  Close(pVfs, pHan
a620: 64 6c 65 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  dle);.}.static i
a630: 6e 74 20 61 73 79 6e 63 52 61 6e 64 6f 6d 6e 65  nt asyncRandomne
a640: 73 73 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  ss(sqlite3_vfs *
a650: 70 41 73 79 6e 63 56 66 73 2c 20 69 6e 74 20 6e  pAsyncVfs, int n
a660: 42 79 74 65 2c 20 63 68 61 72 20 2a 7a 42 75 66  Byte, char *zBuf
a670: 4f 75 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  Out){.  sqlite3_
a680: 76 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71 6c  vfs *pVfs = (sql
a690: 69 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79 6e  ite3_vfs *)pAsyn
a6a0: 63 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  cVfs->pAppData;.
a6b0: 20 20 72 65 74 75 72 6e 20 70 56 66 73 2d 3e 78    return pVfs->x
a6c0: 52 61 6e 64 6f 6d 6e 65 73 73 28 70 56 66 73 2c  Randomness(pVfs,
a6d0: 20 6e 42 79 74 65 2c 20 7a 42 75 66 4f 75 74 29   nByte, zBufOut)
a6e0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 61  ;.}.static int a
a6f0: 73 79 6e 63 53 6c 65 65 70 28 73 71 6c 69 74 65  syncSleep(sqlite
a700: 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66 73  3_vfs *pAsyncVfs
a710: 2c 20 69 6e 74 20 6e 4d 69 63 72 6f 29 7b 0a 20  , int nMicro){. 
a720: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
a730: 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66  fs = (sqlite3_vf
a740: 73 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70  s *)pAsyncVfs->p
a750: 41 70 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72  AppData;.  retur
a760: 6e 20 70 56 66 73 2d 3e 78 53 6c 65 65 70 28 70  n pVfs->xSleep(p
a770: 56 66 73 2c 20 6e 4d 69 63 72 6f 29 3b 0a 7d 0a  Vfs, nMicro);.}.
a780: 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63  static int async
a790: 43 75 72 72 65 6e 74 54 69 6d 65 28 73 71 6c 69  CurrentTime(sqli
a7a0: 74 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56  te3_vfs *pAsyncV
a7b0: 66 73 2c 20 64 6f 75 62 6c 65 20 2a 70 54 69 6d  fs, double *pTim
a7c0: 65 4f 75 74 29 7b 0a 20 20 73 71 6c 69 74 65 33  eOut){.  sqlite3
a7d0: 5f 76 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71  _vfs *pVfs = (sq
a7e0: 6c 69 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79  lite3_vfs *)pAsy
a7f0: 6e 63 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  ncVfs->pAppData;
a800: 0a 20 20 72 65 74 75 72 6e 20 70 56 66 73 2d 3e  .  return pVfs->
a810: 78 43 75 72 72 65 6e 74 54 69 6d 65 28 70 56 66  xCurrentTime(pVf
a820: 73 2c 20 70 54 69 6d 65 4f 75 74 29 3b 0a 7d 0a  s, pTimeOut);.}.
a830: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
a840: 76 66 73 20 61 73 79 6e 63 5f 76 66 73 20 3d 20  vfs async_vfs = 
a850: 7b 0a 20 20 31 2c 20 20 20 20 20 20 20 20 20 20  {.  1,          
a860: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65            /* iVe
a870: 72 73 69 6f 6e 20 2a 2f 0a 20 20 73 69 7a 65 6f  rsion */.  sizeo
a880: 66 28 41 73 79 6e 63 46 69 6c 65 29 2c 20 20 20  f(AsyncFile),   
a890: 20 2f 2a 20 73 7a 4f 73 46 69 6c 65 20 2a 2f 0a   /* szOsFile */.
a8a0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
a8b0: 20 20 20 20 20 20 20 20 2f 2a 20 6d 78 50 61 74          /* mxPat
a8c0: 68 6e 61 6d 65 20 2a 2f 0a 20 20 30 2c 20 20 20  hname */.  0,   
a8d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a8e0: 20 2f 2a 20 70 4e 65 78 74 20 2a 2f 0a 20 20 22   /* pNext */.  "
a8f0: 61 73 79 6e 63 22 2c 20 20 20 20 20 20 20 20 20  async",         
a900: 20 20 20 20 20 2f 2a 20 7a 4e 61 6d 65 20 2a 2f       /* zName */
a910: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
a920: 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 70 70           /* pApp
a930: 44 61 74 61 20 2a 2f 0a 20 20 61 73 79 6e 63 4f  Data */.  asyncO
a940: 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  pen,            
a950: 2f 2a 20 78 4f 70 65 6e 20 2a 2f 0a 20 20 61 73  /* xOpen */.  as
a960: 79 6e 63 44 65 6c 65 74 65 2c 20 20 20 20 20 20  yncDelete,      
a970: 20 20 20 20 2f 2a 20 78 44 65 6c 65 74 65 20 2a      /* xDelete *
a980: 2f 0a 20 20 61 73 79 6e 63 41 63 63 65 73 73 2c  /.  asyncAccess,
a990: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 41 63            /* xAc
a9a0: 63 65 73 73 20 2a 2f 0a 20 20 61 73 79 6e 63 46  cess */.  asyncF
a9b0: 75 6c 6c 50 61 74 68 6e 61 6d 65 2c 20 20 20 20  ullPathname,    
a9c0: 2f 2a 20 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65  /* xFullPathname
a9d0: 20 2a 2f 0a 20 20 61 73 79 6e 63 44 6c 4f 70 65   */.  asyncDlOpe
a9e0: 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  n,          /* x
a9f0: 44 6c 4f 70 65 6e 20 2a 2f 0a 20 20 61 73 79 6e  DlOpen */.  asyn
aa00: 63 44 6c 45 72 72 6f 72 2c 20 20 20 20 20 20 20  cDlError,       
aa10: 20 20 2f 2a 20 78 44 6c 45 72 72 6f 72 20 2a 2f    /* xDlError */
aa20: 0a 20 20 61 73 79 6e 63 44 6c 53 79 6d 2c 20 20  .  asyncDlSym,  
aa30: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 53           /* xDlS
aa40: 79 6d 20 2a 2f 0a 20 20 61 73 79 6e 63 44 6c 43  ym */.  asyncDlC
aa50: 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 2f 2a  lose,         /*
aa60: 20 78 44 6c 43 6c 6f 73 65 20 2a 2f 0a 20 20 61   xDlClose */.  a
aa70: 73 79 6e 63 52 61 6e 64 6f 6d 6e 65 73 73 2c 20  syncRandomness, 
aa80: 20 20 20 20 20 2f 2a 20 78 44 6c 45 72 72 6f 72       /* xDlError
aa90: 20 2a 2f 0a 20 20 61 73 79 6e 63 53 6c 65 65 70   */.  asyncSleep
aaa0: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  ,           /* x
aab0: 44 6c 53 79 6d 20 2a 2f 0a 20 20 61 73 79 6e 63  DlSym */.  async
aac0: 43 75 72 72 65 6e 74 54 69 6d 65 20 20 20 20 20  CurrentTime     
aad0: 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20 2a 2f 0a   /* xDlClose */.
aae0: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 61 6c 6c 20 74  };../*.** Call t
aaf0: 68 69 73 20 72 6f 75 74 69 6e 65 20 74 6f 20 65  his routine to e
ab00: 6e 61 62 6c 65 20 6f 72 20 64 69 73 61 62 6c 65  nable or disable
ab10: 20 74 68 65 0a 2a 2a 20 61 73 79 6e 63 68 72 6f   the.** asynchro
ab20: 6e 6f 75 73 20 49 4f 20 66 65 61 74 75 72 65 73  nous IO features
ab30: 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 69 6e 20   implemented in 
ab40: 74 68 69 73 20 66 69 6c 65 2e 20 0a 2a 2a 0a 2a  this file. .**.*
ab50: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69  * This routine i
ab60: 73 20 6e 6f 74 20 65 76 65 6e 20 72 65 6d 6f 74  s not even remot
ab70: 65 6c 79 20 74 68 72 65 61 64 73 61 66 65 2e 20  ely threadsafe. 
ab80: 20 44 6f 20 6e 6f 74 20 63 61 6c 6c 0a 2a 2a 20   Do not call.** 
ab90: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 68 69  this routine whi
aba0: 6c 65 20 61 6e 79 20 53 51 4c 69 74 65 20 64 61  le any SQLite da
abb0: 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f  tabase connectio
abc0: 6e 73 20 61 72 65 20 6f 70 65 6e 2e 0a 2a 2f 0a  ns are open..*/.
abd0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 73 79 6e  static void asyn
abe0: 63 45 6e 61 62 6c 65 28 69 6e 74 20 65 6e 61 62  cEnable(int enab
abf0: 6c 65 29 7b 0a 20 20 69 66 28 20 65 6e 61 62 6c  le){.  if( enabl
ac00: 65 20 29 7b 0a 20 20 20 20 69 66 28 20 21 61 73  e ){.    if( !as
ac10: 79 6e 63 5f 76 66 73 2e 70 41 70 70 44 61 74 61  ync_vfs.pAppData
ac20: 20 29 7b 0a 20 20 20 20 20 20 61 73 79 6e 63 5f   ){.      async_
ac30: 76 66 73 2e 70 41 70 70 44 61 74 61 20 3d 20 28  vfs.pAppData = (
ac40: 76 6f 69 64 20 2a 29 73 71 6c 69 74 65 33 5f 76  void *)sqlite3_v
ac50: 66 73 5f 66 69 6e 64 28 30 29 3b 0a 20 20 20 20  fs_find(0);.    
ac60: 20 20 61 73 79 6e 63 5f 76 66 73 2e 6d 78 50 61    async_vfs.mxPa
ac70: 74 68 6e 61 6d 65 20 3d 20 28 28 73 71 6c 69 74  thname = ((sqlit
ac80: 65 33 5f 76 66 73 20 2a 29 61 73 79 6e 63 5f 76  e3_vfs *)async_v
ac90: 66 73 2e 70 41 70 70 44 61 74 61 29 2d 3e 6d 78  fs.pAppData)->mx
aca0: 50 61 74 68 6e 61 6d 65 3b 0a 20 20 20 20 20 20  Pathname;.      
acb0: 73 71 6c 69 74 65 33 5f 76 66 73 5f 72 65 67 69  sqlite3_vfs_regi
acc0: 73 74 65 72 28 26 61 73 79 6e 63 5f 76 66 73 2c  ster(&async_vfs,
acd0: 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c   1);.    }.  }el
ace0: 73 65 7b 0a 20 20 20 20 69 66 28 20 61 73 79 6e  se{.    if( asyn
acf0: 63 5f 76 66 73 2e 70 41 70 70 44 61 74 61 20 29  c_vfs.pAppData )
ad00: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
ad10: 76 66 73 5f 75 6e 72 65 67 69 73 74 65 72 28 26  vfs_unregister(&
ad20: 61 73 79 6e 63 5f 76 66 73 29 3b 0a 20 20 20 20  async_vfs);.    
ad30: 20 20 61 73 79 6e 63 5f 76 66 73 2e 70 41 70 70    async_vfs.pApp
ad40: 44 61 74 61 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Data = 0;.    }.
ad50: 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68    }.}../* .** Th
ad60: 69 73 20 70 72 6f 63 65 64 75 72 65 20 72 75 6e  is procedure run
ad70: 73 20 69 6e 20 61 20 73 65 70 61 72 61 74 65 20  s in a separate 
ad80: 74 68 72 65 61 64 2c 20 72 65 61 64 69 6e 67 20  thread, reading 
ad90: 6d 65 73 73 61 67 65 73 20 6f 66 66 20 6f 66 20  messages off of 
ada0: 74 68 65 0a 2a 2a 20 77 72 69 74 65 20 71 75 65  the.** write que
adb0: 75 65 20 61 6e 64 20 70 72 6f 63 65 73 73 69 6e  ue and processin
adc0: 67 20 74 68 65 6d 20 6f 6e 65 20 62 79 20 6f 6e  g them one by on
add0: 65 2e 20 20 0a 2a 2a 0a 2a 2a 20 49 66 20 61 73  e.  .**.** If as
ade0: 79 6e 63 2e 77 72 69 74 65 72 48 61 6c 74 4e 6f  ync.writerHaltNo
adf0: 77 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20  w is true, then 
ae00: 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 65  this procedure e
ae10: 78 69 74 73 0a 2a 2a 20 61 66 74 65 72 20 70 72  xits.** after pr
ae20: 6f 63 65 73 73 69 6e 67 20 61 20 73 69 6e 67 6c  ocessing a singl
ae30: 65 20 6d 65 73 73 61 67 65 2e 0a 2a 2a 0a 2a 2a  e message..**.**
ae40: 20 49 66 20 61 73 79 6e 63 2e 77 72 69 74 65 72   If async.writer
ae50: 48 61 6c 74 57 68 65 6e 49 64 6c 65 20 69 73 20  HaltWhenIdle is 
ae60: 74 72 75 65 2c 20 74 68 65 6e 20 74 68 69 73 20  true, then this 
ae70: 70 72 6f 63 65 64 75 72 65 20 65 78 69 74 73 20  procedure exits 
ae80: 77 68 65 6e 0a 2a 2a 20 74 68 65 20 77 72 69 74  when.** the writ
ae90: 65 20 71 75 65 75 65 20 69 73 20 65 6d 70 74 79  e queue is empty
aea0: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 62 6f 74 68 20  ..**.** If both 
aeb0: 6f 66 20 74 68 65 20 61 62 6f 76 65 20 76 61 72  of the above var
aec0: 69 61 62 6c 65 73 20 61 72 65 20 66 61 6c 73 65  iables are false
aed0: 2c 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65  , this procedure
aee0: 20 72 75 6e 73 0a 2a 2a 20 69 6e 64 65 66 69 6e   runs.** indefin
aef0: 61 74 65 6c 79 2c 20 77 61 69 74 69 6e 67 20 66  ately, waiting f
af00: 6f 72 20 6f 70 65 72 61 74 69 6f 6e 73 20 74 6f  or operations to
af10: 20 62 65 20 61 64 64 65 64 20 74 6f 20 74 68 65   be added to the
af20: 20 77 72 69 74 65 20 71 75 65 75 65 0a 2a 2a 20   write queue.** 
af30: 61 6e 64 20 70 72 6f 63 65 73 73 69 6e 67 20 74  and processing t
af40: 68 65 6d 20 69 6e 20 74 68 65 20 6f 72 64 65 72  hem in the order
af50: 20 69 6e 20 77 68 69 63 68 20 74 68 65 79 20 61   in which they a
af60: 72 72 69 76 65 2e 0a 2a 2a 0a 2a 2a 20 41 6e 20  rrive..**.** An 
af70: 61 72 74 69 66 69 63 61 6c 20 64 65 6c 61 79 20  artifical delay 
af80: 6f 66 20 61 73 79 6e 63 2e 69 6f 44 65 6c 61 79  of async.ioDelay
af90: 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73 20 69 73   milliseconds is
afa0: 20 69 6e 73 65 72 74 65 64 20 62 65 66 6f 72 65   inserted before
afb0: 0a 2a 2a 20 65 61 63 68 20 77 72 69 74 65 20 6f  .** each write o
afc0: 70 65 72 61 74 69 6f 6e 20 69 6e 20 6f 72 64 65  peration in orde
afd0: 72 20 74 6f 20 73 69 6d 75 6c 61 74 65 20 74 68  r to simulate th
afe0: 65 20 65 66 66 65 63 74 20 6f 66 20 61 20 73 6c  e effect of a sl
aff0: 6f 77 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a 20 4f  ow disk..**.** O
b000: 6e 6c 79 20 6f 6e 65 20 69 6e 73 74 61 6e 63 65  nly one instance
b010: 20 6f 66 20 74 68 69 73 20 70 72 6f 63 65 64 75   of this procedu
b020: 72 65 20 6d 61 79 20 62 65 20 72 75 6e 6e 69 6e  re may be runnin
b030: 67 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2f 0a  g at a time..*/.
b040: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 61 73 79  static void *asy
b050: 6e 63 57 72 69 74 65 72 54 68 72 65 61 64 28 76  ncWriterThread(v
b060: 6f 69 64 20 2a 70 49 73 53 74 61 72 74 65 64 29  oid *pIsStarted)
b070: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  {.  sqlite3_vfs 
b080: 2a 70 56 66 73 20 3d 20 28 73 71 6c 69 74 65 33  *pVfs = (sqlite3
b090: 5f 76 66 73 20 2a 29 28 61 73 79 6e 63 5f 76 66  _vfs *)(async_vf
b0a0: 73 2e 70 41 70 70 44 61 74 61 29 3b 0a 20 20 41  s.pAppData);.  A
b0b0: 73 79 6e 63 57 72 69 74 65 20 2a 70 20 3d 20 30  syncWrite *p = 0
b0c0: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
b0d0: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 68 6f  ITE_OK;.  int ho
b0e0: 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20 30 3b 0a  ldingMutex = 0;.
b0f0: 0a 20 20 69 66 28 20 70 74 68 72 65 61 64 5f 6d  .  if( pthread_m
b100: 75 74 65 78 5f 74 72 79 6c 6f 63 6b 28 26 61 73  utex_trylock(&as
b110: 79 6e 63 2e 77 72 69 74 65 72 4d 75 74 65 78 29  ync.writerMutex)
b120: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30   ){.    return 0
b130: 3b 0a 20 20 7d 0a 20 20 28 2a 28 69 6e 74 20 2a  ;.  }.  (*(int *
b140: 29 70 49 73 53 74 61 72 74 65 64 29 20 3d 20 31  )pIsStarted) = 1
b150: 3b 0a 20 20 77 68 69 6c 65 28 20 61 73 79 6e 63  ;.  while( async
b160: 2e 77 72 69 74 65 72 48 61 6c 74 4e 6f 77 3d 3d  .writerHaltNow==
b170: 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 64 6f 4e  0 ){.    int doN
b180: 6f 74 46 72 65 65 20 3d 20 30 3b 0a 20 20 20 20  otFree = 0;.    
b190: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 42  sqlite3_file *pB
b1a0: 61 73 65 20 3d 20 30 3b 0a 0a 20 20 20 20 69 66  ase = 0;..    if
b1b0: 28 20 21 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20  ( !holdingMutex 
b1c0: 29 7b 0a 20 20 20 20 20 20 70 74 68 72 65 61 64  ){.      pthread
b1d0: 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79  _mutex_lock(&asy
b1e0: 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b 0a  nc.queueMutex);.
b1f0: 20 20 20 20 7d 0a 20 20 20 20 77 68 69 6c 65 28      }.    while(
b200: 20 28 70 20 3d 20 61 73 79 6e 63 2e 70 51 75 65   (p = async.pQue
b210: 75 65 46 69 72 73 74 29 3d 3d 30 20 29 7b 0a 20  ueFirst)==0 ){. 
b220: 20 20 20 20 20 70 74 68 72 65 61 64 5f 63 6f 6e       pthread_con
b230: 64 5f 62 72 6f 61 64 63 61 73 74 28 26 61 73 79  d_broadcast(&asy
b240: 6e 63 2e 65 6d 70 74 79 53 69 67 6e 61 6c 29 3b  nc.emptySignal);
b250: 0a 20 20 20 20 20 20 69 66 28 20 61 73 79 6e 63  .      if( async
b260: 2e 77 72 69 74 65 72 48 61 6c 74 57 68 65 6e 49  .writerHaltWhenI
b270: 64 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20 70  dle ){.        p
b280: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
b290: 6f 63 6b 28 26 61 73 79 6e 63 2e 71 75 65 75 65  ock(&async.queue
b2a0: 4d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 20 20  Mutex);.        
b2b0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65 6c  break;.      }el
b2c0: 73 65 7b 0a 20 20 20 20 20 20 20 20 41 53 59 4e  se{.        ASYN
b2d0: 43 5f 54 52 41 43 45 28 28 22 49 44 4c 45 5c 6e  C_TRACE(("IDLE\n
b2e0: 22 29 29 3b 0a 20 20 20 20 20 20 20 20 70 74 68  "));.        pth
b2f0: 72 65 61 64 5f 63 6f 6e 64 5f 77 61 69 74 28 26  read_cond_wait(&
b300: 61 73 79 6e 63 2e 71 75 65 75 65 53 69 67 6e 61  async.queueSigna
b310: 6c 2c 20 26 61 73 79 6e 63 2e 71 75 65 75 65 4d  l, &async.queueM
b320: 75 74 65 78 29 3b 0a 20 20 20 20 20 20 20 20 41  utex);.        A
b330: 53 59 4e 43 5f 54 52 41 43 45 28 28 22 57 41 4b  SYNC_TRACE(("WAK
b340: 45 55 50 5c 6e 22 29 29 3b 0a 20 20 20 20 20 20  EUP\n"));.      
b350: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  }.    }.    if( 
b360: 70 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  p==0 ) break;.  
b370: 20 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d    holdingMutex =
b380: 20 31 3b 0a 0a 20 20 20 20 2f 2a 20 52 69 67 68   1;..    /* Righ
b390: 74 20 6e 6f 77 20 74 68 69 73 20 74 68 72 65 61  t now this threa
b3a0: 64 20 69 73 20 68 6f 6c 64 69 6e 67 20 74 68 65  d is holding the
b3b0: 20 6d 75 74 65 78 20 6f 6e 20 74 68 65 20 77 72   mutex on the wr
b3c0: 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 0a 20 20  ite-op queue..  
b3d0: 20 20 2a 2a 20 56 61 72 69 61 62 6c 65 20 27 70    ** Variable 'p
b3e0: 27 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20  ' points to the 
b3f0: 66 69 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74  first entry in t
b400: 68 65 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75  he write-op queu
b410: 65 2e 20 49 6e 0a 20 20 20 20 2a 2a 20 74 68 65  e. In.    ** the
b420: 20 67 65 6e 65 72 61 6c 20 63 61 73 65 2c 20 77   general case, w
b430: 65 20 68 6f 6c 64 20 6f 6e 20 74 6f 20 74 68 65  e hold on to the
b440: 20 6d 75 74 65 78 20 66 6f 72 20 74 68 65 20 65   mutex for the e
b450: 6e 74 69 72 65 20 62 6f 64 79 20 6f 66 0a 20 20  ntire body of.  
b460: 20 20 2a 2a 20 74 68 65 20 6c 6f 6f 70 2e 20 0a    ** the loop. .
b470: 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 48 6f      **.    ** Ho
b480: 77 65 76 65 72 20 69 6e 20 74 68 65 20 63 61 73  wever in the cas
b490: 65 73 20 65 6e 75 6d 65 72 61 74 65 64 20 62 65  es enumerated be
b4a0: 6c 6f 77 2c 20 77 65 20 72 65 6c 69 6e 71 75 69  low, we relinqui
b4b0: 73 68 20 74 68 65 20 6d 75 74 65 78 2c 0a 20 20  sh the mutex,.  
b4c0: 20 20 2a 2a 20 70 65 72 66 6f 72 6d 20 74 68 65    ** perform the
b4d0: 20 49 4f 2c 20 61 6e 64 20 74 68 65 6e 20 72 65   IO, and then re
b4e0: 2d 72 65 71 75 65 73 74 20 74 68 65 20 6d 75 74  -request the mut
b4f0: 65 78 20 62 65 66 6f 72 65 20 72 65 6d 6f 76 69  ex before removi
b500: 6e 67 20 27 70 27 20 66 72 6f 6d 0a 20 20 20 20  ng 'p' from.    
b510: 2a 2a 20 74 68 65 20 68 65 61 64 20 6f 66 20 74  ** the head of t
b520: 68 65 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75  he write-op queu
b530: 65 2e 20 54 68 65 20 69 64 65 61 20 69 73 20 74  e. The idea is t
b540: 6f 20 69 6e 63 72 65 61 73 65 20 63 6f 6e 63 75  o increase concu
b550: 72 72 65 6e 63 79 20 77 69 74 68 0a 20 20 20 20  rrency with.    
b560: 2a 2a 20 73 71 6c 69 74 65 20 74 68 72 65 61 64  ** sqlite thread
b570: 73 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a  s..    **.    **
b580: 20 20 20 20 20 2a 20 41 6e 20 41 53 59 4e 43 5f       * An ASYNC_
b590: 43 4c 4f 53 45 20 6f 70 65 72 61 74 69 6f 6e 2e  CLOSE operation.
b5a0: 0a 20 20 20 20 2a 2a 20 20 20 20 20 2a 20 41 6e  .    **     * An
b5b0: 20 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55   ASYNC_OPENEXCLU
b5c0: 53 49 56 45 20 6f 70 65 72 61 74 69 6f 6e 2e 20  SIVE operation. 
b5d0: 46 6f 72 20 74 68 69 73 20 6f 6e 65 2c 20 77 65  For this one, we
b5e0: 20 72 65 6c 69 6e 71 75 69 73 68 20 0a 20 20 20   relinquish .   
b5f0: 20 2a 2a 20 20 20 20 20 20 20 74 68 65 20 6d 75   **       the mu
b600: 74 65 78 2c 20 63 61 6c 6c 20 74 68 65 20 75 6e  tex, call the un
b610: 64 65 72 6c 79 69 6e 67 20 78 4f 70 65 6e 45 78  derlying xOpenEx
b620: 63 6c 75 73 69 76 65 28 29 20 66 75 6e 63 74 69  clusive() functi
b630: 6f 6e 2c 20 74 68 65 6e 0a 20 20 20 20 2a 2a 20  on, then.    ** 
b640: 20 20 20 20 20 20 72 65 2d 61 71 75 69 72 65 20        re-aquire 
b650: 74 68 65 20 6d 75 74 65 78 20 62 65 66 6f 72 65  the mutex before
b660: 20 73 65 74 69 6e 67 20 74 68 65 20 41 73 79 6e   seting the Asyn
b670: 63 46 69 6c 65 2e 70 42 61 73 65 52 65 61 64 20  cFile.pBaseRead 
b680: 0a 20 20 20 20 2a 2a 20 20 20 20 20 20 20 76 61  .    **       va
b690: 72 69 61 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 20  riable..    **  
b6a0: 20 20 20 2a 20 41 53 59 4e 43 5f 53 59 4e 43 20     * ASYNC_SYNC 
b6b0: 61 6e 64 20 41 53 59 4e 43 5f 57 52 49 54 45 20  and ASYNC_WRITE 
b6c0: 6f 70 65 72 61 74 69 6f 6e 73 2c 20 69 66 20 0a  operations, if .
b6d0: 20 20 20 20 2a 2a 20 20 20 20 20 20 20 53 51 4c      **       SQL
b6e0: 49 54 45 5f 41 53 59 4e 43 5f 54 57 4f 5f 46 49  ITE_ASYNC_TWO_FI
b6f0: 4c 45 48 41 4e 44 4c 45 53 20 77 61 73 20 73 65  LEHANDLES was se
b700: 74 20 61 74 20 63 6f 6d 70 69 6c 65 20 74 69 6d  t at compile tim
b710: 65 20 61 6e 64 20 74 77 6f 0a 20 20 20 20 2a 2a  e and two.    **
b720: 20 20 20 20 20 20 20 66 69 6c 65 2d 68 61 6e 64         file-hand
b730: 6c 65 73 20 61 72 65 20 6f 70 65 6e 20 66 6f 72  les are open for
b740: 20 74 68 65 20 70 61 72 74 69 63 75 6c 61 72 20   the particular 
b750: 66 69 6c 65 20 62 65 69 6e 67 20 22 73 79 6e 63  file being "sync
b760: 65 64 22 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ed"..    */.    
b770: 69 66 28 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f  if( async.ioErro
b780: 72 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  r!=SQLITE_OK && 
b790: 70 2d 3e 6f 70 21 3d 41 53 59 4e 43 5f 43 4c 4f  p->op!=ASYNC_CLO
b7a0: 53 45 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 6f  SE ){.      p->o
b7b0: 70 20 3d 20 41 53 59 4e 43 5f 4e 4f 4f 50 3b 0a  p = ASYNC_NOOP;.
b7c0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 2d      }.    if( p-
b7d0: 3e 70 46 69 6c 65 44 61 74 61 20 29 7b 0a 20 20  >pFileData ){.  
b7e0: 20 20 20 20 70 42 61 73 65 20 3d 20 70 2d 3e 70      pBase = p->p
b7f0: 46 69 6c 65 44 61 74 61 2d 3e 70 42 61 73 65 57  FileData->pBaseW
b800: 72 69 74 65 3b 0a 20 20 20 20 20 20 69 66 28 20  rite;.      if( 
b810: 0a 20 20 20 20 20 20 20 20 70 2d 3e 6f 70 3d 3d  .        p->op==
b820: 41 53 59 4e 43 5f 43 4c 4f 53 45 20 7c 7c 20 0a  ASYNC_CLOSE || .
b830: 20 20 20 20 20 20 20 20 70 2d 3e 6f 70 3d 3d 41          p->op==A
b840: 53 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49  SYNC_OPENEXCLUSI
b850: 56 45 20 7c 7c 0a 20 20 20 20 20 20 20 20 28 70  VE ||.        (p
b860: 42 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73 20 26  Base->pMethods &
b870: 26 20 28 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f  & (p->op==ASYNC_
b880: 53 59 4e 43 20 7c 7c 20 70 2d 3e 6f 70 3d 3d 41  SYNC || p->op==A
b890: 53 59 4e 43 5f 57 52 49 54 45 29 20 29 20 0a 20  SYNC_WRITE) ) . 
b8a0: 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20       ){.        
b8b0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
b8c0: 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 71 75 65 75  lock(&async.queu
b8d0: 65 4d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 20  eMutex);.       
b8e0: 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20   holdingMutex = 
b8f0: 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  0;.      }.     
b900: 20 69 66 28 20 21 70 42 61 73 65 2d 3e 70 4d 65   if( !pBase->pMe
b910: 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 20 20 20  thods ){.       
b920: 20 70 42 61 73 65 20 3d 20 70 2d 3e 70 46 69 6c   pBase = p->pFil
b930: 65 44 61 74 61 2d 3e 70 42 61 73 65 52 65 61 64  eData->pBaseRead
b940: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
b950: 0a 20 20 20 20 73 77 69 74 63 68 28 20 70 2d 3e  .    switch( p->
b960: 6f 70 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65  op ){.      case
b970: 20 41 53 59 4e 43 5f 4e 4f 4f 50 3a 0a 20 20 20   ASYNC_NOOP:.   
b980: 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
b990: 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f 57 52     case ASYNC_WR
b9a0: 49 54 45 3a 0a 20 20 20 20 20 20 20 20 61 73 73  ITE:.        ass
b9b0: 65 72 74 28 20 70 42 61 73 65 20 29 3b 0a 20 20  ert( pBase );.  
b9c0: 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41 43        ASYNC_TRAC
b9d0: 45 28 28 22 57 52 49 54 45 20 25 73 20 25 64 20  E(("WRITE %s %d 
b9e0: 62 79 74 65 73 20 61 74 20 25 64 5c 6e 22 2c 0a  bytes at %d\n",.
b9f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ba00: 70 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e  p->pFileData->zN
ba10: 61 6d 65 2c 20 70 2d 3e 6e 42 79 74 65 2c 20 70  ame, p->nByte, p
ba20: 2d 3e 69 4f 66 66 73 65 74 29 29 3b 0a 20 20 20  ->iOffset));.   
ba30: 20 20 20 20 20 72 63 20 3d 20 70 42 61 73 65 2d       rc = pBase-
ba40: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 57 72 69 74  >pMethods->xWrit
ba50: 65 28 70 42 61 73 65 2c 20 28 76 6f 69 64 20 2a  e(pBase, (void *
ba60: 29 28 70 2d 3e 7a 42 75 66 29 2c 20 70 2d 3e 6e  )(p->zBuf), p->n
ba70: 42 79 74 65 2c 20 70 2d 3e 69 4f 66 66 73 65 74  Byte, p->iOffset
ba80: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
ba90: 3b 0a 0a 20 20 20 20 20 20 63 61 73 65 20 41 53  ;..      case AS
baa0: 59 4e 43 5f 53 59 4e 43 3a 0a 20 20 20 20 20 20  YNC_SYNC:.      
bab0: 20 20 61 73 73 65 72 74 28 20 70 42 61 73 65 20    assert( pBase 
bac0: 29 3b 0a 20 20 20 20 20 20 20 20 41 53 59 4e 43  );.        ASYNC
bad0: 5f 54 52 41 43 45 28 28 22 53 59 4e 43 20 25 73  _TRACE(("SYNC %s
bae0: 5c 6e 22 2c 20 70 2d 3e 70 46 69 6c 65 44 61 74  \n", p->pFileDat
baf0: 61 2d 3e 7a 4e 61 6d 65 29 29 3b 0a 20 20 20 20  a->zName));.    
bb00: 20 20 20 20 72 63 20 3d 20 70 42 61 73 65 2d 3e      rc = pBase->
bb10: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 79 6e 63 28  pMethods->xSync(
bb20: 70 42 61 73 65 2c 20 70 2d 3e 6e 42 79 74 65 29  pBase, p->nByte)
bb30: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
bb40: 0a 0a 20 20 20 20 20 20 63 61 73 65 20 41 53 59  ..      case ASY
bb50: 4e 43 5f 54 52 55 4e 43 41 54 45 3a 0a 20 20 20  NC_TRUNCATE:.   
bb60: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 42 61       assert( pBa
bb70: 73 65 20 29 3b 0a 20 20 20 20 20 20 20 20 41 53  se );.        AS
bb80: 59 4e 43 5f 54 52 41 43 45 28 28 22 54 52 55 4e  YNC_TRACE(("TRUN
bb90: 43 41 54 45 20 25 73 20 74 6f 20 25 64 20 62 79  CATE %s to %d by
bba0: 74 65 73 5c 6e 22 2c 20 0a 20 20 20 20 20 20 20  tes\n", .       
bbb0: 20 20 20 20 20 20 20 20 20 70 2d 3e 70 46 69 6c           p->pFil
bbc0: 65 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 70 2d  eData->zName, p-
bbd0: 3e 69 4f 66 66 73 65 74 29 29 3b 0a 20 20 20 20  >iOffset));.    
bbe0: 20 20 20 20 72 63 20 3d 20 70 42 61 73 65 2d 3e      rc = pBase->
bbf0: 70 4d 65 74 68 6f 64 73 2d 3e 78 54 72 75 6e 63  pMethods->xTrunc
bc00: 61 74 65 28 70 42 61 73 65 2c 20 70 2d 3e 69 4f  ate(pBase, p->iO
bc10: 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 20 20  ffset);.        
bc20: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61  break;..      ca
bc30: 73 65 20 41 53 59 4e 43 5f 43 4c 4f 53 45 3a 20  se ASYNC_CLOSE: 
bc40: 7b 0a 20 20 20 20 20 20 20 20 41 73 79 6e 63 46  {.        AsyncF
bc50: 69 6c 65 44 61 74 61 20 2a 70 44 61 74 61 20 3d  ileData *pData =
bc60: 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 3b 0a 20   p->pFileData;. 
bc70: 20 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41         ASYNC_TRA
bc80: 43 45 28 28 22 43 4c 4f 53 45 20 25 73 5c 6e 22  CE(("CLOSE %s\n"
bc90: 2c 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e  , p->pFileData->
bca0: 7a 4e 61 6d 65 29 29 3b 0a 20 20 20 20 20 20 20  zName));.       
bcb0: 20 69 66 28 20 70 44 61 74 61 2d 3e 70 42 61 73   if( pData->pBas
bcc0: 65 57 72 69 74 65 2d 3e 70 4d 65 74 68 6f 64 73  eWrite->pMethods
bcd0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 44   ){.          pD
bce0: 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74 65 2d  ata->pBaseWrite-
bcf0: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73  >pMethods->xClos
bd00: 65 28 70 44 61 74 61 2d 3e 70 42 61 73 65 57 72  e(pData->pBaseWr
bd10: 69 74 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ite);.        }.
bd20: 20 20 20 20 20 20 20 20 69 66 28 20 70 44 61 74          if( pDat
bd30: 61 2d 3e 70 42 61 73 65 52 65 61 64 2d 3e 70 4d  a->pBaseRead->pM
bd40: 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 20 20  ethods ){.      
bd50: 20 20 20 20 70 44 61 74 61 2d 3e 70 42 61 73 65      pData->pBase
bd60: 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  Read->pMethods->
bd70: 78 43 6c 6f 73 65 28 70 44 61 74 61 2d 3e 70 42  xClose(pData->pB
bd80: 61 73 65 52 65 61 64 29 3b 0a 20 20 20 20 20 20  aseRead);.      
bd90: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20    }..        /* 
bda0: 55 6e 6c 69 6e 6b 20 41 73 79 6e 63 46 69 6c 65  Unlink AsyncFile
bdb0: 44 61 74 61 2e 6c 6f 63 6b 20 66 72 6f 6d 20 74  Data.lock from t
bdc0: 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f  he linked list o
bdd0: 66 20 41 73 79 6e 63 46 69 6c 65 4c 6f 63 6b 20  f AsyncFileLock 
bde0: 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 74 72 75  .        ** stru
bdf0: 63 74 75 72 65 73 20 66 6f 72 20 74 68 69 73 20  ctures for this 
be00: 66 69 6c 65 2e 20 4f 62 74 61 69 6e 20 74 68 65  file. Obtain the
be10: 20 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65 78   async.lockMutex
be20: 20 6d 75 74 65 78 20 0a 20 20 20 20 20 20 20 20   mutex .        
be30: 2a 2a 20 62 65 66 6f 72 65 20 64 6f 69 6e 67 20  ** before doing 
be40: 73 6f 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  so..        */. 
be50: 20 20 20 20 20 20 20 70 74 68 72 65 61 64 5f 6d         pthread_m
be60: 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e 63  utex_lock(&async
be70: 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20 20 20  .lockMutex);.   
be80: 20 20 20 20 20 72 63 20 3d 20 75 6e 6c 69 6e 6b       rc = unlink
be90: 41 73 79 6e 63 46 69 6c 65 28 70 44 61 74 61 29  AsyncFile(pData)
bea0: 3b 0a 20 20 20 20 20 20 20 20 70 74 68 72 65 61  ;.        pthrea
beb0: 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26  d_mutex_unlock(&
bec0: 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65 78 29  async.lockMutex)
bed0: 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20 21  ;..        if( !
bee0: 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 29 7b 0a  holdingMutex ){.
bef0: 20 20 20 20 20 20 20 20 20 20 70 74 68 72 65 61            pthrea
bf00: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 73  d_mutex_lock(&as
bf10: 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b  ync.queueMutex);
bf20: 0a 20 20 20 20 20 20 20 20 20 20 68 6f 6c 64 69  .          holdi
bf30: 6e 67 4d 75 74 65 78 20 3d 20 31 3b 0a 20 20 20  ngMutex = 1;.   
bf40: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61       }.        a
bf50: 73 73 65 72 74 5f 6d 75 74 65 78 5f 69 73 5f 68  ssert_mutex_is_h
bf60: 65 6c 64 28 26 61 73 79 6e 63 2e 71 75 65 75 65  eld(&async.queue
bf70: 4d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 20 20  Mutex);.        
bf80: 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73  async.pQueueFirs
bf90: 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  t = p->pNext;.  
bfa0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
bfb0: 65 65 28 70 44 61 74 61 29 3b 0a 20 20 20 20 20  ee(pData);.     
bfc0: 20 20 20 64 6f 4e 6f 74 46 72 65 65 20 3d 20 31     doNotFree = 1
bfd0: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
bfe0: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
bff0: 63 61 73 65 20 41 53 59 4e 43 5f 55 4e 4c 4f 43  case ASYNC_UNLOC
c000: 4b 3a 20 7b 0a 20 20 20 20 20 20 20 20 41 73 79  K: {.        Asy
c010: 6e 63 57 72 69 74 65 20 2a 70 49 74 65 72 3b 0a  ncWrite *pIter;.
c020: 20 20 20 20 20 20 20 20 41 73 79 6e 63 46 69 6c          AsyncFil
c030: 65 44 61 74 61 20 2a 70 44 61 74 61 20 3d 20 70  eData *pData = p
c040: 2d 3e 70 46 69 6c 65 44 61 74 61 3b 0a 20 20 20  ->pFileData;.   
c050: 20 20 20 20 20 69 6e 74 20 65 4c 6f 63 6b 20 3d       int eLock =
c060: 20 70 2d 3e 6e 42 79 74 65 3b 0a 0a 20 20 20 20   p->nByte;..    
c070: 20 20 20 20 2f 2a 20 57 68 65 6e 20 61 20 66 69      /* When a fi
c080: 6c 65 20 69 73 20 6c 6f 63 6b 65 64 20 62 79 20  le is locked by 
c090: 53 51 4c 69 74 65 20 75 73 69 6e 67 20 74 68 65  SQLite using the
c0a0: 20 61 73 79 6e 63 20 62 61 63 6b 65 6e 64 2c 20   async backend, 
c0b0: 69 74 20 69 73 20 0a 20 20 20 20 20 20 20 20 2a  it is .        *
c0c0: 2a 20 6c 6f 63 6b 65 64 20 77 69 74 68 69 6e 20  * locked within 
c0d0: 74 68 65 20 27 72 65 61 6c 27 20 66 69 6c 65 2d  the 'real' file-
c0e0: 73 79 73 74 65 6d 20 73 79 6e 63 68 72 6f 6e 6f  system synchrono
c0f0: 75 73 6c 79 2e 20 57 68 65 6e 20 69 74 20 69 73  usly. When it is
c100: 0a 20 20 20 20 20 20 20 20 2a 2a 20 75 6e 6c 6f  .        ** unlo
c110: 63 6b 65 64 2c 20 61 6e 20 41 53 59 4e 43 5f 55  cked, an ASYNC_U
c120: 4e 4c 4f 43 4b 20 65 76 65 6e 74 20 69 73 20 61  NLOCK event is a
c130: 64 64 65 64 20 74 6f 20 74 68 65 20 77 72 69 74  dded to the writ
c140: 65 2d 71 75 65 75 65 20 74 6f 0a 20 20 20 20 20  e-queue to.     
c150: 20 20 20 2a 2a 20 75 6e 6c 6f 63 6b 20 74 68 65     ** unlock the
c160: 20 66 69 6c 65 20 61 73 79 6e 63 68 72 6f 6e 6f   file asynchrono
c170: 75 73 6c 79 2e 20 54 68 65 20 64 65 73 69 67 6e  usly. The design
c180: 20 6f 66 20 74 68 65 20 61 73 79 6e 63 20 62 61   of the async ba
c190: 63 6b 65 6e 64 0a 20 20 20 20 20 20 20 20 2a 2a  ckend.        **
c1a0: 20 72 65 71 75 69 72 65 73 20 74 68 61 74 20 74   requires that t
c1b0: 68 65 20 27 72 65 61 6c 27 20 66 69 6c 65 2d 73  he 'real' file-s
c1c0: 79 73 74 65 6d 20 66 69 6c 65 20 62 65 20 6c 6f  ystem file be lo
c1d0: 63 6b 65 64 20 66 72 6f 6d 20 74 68 65 0a 20 20  cked from the.  
c1e0: 20 20 20 20 20 20 2a 2a 20 74 69 6d 65 20 74 68        ** time th
c1f0: 61 74 20 53 51 4c 69 74 65 20 66 69 72 73 74 20  at SQLite first 
c200: 6c 6f 63 6b 73 20 69 74 20 28 61 6e 64 20 70 72  locks it (and pr
c210: 6f 62 61 62 6c 79 20 72 65 61 64 73 20 66 72 6f  obably reads fro
c220: 6d 20 69 74 29 0a 20 20 20 20 20 20 20 20 2a 2a  m it).        **
c230: 20 75 6e 74 69 6c 20 61 6c 6c 20 61 73 79 6e 63   until all async
c240: 68 72 6f 6e 6f 75 73 20 77 72 69 74 65 20 65 76  hronous write ev
c250: 65 6e 74 73 20 74 68 61 74 20 77 65 72 65 20 73  ents that were s
c260: 63 68 65 64 75 6c 65 64 20 62 65 66 6f 72 65 0a  cheduled before.
c270: 20 20 20 20 20 20 20 20 2a 2a 20 53 51 4c 69 74          ** SQLit
c280: 65 20 75 6e 6c 6f 63 6b 65 64 20 74 68 65 20 66  e unlocked the f
c290: 69 6c 65 20 68 61 76 65 20 62 65 65 6e 20 70 72  ile have been pr
c2a0: 6f 63 65 73 73 65 64 2e 0a 20 20 20 20 20 20 20  ocessed..       
c2b0: 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 54   **.        ** T
c2c0: 68 69 73 20 69 73 20 6d 6f 72 65 20 63 6f 6d 70  his is more comp
c2d0: 6c 65 78 20 69 66 20 53 51 4c 69 74 65 20 6c 6f  lex if SQLite lo
c2e0: 63 6b 73 20 61 6e 64 20 75 6e 6c 6f 63 6b 73 20  cks and unlocks 
c2f0: 74 68 65 20 66 69 6c 65 20 6d 75 6c 74 69 70 6c  the file multipl
c300: 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 69 6d  e.        ** tim
c310: 65 73 20 69 6e 20 71 75 69 63 6b 20 73 75 63 63  es in quick succ
c320: 65 73 73 69 6f 6e 2e 20 46 6f 72 20 65 78 61 6d  ession. For exam
c330: 70 6c 65 2c 20 69 66 20 53 51 4c 69 74 65 20 64  ple, if SQLite d
c340: 6f 65 73 3a 20 0a 20 20 20 20 20 20 20 20 2a 2a  oes: .        **
c350: 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 20 20 6c   .        **   l
c360: 6f 63 6b 2c 20 77 72 69 74 65 2c 20 75 6e 6c 6f  ock, write, unlo
c370: 63 6b 2c 20 6c 6f 63 6b 2c 20 77 72 69 74 65 2c  ck, lock, write,
c380: 20 75 6e 6c 6f 63 6b 0a 20 20 20 20 20 20 20 20   unlock.        
c390: 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 45 61  **.        ** Ea
c3a0: 63 68 20 22 6c 6f 63 6b 22 20 6f 70 65 72 61 74  ch "lock" operat
c3b0: 69 6f 6e 20 6c 6f 63 6b 73 20 74 68 65 20 66 69  ion locks the fi
c3c0: 6c 65 20 69 6d 6d 65 64 69 61 74 65 6c 79 2e 20  le immediately. 
c3d0: 45 61 63 68 20 22 77 72 69 74 65 22 20 0a 20 20  Each "write" .  
c3e0: 20 20 20 20 20 20 2a 2a 20 61 6e 64 20 22 75 6e        ** and "un
c3f0: 6c 6f 63 6b 22 20 6f 70 65 72 61 74 69 6f 6e 20  lock" operation 
c400: 61 64 64 73 20 61 6e 20 65 76 65 6e 74 20 74 6f  adds an event to
c410: 20 74 68 65 20 65 76 65 6e 74 20 71 75 65 75 65   the event queue
c420: 2e 20 49 66 20 74 68 65 0a 20 20 20 20 20 20 20  . If the.       
c430: 20 2a 2a 20 73 65 63 6f 6e 64 20 22 6c 6f 63 6b   ** second "lock
c440: 22 20 6f 70 65 72 61 74 69 6f 6e 20 69 73 20 70  " operation is p
c450: 65 72 66 6f 72 6d 65 64 20 62 65 66 6f 72 65 20  erformed before 
c460: 74 68 65 20 66 69 72 73 74 20 22 75 6e 6c 6f 63  the first "unloc
c470: 6b 22 0a 20 20 20 20 20 20 20 20 2a 2a 20 6f 70  k".        ** op
c480: 65 72 61 74 69 6f 6e 20 68 61 73 20 62 65 65 6e  eration has been
c490: 20 70 72 6f 63 65 73 73 65 64 20 61 73 79 6e 63   processed async
c4a0: 68 72 6f 6e 6f 75 73 6c 79 2c 20 74 68 65 6e 20  hronously, then 
c4b0: 74 68 65 20 66 69 72 73 74 0a 20 20 20 20 20 20  the first.      
c4c0: 20 20 2a 2a 20 22 75 6e 6c 6f 63 6b 22 20 63 61    ** "unlock" ca
c4d0: 6e 6e 6f 74 20 62 65 20 73 61 66 65 6c 79 20 70  nnot be safely p
c4e0: 72 6f 63 65 73 73 65 64 20 61 73 20 69 73 2c 20  rocessed as is, 
c4f0: 73 69 6e 63 65 20 74 68 69 73 20 77 6f 75 6c 64  since this would
c500: 20 6d 65 61 6e 0a 20 20 20 20 20 20 20 20 2a 2a   mean.        **
c510: 20 74 68 65 20 66 69 6c 65 20 77 61 73 20 75 6e   the file was un
c520: 6c 6f 63 6b 65 64 20 77 68 65 6e 20 74 68 65 20  locked when the 
c530: 73 65 63 6f 6e 64 20 22 77 72 69 74 65 22 20 6f  second "write" o
c540: 70 65 72 61 74 69 6f 6e 20 69 73 0a 20 20 20 20  peration is.    
c550: 20 20 20 20 2a 2a 20 70 72 6f 63 65 73 73 65 64      ** processed
c560: 2e 20 54 6f 20 77 6f 72 6b 20 61 72 6f 75 6e 64  . To work around
c570: 20 74 68 69 73 2c 20 77 68 65 6e 20 70 72 6f 63   this, when proc
c580: 65 73 73 69 6e 67 20 61 6e 20 41 53 59 4e 43 5f  essing an ASYNC_
c590: 55 4e 4c 4f 43 4b 0a 20 20 20 20 20 20 20 20 2a  UNLOCK.        *
c5a0: 2a 20 6f 70 65 72 61 74 69 6f 6e 2c 20 53 51 4c  * operation, SQL
c5b0: 69 74 65 3a 0a 20 20 20 20 20 20 20 20 2a 2a 0a  ite:.        **.
c5c0: 20 20 20 20 20 20 20 20 2a 2a 20 20 20 31 29 20          **   1) 
c5d0: 55 6e 6c 6f 63 6b 73 20 74 68 65 20 66 69 6c 65  Unlocks the file
c5e0: 20 74 6f 20 74 68 65 20 6d 69 6e 69 6d 75 6d 20   to the minimum 
c5f0: 6f 66 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20  of the argument 
c600: 70 61 73 73 65 64 20 74 6f 0a 20 20 20 20 20 20  passed to.      
c610: 20 20 2a 2a 20 20 20 20 20 20 74 68 65 20 78 55    **      the xU
c620: 6e 6c 6f 63 6b 28 29 20 63 61 6c 6c 20 61 6e 64  nlock() call and
c630: 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 6f 63   the current loc
c640: 6b 20 66 72 6f 6d 20 53 51 4c 69 74 65 27 73 20  k from SQLite's 
c650: 70 6f 69 6e 74 0a 20 20 20 20 20 20 20 20 2a 2a  point.        **
c660: 20 20 20 20 20 20 6f 66 20 76 69 65 77 2c 20 61        of view, a
c670: 6e 64 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20  nd.        **.  
c680: 20 20 20 20 20 20 2a 2a 20 20 20 32 29 20 4f 6e        **   2) On
c690: 6c 79 20 75 6e 6c 6f 63 6b 73 20 74 68 65 20 66  ly unlocks the f
c6a0: 69 6c 65 20 61 74 20 61 6c 6c 20 69 66 20 74 68  ile at all if th
c6b0: 69 73 20 65 76 65 6e 74 20 69 73 20 74 68 65 20  is event is the 
c6c0: 6c 61 73 74 0a 20 20 20 20 20 20 20 20 2a 2a 20  last.        ** 
c6d0: 20 20 20 20 20 41 53 59 4e 43 5f 55 4e 4c 4f 43       ASYNC_UNLOC
c6e0: 4b 20 65 76 65 6e 74 20 6f 6e 20 74 68 69 73 20  K event on this 
c6f0: 66 69 6c 65 20 69 6e 20 74 68 65 20 77 72 69 74  file in the writ
c700: 65 2d 71 75 65 75 65 2e 0a 20 20 20 20 20 20 20  e-queue..       
c710: 20 2a 2f 20 0a 20 20 20 20 20 20 20 20 61 73 73   */ .        ass
c720: 65 72 74 28 20 68 6f 6c 64 69 6e 67 4d 75 74 65  ert( holdingMute
c730: 78 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20 20 20  x==1 );.        
c740: 61 73 73 65 72 74 28 20 61 73 79 6e 63 2e 70 51  assert( async.pQ
c750: 75 65 75 65 46 69 72 73 74 3d 3d 70 20 29 3b 0a  ueueFirst==p );.
c760: 20 20 20 20 20 20 20 20 66 6f 72 28 70 49 74 65          for(pIte
c770: 72 3d 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69  r=async.pQueueFi
c780: 72 73 74 2d 3e 70 4e 65 78 74 3b 20 70 49 74 65  rst->pNext; pIte
c790: 72 3b 20 70 49 74 65 72 3d 70 49 74 65 72 2d 3e  r; pIter=pIter->
c7a0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20  pNext){.        
c7b0: 20 20 69 66 28 20 70 49 74 65 72 2d 3e 70 46 69    if( pIter->pFi
c7c0: 6c 65 44 61 74 61 3d 3d 70 44 61 74 61 20 26 26  leData==pData &&
c7d0: 20 70 49 74 65 72 2d 3e 6f 70 3d 3d 41 53 59 4e   pIter->op==ASYN
c7e0: 43 5f 55 4e 4c 4f 43 4b 20 29 20 62 72 65 61 6b  C_UNLOCK ) break
c7f0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
c800: 20 20 20 20 69 66 28 20 21 70 49 74 65 72 20 29      if( !pIter )
c810: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 74 68 72  {.          pthr
c820: 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26  ead_mutex_lock(&
c830: 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65 78 29  async.lockMutex)
c840: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 44 61 74  ;.          pDat
c850: 61 2d 3e 6c 6f 63 6b 2e 65 41 73 79 6e 63 4c 6f  a->lock.eAsyncLo
c860: 63 6b 20 3d 20 4d 49 4e 28 0a 20 20 20 20 20 20  ck = MIN(.      
c870: 20 20 20 20 20 20 20 20 70 44 61 74 61 2d 3e 6c          pData->l
c880: 6f 63 6b 2e 65 41 73 79 6e 63 4c 6f 63 6b 2c 20  ock.eAsyncLock, 
c890: 4d 41 58 28 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e  MAX(pData->lock.
c8a0: 65 4c 6f 63 6b 2c 20 65 4c 6f 63 6b 29 0a 20 20  eLock, eLock).  
c8b0: 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20          );.     
c8c0: 20 20 20 20 20 61 73 73 65 72 74 28 70 44 61 74       assert(pDat
c8d0: 61 2d 3e 6c 6f 63 6b 2e 65 41 73 79 6e 63 4c 6f  a->lock.eAsyncLo
c8e0: 63 6b 3e 3d 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e  ck>=pData->lock.
c8f0: 65 4c 6f 63 6b 29 3b 0a 20 20 20 20 20 20 20 20  eLock);.        
c900: 20 20 72 63 20 3d 20 67 65 74 46 69 6c 65 4c 6f    rc = getFileLo
c910: 63 6b 28 70 44 61 74 61 2d 3e 70 4c 6f 63 6b 29  ck(pData->pLock)
c920: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 74 68 72  ;.          pthr
c930: 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b  ead_mutex_unlock
c940: 28 26 61 73 79 6e 63 2e 6c 6f 63 6b 4d 75 74 65  (&async.lockMute
c950: 78 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  x);.        }.  
c960: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
c970: 20 20 20 7d 0a 0a 20 20 20 20 20 20 63 61 73 65     }..      case
c980: 20 41 53 59 4e 43 5f 44 45 4c 45 54 45 3a 0a 20   ASYNC_DELETE:. 
c990: 20 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41         ASYNC_TRA
c9a0: 43 45 28 28 22 44 45 4c 45 54 45 20 25 73 5c 6e  CE(("DELETE %s\n
c9b0: 22 2c 20 70 2d 3e 7a 42 75 66 29 29 3b 0a 20 20  ", p->zBuf));.  
c9c0: 20 20 20 20 20 20 72 63 20 3d 20 70 56 66 73 2d        rc = pVfs-
c9d0: 3e 78 44 65 6c 65 74 65 28 70 56 66 73 2c 20 70  >xDelete(pVfs, p
c9e0: 2d 3e 7a 42 75 66 2c 20 28 69 6e 74 29 70 2d 3e  ->zBuf, (int)p->
c9f0: 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20  iOffset);.      
ca00: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20    break;..      
ca10: 63 61 73 65 20 41 53 59 4e 43 5f 4f 50 45 4e 45  case ASYNC_OPENE
ca20: 58 43 4c 55 53 49 56 45 3a 20 7b 0a 20 20 20 20  XCLUSIVE: {.    
ca30: 20 20 20 20 69 6e 74 20 66 6c 61 67 73 20 3d 20      int flags = 
ca40: 28 69 6e 74 29 70 2d 3e 69 4f 66 66 73 65 74 3b  (int)p->iOffset;
ca50: 0a 20 20 20 20 20 20 20 20 41 73 79 6e 63 46 69  .        AsyncFi
ca60: 6c 65 44 61 74 61 20 2a 70 44 61 74 61 20 3d 20  leData *pData = 
ca70: 70 2d 3e 70 46 69 6c 65 44 61 74 61 3b 0a 20 20  p->pFileData;.  
ca80: 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41 43        ASYNC_TRAC
ca90: 45 28 28 22 4f 50 45 4e 20 25 73 20 66 6c 61 67  E(("OPEN %s flag
caa0: 73 3d 25 64 5c 6e 22 2c 20 70 2d 3e 7a 42 75 66  s=%d\n", p->zBuf
cab0: 2c 20 28 69 6e 74 29 70 2d 3e 69 4f 66 66 73 65  , (int)p->iOffse
cac0: 74 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73  t));.        ass
cad0: 65 72 74 28 70 44 61 74 61 2d 3e 70 42 61 73 65  ert(pData->pBase
cae0: 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73 3d 3d  Read->pMethods==
caf0: 30 20 26 26 20 70 44 61 74 61 2d 3e 70 42 61 73  0 && pData->pBas
cb00: 65 57 72 69 74 65 2d 3e 70 4d 65 74 68 6f 64 73  eWrite->pMethods
cb10: 3d 3d 30 29 3b 0a 20 20 20 20 20 20 20 20 72 63  ==0);.        rc
cb20: 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65 6e 28 70   = pVfs->xOpen(p
cb30: 56 66 73 2c 20 70 44 61 74 61 2d 3e 7a 4e 61 6d  Vfs, pData->zNam
cb40: 65 2c 20 70 44 61 74 61 2d 3e 70 42 61 73 65 52  e, pData->pBaseR
cb50: 65 61 64 2c 20 66 6c 61 67 73 2c 20 30 29 3b 0a  ead, flags, 0);.
cb60: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
cb70: 68 6f 6c 64 69 6e 67 4d 75 74 65 78 3d 3d 30 20  holdingMutex==0 
cb80: 29 3b 0a 20 20 20 20 20 20 20 20 70 74 68 72 65  );.        pthre
cb90: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
cba0: 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29  sync.queueMutex)
cbb0: 3b 0a 20 20 20 20 20 20 20 20 68 6f 6c 64 69 6e  ;.        holdin
cbc0: 67 4d 75 74 65 78 20 3d 20 31 3b 0a 20 20 20 20  gMutex = 1;.    
cbd0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
cbe0: 20 7d 0a 0a 20 20 20 20 20 20 64 65 66 61 75 6c   }..      defaul
cbf0: 74 3a 20 61 73 73 65 72 74 28 21 22 49 6c 6c 65  t: assert(!"Ille
cc00: 67 61 6c 20 76 61 6c 75 65 20 66 6f 72 20 41 73  gal value for As
cc10: 79 6e 63 57 72 69 74 65 2e 6f 70 22 29 3b 0a 20  yncWrite.op");. 
cc20: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20     }..    /* If 
cc30: 77 65 20 64 69 64 6e 27 74 20 68 61 6e 67 20 6f  we didn't hang o
cc40: 6e 20 74 6f 20 74 68 65 20 6d 75 74 65 78 20 64  n to the mutex d
cc50: 75 72 69 6e 67 20 74 68 65 20 49 4f 20 6f 70 2c  uring the IO op,
cc60: 20 6f 62 74 61 69 6e 20 69 74 20 6e 6f 77 0a 20   obtain it now. 
cc70: 20 20 20 2a 2a 20 73 6f 20 74 68 61 74 20 74 68     ** so that th
cc80: 65 20 41 73 79 6e 63 57 72 69 74 65 20 73 74 72  e AsyncWrite str
cc90: 75 63 74 75 72 65 20 63 61 6e 20 62 65 20 73 61  ucture can be sa
cca0: 66 65 6c 79 20 72 65 6d 6f 76 65 64 20 66 72 6f  fely removed fro
ccb0: 6d 20 74 68 65 20 0a 20 20 20 20 2a 2a 20 67 6c  m the .    ** gl
ccc0: 6f 62 61 6c 20 77 72 69 74 65 2d 6f 70 20 71 75  obal write-op qu
ccd0: 65 75 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  eue..    */.    
cce0: 69 66 28 20 21 68 6f 6c 64 69 6e 67 4d 75 74 65  if( !holdingMute
ccf0: 78 20 29 7b 0a 20 20 20 20 20 20 70 74 68 72 65  x ){.      pthre
cd00: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
cd10: 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29  sync.queueMutex)
cd20: 3b 0a 20 20 20 20 20 20 68 6f 6c 64 69 6e 67 4d  ;.      holdingM
cd30: 75 74 65 78 20 3d 20 31 3b 0a 20 20 20 20 7d 0a  utex = 1;.    }.
cd40: 20 20 20 20 2f 2a 20 41 53 59 4e 43 5f 54 52 41      /* ASYNC_TRA
cd50: 43 45 28 28 22 55 4e 4c 49 4e 4b 20 25 70 5c 6e  CE(("UNLINK %p\n
cd60: 22 2c 20 70 29 29 3b 20 2a 2f 0a 20 20 20 20 69  ", p)); */.    i
cd70: 66 28 20 70 3d 3d 61 73 79 6e 63 2e 70 51 75 65  f( p==async.pQue
cd80: 75 65 4c 61 73 74 20 29 7b 0a 20 20 20 20 20 20  ueLast ){.      
cd90: 61 73 79 6e 63 2e 70 51 75 65 75 65 4c 61 73 74  async.pQueueLast
cda0: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 0;.    }.    
cdb0: 69 66 28 20 21 64 6f 4e 6f 74 46 72 65 65 20 29  if( !doNotFree )
cdc0: 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 5f 6d  {.      assert_m
cdd0: 75 74 65 78 5f 69 73 5f 68 65 6c 64 28 26 61 73  utex_is_held(&as
cde0: 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b  ync.queueMutex);
cdf0: 0a 20 20 20 20 20 20 61 73 79 6e 63 2e 70 51 75  .      async.pQu
ce00: 65 75 65 46 69 72 73 74 20 3d 20 70 2d 3e 70 4e  eueFirst = p->pN
ce10: 65 78 74 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  ext;.      sqlit
ce20: 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20  e3_free(p);.    
ce30: 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 68 6f  }.    assert( ho
ce40: 6c 64 69 6e 67 4d 75 74 65 78 20 29 3b 0a 0a 20  ldingMutex );.. 
ce50: 20 20 20 2f 2a 20 41 6e 20 49 4f 20 65 72 72 6f     /* An IO erro
ce60: 72 20 68 61 73 20 6f 63 63 75 72 72 65 64 2e 20  r has occurred. 
ce70: 57 65 20 63 61 6e 6e 6f 74 20 72 65 70 6f 72 74  We cannot report
ce80: 20 74 68 65 20 65 72 72 6f 72 20 62 61 63 6b 20   the error back 
ce90: 74 6f 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f  to the.    ** co
cea0: 6e 6e 65 63 74 69 6f 6e 20 74 68 61 74 20 72 65  nnection that re
ceb0: 71 75 65 73 74 65 64 20 74 68 65 20 49 2f 4f 20  quested the I/O 
cec0: 73 69 6e 63 65 20 74 68 65 20 65 72 72 6f 72 20  since the error 
ced0: 68 61 70 70 65 6e 65 64 20 0a 20 20 20 20 2a 2a  happened .    **
cee0: 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 6c 79 2e   asynchronously.
cef0: 20 20 54 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e    The connection
cf00: 20 68 61 73 20 61 6c 72 65 61 64 79 20 6d 6f 76   has already mov
cf10: 65 64 20 6f 6e 2e 20 20 54 68 65 72 65 20 0a 20  ed on.  There . 
cf20: 20 20 20 2a 2a 20 72 65 61 6c 6c 79 20 69 73 20     ** really is 
cf30: 6e 6f 62 6f 64 79 20 74 6f 20 72 65 70 6f 72 74  nobody to report
cf40: 20 74 68 65 20 65 72 72 6f 72 20 74 6f 2e 0a 20   the error to.. 
cf50: 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 65     **.    ** The
cf60: 20 66 69 6c 65 20 66 6f 72 20 77 68 69 63 68 20   file for which 
cf70: 74 68 65 20 65 72 72 6f 72 20 6f 63 63 75 72 72  the error occurr
cf80: 65 64 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  ed may have been
cf90: 20 61 20 64 61 74 61 62 61 73 65 20 6f 72 0a 20   a database or. 
cfa0: 20 20 20 2a 2a 20 6a 6f 75 72 6e 61 6c 20 66 69     ** journal fi
cfb0: 6c 65 2e 20 52 65 67 61 72 64 6c 65 73 73 2c 20  le. Regardless, 
cfc0: 6e 6f 6e 65 20 6f 66 20 74 68 65 20 63 75 72 72  none of the curr
cfd0: 65 6e 74 6c 79 20 71 75 65 75 65 64 20 6f 70 65  ently queued ope
cfe0: 72 61 74 69 6f 6e 73 0a 20 20 20 20 2a 2a 20 61  rations.    ** a
cff0: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74  ssociated with t
d000: 68 65 20 73 61 6d 65 20 64 61 74 61 62 61 73 65  he same database
d010: 20 73 68 6f 75 6c 64 20 6e 6f 77 20 62 65 20 70   should now be p
d020: 65 72 66 6f 72 6d 65 64 2e 20 4e 6f 72 20 73 68  erformed. Nor sh
d030: 6f 75 6c 64 0a 20 20 20 20 2a 2a 20 61 6e 79 20  ould.    ** any 
d040: 73 75 62 73 65 71 75 65 6e 74 6c 79 20 72 65 71  subsequently req
d050: 75 65 73 74 65 64 20 49 4f 20 6f 6e 20 65 69 74  uested IO on eit
d060: 68 65 72 20 61 20 64 61 74 61 62 61 73 65 20 6f  her a database o
d070: 72 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20 0a  r journal file .
d080: 20 20 20 20 2a 2a 20 68 61 6e 64 6c 65 20 66 6f      ** handle fo
d090: 72 20 74 68 65 20 73 61 6d 65 20 64 61 74 61 62  r the same datab
d0a0: 61 73 65 20 62 65 20 61 63 63 65 70 74 65 64 20  ase be accepted 
d0b0: 75 6e 74 69 6c 20 74 68 65 20 6d 61 69 6e 20 64  until the main d
d0c0: 61 74 61 62 61 73 65 0a 20 20 20 20 2a 2a 20 66  atabase.    ** f
d0d0: 69 6c 65 20 68 61 6e 64 6c 65 20 68 61 73 20 62  ile handle has b
d0e0: 65 65 6e 20 63 6c 6f 73 65 64 20 61 6e 64 20 72  een closed and r
d0f0: 65 6f 70 65 6e 65 64 2e 0a 20 20 20 20 2a 2a 0a  eopened..    **.
d100: 20 20 20 20 2a 2a 20 46 75 72 74 68 65 72 6d 6f      ** Furthermo
d110: 72 65 2c 20 6e 6f 20 66 75 72 74 68 65 72 20 49  re, no further I
d120: 4f 20 73 68 6f 75 6c 64 20 62 65 20 71 75 65 75  O should be queu
d130: 65 64 20 6f 72 20 70 65 72 66 6f 72 6d 65 64 20  ed or performed 
d140: 6f 6e 20 61 6e 79 20 66 69 6c 65 0a 20 20 20 20  on any file.    
d150: 2a 2a 20 68 61 6e 64 6c 65 20 61 73 73 6f 63 69  ** handle associ
d160: 61 74 65 64 20 77 69 74 68 20 61 20 64 61 74 61  ated with a data
d170: 62 61 73 65 20 74 68 61 74 20 6d 61 79 20 68 61  base that may ha
d180: 76 65 20 62 65 65 6e 20 70 61 72 74 20 6f 66 20  ve been part of 
d190: 61 20 0a 20 20 20 20 2a 2a 20 6d 75 6c 74 69 2d  a .    ** multi-
d1a0: 66 69 6c 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  file transaction
d1b0: 20 74 68 61 74 20 69 6e 63 6c 75 64 65 64 20 74   that included t
d1c0: 68 65 20 64 61 74 61 62 61 73 65 20 61 73 73 6f  he database asso
d1d0: 63 69 61 74 65 64 20 77 69 74 68 20 0a 20 20 20  ciated with .   
d1e0: 20 2a 2a 20 74 68 65 20 49 4f 20 65 72 72 6f 72   ** the IO error
d1f0: 20 28 69 2e 65 2e 20 61 20 64 61 74 61 62 61 73   (i.e. a databas
d200: 65 20 41 54 54 41 43 48 65 64 20 74 6f 20 74 68  e ATTACHed to th
d210: 65 20 73 61 6d 65 20 68 61 6e 64 6c 65 20 61 74  e same handle at
d220: 20 73 6f 6d 65 20 0a 20 20 20 20 2a 2a 20 70 6f   some .    ** po
d230: 69 6e 74 20 69 6e 20 74 69 6d 65 29 2e 0a 20 20  int in time)..  
d240: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 21    */.    if( rc!
d250: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
d260: 20 20 20 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f      async.ioErro
d270: 72 20 3d 20 72 63 3b 0a 20 20 20 20 7d 0a 0a 20  r = rc;.    }.. 
d280: 20 20 20 69 66 28 20 61 73 79 6e 63 2e 69 6f 45     if( async.ioE
d290: 72 72 6f 72 20 26 26 20 21 61 73 79 6e 63 2e 70  rror && !async.p
d2a0: 51 75 65 75 65 46 69 72 73 74 20 29 7b 0a 20 20  QueueFirst ){.  
d2b0: 20 20 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65      pthread_mute
d2c0: 78 5f 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 6c 6f  x_lock(&async.lo
d2d0: 63 6b 4d 75 74 65 78 29 3b 0a 20 20 20 20 20 20  ckMutex);.      
d2e0: 69 66 28 20 30 3d 3d 61 73 79 6e 63 2e 70 4c 6f  if( 0==async.pLo
d2f0: 63 6b 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73  ck ){.        as
d300: 79 6e 63 2e 69 6f 45 72 72 6f 72 20 3d 20 53 51  ync.ioError = SQ
d310: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d  LITE_OK;.      }
d320: 0a 20 20 20 20 20 20 70 74 68 72 65 61 64 5f 6d  .      pthread_m
d330: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73 79  utex_unlock(&asy
d340: 6e 63 2e 6c 6f 63 6b 4d 75 74 65 78 29 3b 0a 20  nc.lockMutex);. 
d350: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 44 72 6f     }..    /* Dro
d360: 70 20 74 68 65 20 71 75 65 75 65 20 6d 75 74 65  p the queue mute
d370: 78 20 62 65 66 6f 72 65 20 63 6f 6e 74 69 6e 75  x before continu
d380: 69 6e 67 20 74 6f 20 74 68 65 20 6e 65 78 74 20  ing to the next 
d390: 77 72 69 74 65 20 6f 70 65 72 61 74 69 6f 6e 0a  write operation.
d3a0: 20 20 20 20 2a 2a 20 69 6e 20 6f 72 64 65 72 20      ** in order 
d3b0: 74 6f 20 67 69 76 65 20 6f 74 68 65 72 20 74 68  to give other th
d3c0: 72 65 61 64 73 20 61 20 63 68 61 6e 63 65 20 74  reads a chance t
d3d0: 6f 20 77 6f 72 6b 20 77 69 74 68 20 74 68 65 20  o work with the 
d3e0: 77 72 69 74 65 20 71 75 65 75 65 2e 0a 20 20 20  write queue..   
d3f0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 21 61 73 79   */.    if( !asy
d400: 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74 20 7c  nc.pQueueFirst |
d410: 7c 20 21 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72  | !async.ioError
d420: 20 29 7b 0a 20 20 20 20 20 20 70 74 68 72 65 61   ){.      pthrea
d430: 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26  d_mutex_unlock(&
d440: 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78  async.queueMutex
d450: 29 3b 0a 20 20 20 20 20 20 68 6f 6c 64 69 6e 67  );.      holding
d460: 4d 75 74 65 78 20 3d 20 30 3b 0a 20 20 20 20 20  Mutex = 0;.     
d470: 20 69 66 28 20 61 73 79 6e 63 2e 69 6f 44 65 6c   if( async.ioDel
d480: 61 79 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20  ay>0 ){.        
d490: 70 56 66 73 2d 3e 78 53 6c 65 65 70 28 70 56 66  pVfs->xSleep(pVf
d4a0: 73 2c 20 61 73 79 6e 63 2e 69 6f 44 65 6c 61 79  s, async.ioDelay
d4b0: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
d4c0: 20 20 20 20 20 20 20 20 73 63 68 65 64 5f 79 69          sched_yi
d4d0: 65 6c 64 28 29 3b 0a 20 20 20 20 20 20 7d 0a 20  eld();.      }. 
d4e0: 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 70 74     }.  }.  .  pt
d4f0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
d500: 63 6b 28 26 61 73 79 6e 63 2e 77 72 69 74 65 72  ck(&async.writer
d510: 4d 75 74 65 78 29 3b 0a 20 20 72 65 74 75 72 6e  Mutex);.  return
d520: 20 30 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a   0;.}../********
d530: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
d540: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
d550: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
d560: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
d570: 2a 2a 0a 2a 2a 20 54 68 65 20 72 65 6d 61 69 6e  **.** The remain
d580: 69 6e 67 20 63 6f 64 65 20 64 65 66 69 6e 65 73  ing code defines
d590: 20 61 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65   a Tcl interface
d5a0: 20 66 6f 72 20 74 65 73 74 69 6e 67 20 74 68 65   for testing the
d5b0: 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 0a 2a 2a   asynchronous.**
d5c0: 20 49 4f 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69   IO implementati
d5d0: 6f 6e 20 69 6e 20 74 68 69 73 20 66 69 6c 65 2e  on in this file.
d5e0: 0a 2a 2a 0a 2a 2a 20 54 6f 20 61 64 61 70 74 20  .**.** To adapt 
d5f0: 74 68 65 20 63 6f 64 65 20 74 6f 20 61 20 6e 6f  the code to a no
d600: 6e 2d 54 43 4c 20 65 6e 76 69 72 6f 6e 6d 65 6e  n-TCL environmen
d610: 74 2c 20 64 65 6c 65 74 65 20 6f 72 20 63 6f 6d  t, delete or com
d620: 6d 65 6e 74 20 6f 75 74 0a 2a 2a 20 74 68 65 20  ment out.** the 
d630: 63 6f 64 65 20 74 68 61 74 20 66 6f 6c 6c 6f 77  code that follow
d640: 73 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c  s..*/../*.** sql
d650: 69 74 65 33 61 73 79 6e 63 5f 65 6e 61 62 6c 65  ite3async_enable
d660: 20 3f 59 45 53 2f 4e 4f 3f 0a 2a 2a 0a 2a 2a 20   ?YES/NO?.**.** 
d670: 45 6e 61 62 6c 65 20 6f 72 20 64 69 73 61 62 6c  Enable or disabl
d680: 65 20 74 68 65 20 61 73 79 6e 63 68 72 6f 6e 6f  e the asynchrono
d690: 75 73 20 49 2f 4f 20 62 61 63 6b 65 6e 64 2e 20  us I/O backend. 
d6a0: 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20 69 73   This command is
d6b0: 0a 2a 2a 20 6e 6f 74 20 74 68 72 65 61 64 2d 73  .** not thread-s
d6c0: 61 66 65 2e 20 20 44 6f 20 6e 6f 74 20 63 61 6c  afe.  Do not cal
d6d0: 6c 20 69 74 20 77 68 69 6c 65 20 61 6e 79 20 64  l it while any d
d6e0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
d6f0: 6f 6e 73 0a 2a 2a 20 61 72 65 20 6f 70 65 6e 2e  ons.** are open.
d700: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
d710: 65 73 74 41 73 79 6e 63 45 6e 61 62 6c 65 28 0a  estAsyncEnable(.
d720: 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44    void * clientD
d730: 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72  ata,.  Tcl_Inter
d740: 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74  p *interp,.  int
d750: 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a   objc,.  Tcl_Obj
d760: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29   *CONST objv[].)
d770: 7b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 31 20  {.  if( objc!=1 
d780: 26 26 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20  && objc!=2 ){.  
d790: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
d7a0: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
d7b0: 6a 76 2c 20 22 3f 59 45 53 2f 4e 4f 3f 22 29 3b  jv, "?YES/NO?");
d7c0: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
d7d0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28  ERROR;.  }.  if(
d7e0: 20 6f 62 6a 63 3d 3d 31 20 29 7b 0a 20 20 20 20   objc==1 ){.    
d7f0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
d800: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
d810: 42 6f 6f 6c 65 61 6e 4f 62 6a 28 61 73 79 6e 63  BooleanObj(async
d820: 5f 76 66 73 2e 70 41 70 70 44 61 74 61 21 3d 30  _vfs.pAppData!=0
d830: 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ));.  }else{.   
d840: 20 69 6e 74 20 65 6e 3b 0a 20 20 20 20 69 66 28   int en;.    if(
d850: 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46   Tcl_GetBooleanF
d860: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
d870: 62 6a 76 5b 31 5d 2c 20 26 65 6e 29 20 29 20 72  bjv[1], &en) ) r
d880: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
d890: 0a 20 20 20 20 61 73 79 6e 63 45 6e 61 62 6c 65  .    asyncEnable
d8a0: 28 65 6e 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  (en);.  }.  retu
d8b0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  rn TCL_OK;.}../*
d8c0: 0a 2a 2a 20 73 71 6c 69 74 65 33 61 73 79 6e 63  .** sqlite3async
d8d0: 5f 68 61 6c 74 20 20 22 6e 6f 77 22 7c 22 69 64  _halt  "now"|"id
d8e0: 6c 65 22 7c 22 6e 65 76 65 72 22 0a 2a 2a 0a 2a  le"|"never".**.*
d8f0: 2a 20 53 65 74 20 74 68 65 20 63 6f 6e 64 69 74  * Set the condit
d900: 69 6f 6e 73 20 61 74 20 77 68 69 63 68 20 74 68  ions at which th
d910: 65 20 77 72 69 74 65 72 20 74 68 72 65 61 64 20  e writer thread 
d920: 77 69 6c 6c 20 68 61 6c 74 2e 0a 2a 2f 0a 73 74  will halt..*/.st
d930: 61 74 69 63 20 69 6e 74 20 74 65 73 74 41 73 79  atic int testAsy
d940: 6e 63 48 61 6c 74 28 0a 20 20 76 6f 69 64 20 2a  ncHalt(.  void *
d950: 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54   clientData,.  T
d960: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
d970: 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20  p,.  int objc,. 
d980: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
d990: 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73  objv[].){.  cons
d9a0: 74 20 63 68 61 72 20 2a 7a 43 6f 6e 64 3b 0a 20  t char *zCond;. 
d9b0: 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a   if( objc!=2 ){.
d9c0: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
d9d0: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
d9e0: 6f 62 6a 76 2c 20 22 5c 22 6e 6f 77 5c 22 7c 5c  objv, "\"now\"|\
d9f0: 22 69 64 6c 65 5c 22 7c 5c 22 6e 65 76 65 72 5c  "idle\"|\"never\
da00: 22 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  "");.    return 
da10: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
da20: 20 7a 43 6f 6e 64 20 3d 20 54 63 6c 5f 47 65 74   zCond = Tcl_Get
da30: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b  String(objv[1]);
da40: 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 43  .  if( strcmp(zC
da50: 6f 6e 64 2c 20 22 6e 6f 77 22 29 3d 3d 30 20 29  ond, "now")==0 )
da60: 7b 0a 20 20 20 20 61 73 79 6e 63 2e 77 72 69 74  {.    async.writ
da70: 65 72 48 61 6c 74 4e 6f 77 20 3d 20 31 3b 0a 20  erHaltNow = 1;. 
da80: 20 20 20 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f     pthread_cond_
da90: 62 72 6f 61 64 63 61 73 74 28 26 61 73 79 6e 63  broadcast(&async
daa0: 2e 71 75 65 75 65 53 69 67 6e 61 6c 29 3b 0a 20  .queueSignal);. 
dab0: 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d   }else if( strcm
dac0: 70 28 7a 43 6f 6e 64 2c 20 22 69 64 6c 65 22 29  p(zCond, "idle")
dad0: 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 79 6e 63  ==0 ){.    async
dae0: 2e 77 72 69 74 65 72 48 61 6c 74 57 68 65 6e 49  .writerHaltWhenI
daf0: 64 6c 65 20 3d 20 31 3b 0a 20 20 20 20 61 73 79  dle = 1;.    asy
db00: 6e 63 2e 77 72 69 74 65 72 48 61 6c 74 4e 6f 77  nc.writerHaltNow
db10: 20 3d 20 30 3b 0a 20 20 20 20 70 74 68 72 65 61   = 0;.    pthrea
db20: 64 5f 63 6f 6e 64 5f 62 72 6f 61 64 63 61 73 74  d_cond_broadcast
db30: 28 26 61 73 79 6e 63 2e 71 75 65 75 65 53 69 67  (&async.queueSig
db40: 6e 61 6c 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66  nal);.  }else if
db50: 28 20 73 74 72 63 6d 70 28 7a 43 6f 6e 64 2c 20  ( strcmp(zCond, 
db60: 22 6e 65 76 65 72 22 29 3d 3d 30 20 29 7b 0a 20  "never")==0 ){. 
db70: 20 20 20 61 73 79 6e 63 2e 77 72 69 74 65 72 48     async.writerH
db80: 61 6c 74 57 68 65 6e 49 64 6c 65 20 3d 20 30 3b  altWhenIdle = 0;
db90: 0a 20 20 20 20 61 73 79 6e 63 2e 77 72 69 74 65  .    async.write
dba0: 72 48 61 6c 74 4e 6f 77 20 3d 20 30 3b 0a 20 20  rHaltNow = 0;.  
dbb0: 7d 65 6c 73 65 7b 0a 20 20 20 20 54 63 6c 5f 41  }else{.    Tcl_A
dbc0: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
dbd0: 72 70 2c 20 0a 20 20 20 20 20 20 22 73 68 6f 75  rp, .      "shou
dbe0: 6c 64 20 62 65 20 6f 6e 65 20 6f 66 3a 20 5c 22  ld be one of: \"
dbf0: 6e 6f 77 5c 22 2c 20 5c 22 69 64 6c 65 5c 22 2c  now\", \"idle\",
dc00: 20 6f 72 20 5c 22 6e 65 76 65 72 5c 22 22 2c 20   or \"never\"", 
dc10: 28 63 68 61 72 2a 29 30 29 3b 0a 20 20 20 20 72  (char*)0);.    r
dc20: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
dc30: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 54 43  .  }.  return TC
dc40: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73  L_OK;.}../*.** s
dc50: 71 6c 69 74 65 33 61 73 79 6e 63 5f 64 65 6c 61  qlite3async_dela
dc60: 79 20 3f 4d 53 3f 0a 2a 2a 0a 2a 2a 20 51 75 65  y ?MS?.**.** Que
dc70: 72 79 20 6f 72 20 73 65 74 20 74 68 65 20 6e 75  ry or set the nu
dc80: 6d 62 65 72 20 6f 66 20 6d 69 6c 6c 69 73 65 63  mber of millisec
dc90: 6f 6e 64 73 20 6f 66 20 64 65 6c 61 79 20 69 6e  onds of delay in
dca0: 20 74 68 65 20 77 72 69 74 65 72 0a 2a 2a 20 74   the writer.** t
dcb0: 68 72 65 61 64 20 61 66 74 65 72 20 65 61 63 68  hread after each
dcc0: 20 77 72 69 74 65 20 6f 70 65 72 61 74 69 6f 6e   write operation
dcd0: 2e 20 20 54 68 65 20 64 65 66 61 75 6c 74 20 69  .  The default i
dce0: 73 20 30 2e 20 20 42 79 20 69 6e 63 72 65 61 73  s 0.  By increas
dcf0: 69 6e 67 0a 2a 2a 20 74 68 65 20 6d 65 6d 6f 72  ing.** the memor
dd00: 79 20 64 65 6c 61 79 20 77 65 20 63 61 6e 20 73  y delay we can s
dd10: 69 6d 75 6c 61 74 65 20 74 68 65 20 65 66 66 65  imulate the effe
dd20: 63 74 20 6f 66 20 73 6c 6f 77 20 64 69 73 6b 20  ct of slow disk 
dd30: 49 2f 4f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  I/O..*/.static i
dd40: 6e 74 20 74 65 73 74 41 73 79 6e 63 44 65 6c 61  nt testAsyncDela
dd50: 79 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65  y(.  void * clie
dd60: 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e  ntData,.  Tcl_In
dd70: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
dd80: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
dd90: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
dda0: 5d 0a 29 7b 0a 20 20 69 66 28 20 6f 62 6a 63 21  ].){.  if( objc!
ddb0: 3d 31 20 26 26 20 6f 62 6a 63 21 3d 32 20 29 7b  =1 && objc!=2 ){
ddc0: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
ddd0: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
dde0: 20 6f 62 6a 76 2c 20 22 3f 4d 53 3f 22 29 3b 0a   objv, "?MS?");.
ddf0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
de00: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20  RROR;.  }.  if( 
de10: 6f 62 6a 63 3d 3d 31 20 29 7b 0a 20 20 20 20 54  objc==1 ){.    T
de20: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
de30: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49  interp, Tcl_NewI
de40: 6e 74 4f 62 6a 28 61 73 79 6e 63 2e 69 6f 44 65  ntObj(async.ioDe
de50: 6c 61 79 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  lay));.  }else{.
de60: 20 20 20 20 69 6e 74 20 69 6f 44 65 6c 61 79 3b      int ioDelay;
de70: 0a 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74  .    if( Tcl_Get
de80: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
de90: 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 69 6f 44  p, objv[1], &ioD
dea0: 65 6c 61 79 29 20 29 20 72 65 74 75 72 6e 20 54  elay) ) return T
deb0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 61 73  CL_ERROR;.    as
dec0: 79 6e 63 2e 69 6f 44 65 6c 61 79 20 3d 20 69 6f  ync.ioDelay = io
ded0: 44 65 6c 61 79 3b 0a 20 20 7d 0a 20 20 72 65 74  Delay;.  }.  ret
dee0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn TCL_OK;.}../
def0: 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 61 73 79 6e  *.** sqlite3asyn
df00: 63 5f 73 74 61 72 74 0a 2a 2a 0a 2a 2a 20 53 74  c_start.**.** St
df10: 61 72 74 20 61 20 6e 65 77 20 77 72 69 74 65 72  art a new writer
df20: 20 74 68 72 65 61 64 2e 0a 2a 2f 0a 73 74 61 74   thread..*/.stat
df30: 69 63 20 69 6e 74 20 74 65 73 74 41 73 79 6e 63  ic int testAsync
df40: 53 74 61 72 74 28 0a 20 20 76 6f 69 64 20 2a 20  Start(.  void * 
df50: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
df60: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
df70: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
df80: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
df90: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 70 74 68 72 65  bjv[].){.  pthre
dfa0: 61 64 5f 74 20 78 3b 0a 20 20 69 6e 74 20 72 63  ad_t x;.  int rc
dfb0: 3b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 69 6e 74  ;.  volatile int
dfc0: 20 69 73 53 74 61 72 74 65 64 20 3d 20 30 3b 0a   isStarted = 0;.
dfd0: 20 20 72 63 20 3d 20 70 74 68 72 65 61 64 5f 63    rc = pthread_c
dfe0: 72 65 61 74 65 28 26 78 2c 20 30 2c 20 61 73 79  reate(&x, 0, asy
dff0: 6e 63 57 72 69 74 65 72 54 68 72 65 61 64 2c 20  ncWriterThread, 
e000: 28 76 6f 69 64 20 2a 29 26 69 73 53 74 61 72 74  (void *)&isStart
e010: 65 64 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b  ed);.  if( rc ){
e020: 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52  .    Tcl_AppendR
e030: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 66  esult(interp, "f
e040: 61 69 6c 65 64 20 74 6f 20 63 72 65 61 74 65 20  ailed to create 
e050: 74 68 65 20 74 68 72 65 61 64 22 2c 20 30 29 3b  the thread", 0);
e060: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
e070: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 70 74 68  ERROR;.  }.  pth
e080: 72 65 61 64 5f 64 65 74 61 63 68 28 78 29 3b 0a  read_detach(x);.
e090: 20 20 77 68 69 6c 65 28 20 69 73 53 74 61 72 74    while( isStart
e0a0: 65 64 3d 3d 30 20 29 7b 0a 20 20 20 20 73 63 68  ed==0 ){.    sch
e0b0: 65 64 5f 79 69 65 6c 64 28 29 3b 0a 20 20 7d 0a  ed_yield();.  }.
e0c0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
e0d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65  .}../*.** sqlite
e0e0: 33 61 73 79 6e 63 5f 77 61 69 74 0a 2a 2a 0a 2a  3async_wait.**.*
e0f0: 2a 20 57 61 69 74 20 66 6f 72 20 74 68 65 20 63  * Wait for the c
e100: 75 72 72 65 6e 74 20 77 72 69 74 65 72 20 74 68  urrent writer th
e110: 72 65 61 64 20 74 6f 20 74 65 72 6d 69 6e 61 74  read to terminat
e120: 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  e..**.** If the 
e130: 63 75 72 72 65 6e 74 20 77 72 69 74 65 72 20 74  current writer t
e140: 68 72 65 61 64 20 69 73 20 73 65 74 20 74 6f 20  hread is set to 
e150: 72 75 6e 20 66 6f 72 65 76 65 72 20 74 68 65 6e  run forever then
e160: 20 74 68 69 73 0a 2a 2a 20 63 6f 6d 6d 61 6e 64   this.** command
e170: 20 77 6f 75 6c 64 20 62 6c 6f 63 6b 20 66 6f 72   would block for
e180: 65 76 65 72 2e 20 20 54 6f 20 70 72 65 76 65 6e  ever.  To preven
e190: 74 20 74 68 61 74 2c 20 61 6e 20 65 72 72 6f 72  t that, an error
e1a0: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 0a 2a   is returned. .*
e1b0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73  /.static int tes
e1c0: 74 41 73 79 6e 63 57 61 69 74 28 0a 20 20 76 6f  tAsyncWait(.  vo
e1d0: 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c  id * clientData,
e1e0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
e1f0: 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a  nterp,.  int obj
e200: 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  c,.  Tcl_Obj *CO
e210: 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20  NST objv[].){.  
e220: 69 6e 74 20 63 6e 74 20 3d 20 31 30 3b 0a 20 20  int cnt = 10;.  
e230: 69 66 28 20 61 73 79 6e 63 2e 77 72 69 74 65 72  if( async.writer
e240: 48 61 6c 74 4e 6f 77 3d 3d 30 20 26 26 20 61 73  HaltNow==0 && as
e250: 79 6e 63 2e 77 72 69 74 65 72 48 61 6c 74 57 68  ync.writerHaltWh
e260: 65 6e 49 64 6c 65 3d 3d 30 20 29 7b 0a 20 20 20  enIdle==0 ){.   
e270: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
e280: 74 28 69 6e 74 65 72 70 2c 20 22 77 6f 75 6c 64  t(interp, "would
e290: 20 62 6c 6f 63 6b 20 66 6f 72 65 76 65 72 22 2c   block forever",
e2a0: 20 28 63 68 61 72 2a 29 30 29 3b 0a 20 20 20 20   (char*)0);.    
e2b0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
e2c0: 3b 0a 20 20 7d 0a 0a 20 20 77 68 69 6c 65 28 20  ;.  }..  while( 
e2d0: 63 6e 74 2d 2d 20 26 26 20 21 70 74 68 72 65 61  cnt-- && !pthrea
e2e0: 64 5f 6d 75 74 65 78 5f 74 72 79 6c 6f 63 6b 28  d_mutex_trylock(
e2f0: 26 61 73 79 6e 63 2e 77 72 69 74 65 72 4d 75 74  &async.writerMut
e300: 65 78 29 20 29 7b 0a 20 20 20 20 70 74 68 72 65  ex) ){.    pthre
e310: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
e320: 26 61 73 79 6e 63 2e 77 72 69 74 65 72 4d 75 74  &async.writerMut
e330: 65 78 29 3b 0a 20 20 20 20 73 63 68 65 64 5f 79  ex);.    sched_y
e340: 69 65 6c 64 28 29 3b 0a 20 20 7d 0a 20 20 69 66  ield();.  }.  if
e350: 28 20 63 6e 74 3e 3d 30 20 29 7b 0a 20 20 20 20  ( cnt>=0 ){.    
e360: 41 53 59 4e 43 5f 54 52 41 43 45 28 28 22 57 41  ASYNC_TRACE(("WA
e370: 49 54 5c 6e 22 29 29 3b 0a 20 20 20 20 70 74 68  IT\n"));.    pth
e380: 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28  read_mutex_lock(
e390: 26 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65  &async.queueMute
e3a0: 78 29 3b 0a 20 20 20 20 70 74 68 72 65 61 64 5f  x);.    pthread_
e3b0: 63 6f 6e 64 5f 62 72 6f 61 64 63 61 73 74 28 26  cond_broadcast(&
e3c0: 61 73 79 6e 63 2e 71 75 65 75 65 53 69 67 6e 61  async.queueSigna
e3d0: 6c 29 3b 0a 20 20 20 20 70 74 68 72 65 61 64 5f  l);.    pthread_
e3e0: 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 73  mutex_unlock(&as
e3f0: 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 29 3b  ync.queueMutex);
e400: 0a 20 20 20 20 70 74 68 72 65 61 64 5f 6d 75 74  .    pthread_mut
e410: 65 78 5f 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 77  ex_lock(&async.w
e420: 72 69 74 65 72 4d 75 74 65 78 29 3b 0a 20 20 20  riterMutex);.   
e430: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75   pthread_mutex_u
e440: 6e 6c 6f 63 6b 28 26 61 73 79 6e 63 2e 77 72 69  nlock(&async.wri
e450: 74 65 72 4d 75 74 65 78 29 3b 0a 20 20 7d 65 6c  terMutex);.  }el
e460: 73 65 7b 0a 20 20 20 20 41 53 59 4e 43 5f 54 52  se{.    ASYNC_TR
e470: 41 43 45 28 28 22 4e 4f 2d 57 41 49 54 5c 6e 22  ACE(("NO-WAIT\n"
e480: 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ));.  }.  return
e490: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 0a 23 65 6e   TCL_OK;.}...#en
e4a0: 64 69 66 20 20 2f 2a 20 53 51 4c 49 54 45 5f 4f  dif  /* SQLITE_O
e4b0: 53 5f 55 4e 49 58 20 61 6e 64 20 53 51 4c 49 54  S_UNIX and SQLIT
e4c0: 45 5f 54 48 52 45 41 44 53 41 46 45 20 2a 2f 0a  E_THREADSAFE */.
e4d0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  ./*.** This rout
e4e0: 69 6e 65 20 72 65 67 69 73 74 65 72 73 20 74 68  ine registers th
e4f0: 65 20 63 75 73 74 6f 6d 20 54 43 4c 20 63 6f 6d  e custom TCL com
e500: 6d 61 6e 64 73 20 64 65 66 69 6e 65 64 20 69 6e  mands defined in
e510: 20 74 68 69 73 0a 2a 2a 20 6d 6f 64 75 6c 65 2e   this.** module.
e520: 20 20 54 68 69 73 20 73 68 6f 75 6c 64 20 62 65    This should be
e530: 20 74 68 65 20 6f 6e 6c 79 20 70 72 6f 63 65 64   the only proced
e540: 75 72 65 20 76 69 73 69 62 6c 65 20 66 72 6f 6d  ure visible from
e550: 20 6f 75 74 73 69 64 65 0a 2a 2a 20 6f 66 20 74   outside.** of t
e560: 68 69 73 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 69  his module..*/.i
e570: 6e 74 20 53 71 6c 69 74 65 74 65 73 74 61 73 79  nt Sqlitetestasy
e580: 6e 63 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65  nc_Init(Tcl_Inte
e590: 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a 23 69 66  rp *interp){.#if
e5a0: 20 53 51 4c 49 54 45 5f 4f 53 5f 55 4e 49 58 20   SQLITE_OS_UNIX 
e5b0: 26 26 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44  && SQLITE_THREAD
e5c0: 53 41 46 45 0a 20 20 54 63 6c 5f 43 72 65 61 74  SAFE.  Tcl_Creat
e5d0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
e5e0: 72 70 2c 22 73 71 6c 69 74 65 33 61 73 79 6e 63  rp,"sqlite3async
e5f0: 5f 65 6e 61 62 6c 65 22 2c 74 65 73 74 41 73 79  _enable",testAsy
e600: 6e 63 45 6e 61 62 6c 65 2c 30 2c 30 29 3b 0a 20  ncEnable,0,0);. 
e610: 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f   Tcl_CreateObjCo
e620: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 22 73 71  mmand(interp,"sq
e630: 6c 69 74 65 33 61 73 79 6e 63 5f 68 61 6c 74 22  lite3async_halt"
e640: 2c 74 65 73 74 41 73 79 6e 63 48 61 6c 74 2c 30  ,testAsyncHalt,0
e650: 2c 30 29 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74  ,0);.  Tcl_Creat
e660: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
e670: 72 70 2c 22 73 71 6c 69 74 65 33 61 73 79 6e 63  rp,"sqlite3async
e680: 5f 64 65 6c 61 79 22 2c 74 65 73 74 41 73 79 6e  _delay",testAsyn
e690: 63 44 65 6c 61 79 2c 30 2c 30 29 3b 0a 20 20 54  cDelay,0,0);.  T
e6a0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
e6b0: 61 6e 64 28 69 6e 74 65 72 70 2c 22 73 71 6c 69  and(interp,"sqli
e6c0: 74 65 33 61 73 79 6e 63 5f 73 74 61 72 74 22 2c  te3async_start",
e6d0: 74 65 73 74 41 73 79 6e 63 53 74 61 72 74 2c 30  testAsyncStart,0
e6e0: 2c 30 29 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74  ,0);.  Tcl_Creat
e6f0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
e700: 72 70 2c 22 73 71 6c 69 74 65 33 61 73 79 6e 63  rp,"sqlite3async
e710: 5f 77 61 69 74 22 2c 74 65 73 74 41 73 79 6e 63  _wait",testAsync
e720: 57 61 69 74 2c 30 2c 30 29 3b 0a 20 20 54 63 6c  Wait,0,0);.  Tcl
e730: 5f 4c 69 6e 6b 56 61 72 28 69 6e 74 65 72 70 2c  _LinkVar(interp,
e740: 20 22 73 71 6c 69 74 65 33 61 73 79 6e 63 5f 74   "sqlite3async_t
e750: 72 61 63 65 22 2c 0a 20 20 20 20 20 20 28 63 68  race",.      (ch
e760: 61 72 2a 29 26 73 71 6c 69 74 65 33 61 73 79 6e  ar*)&sqlite3asyn
e770: 63 5f 74 72 61 63 65 2c 20 54 43 4c 5f 4c 49 4e  c_trace, TCL_LIN
e780: 4b 5f 49 4e 54 29 3b 0a 23 65 6e 64 69 66 20 20  K_INT);.#endif  
e790: 2f 2a 20 53 51 4c 49 54 45 5f 4f 53 5f 55 4e 49  /* SQLITE_OS_UNI
e7a0: 58 20 61 6e 64 20 53 51 4c 49 54 45 5f 54 48 52  X and SQLITE_THR
e7b0: 45 41 44 53 41 46 45 20 2a 2f 0a 20 20 72 65 74  EADSAFE */.  ret
e7c0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a        urn TCL_OK;.}.