/ Hex Artifact Content
Login

Artifact a7c6078c82c0bac3b7bea95bc52d5ce7ed58083a:


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 73 71 6c 69 74 65 33 61 73 79 6e 63 2e 63 2c   sqlite3async.c,
0190: 76 20 31 2e 37 20 32 30 30 39 2f 30 37 2f 31 38  v 1.7 2009/07/18
01a0: 20 31 31 3a 35 32 3a 30 34 20 64 61 6e 69 65 6c   11:52:04 daniel
01b0: 6b 31 39 37 37 20 45 78 70 20 24 0a 2a 2a 0a 2a  k1977 Exp $.**.*
01c0: 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f 6e 74  * This file cont
01d0: 61 69 6e 73 20 74 68 65 20 69 6d 70 6c 65 6d 65  ains the impleme
01e0: 6e 74 61 74 69 6f 6e 20 6f 66 20 61 6e 20 61 73  ntation of an as
01f0: 79 6e 63 68 72 6f 6e 6f 75 73 20 49 4f 20 62 61  ynchronous IO ba
0200: 63 6b 65 6e 64 20 0a 2a 2a 20 66 6f 72 20 53 51  ckend .** for SQ
0210: 4c 69 74 65 2e 0a 2a 2f 0a 0a 23 69 66 20 21 64  Lite..*/..#if !d
0220: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43 4f  efined(SQLITE_CO
0230: 52 45 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 53  RE) || defined(S
0240: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 41 53 59  QLITE_ENABLE_ASY
0250: 4e 43 49 4f 29 0a 0a 23 69 6e 63 6c 75 64 65 20  NCIO)..#include 
0260: 22 73 71 6c 69 74 65 33 61 73 79 6e 63 2e 68 22  "sqlite3async.h"
0270: 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74  .#include "sqlit
0280: 65 33 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 3c  e3.h".#include <
0290: 73 74 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c 75  stdarg.h>.#inclu
02a0: 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69  de <string.h>.#i
02b0: 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68  nclude <assert.h
02c0: 3e 0a 0a 2f 2a 20 55 73 65 66 75 6c 20 6d 61 63  >../* Useful mac
02d0: 72 6f 73 20 75 73 65 64 20 69 6e 20 73 65 76 65  ros used in seve
02e0: 72 61 6c 20 70 6c 61 63 65 73 20 2a 2f 0a 23 64  ral places */.#d
02f0: 65 66 69 6e 65 20 4d 49 4e 28 78 2c 79 29 20 28  efine MIN(x,y) (
0300: 28 78 29 3c 28 79 29 3f 28 78 29 3a 28 79 29 29  (x)<(y)?(x):(y))
0310: 0a 23 64 65 66 69 6e 65 20 4d 41 58 28 78 2c 79  .#define MAX(x,y
0320: 29 20 28 28 78 29 3e 28 79 29 3f 28 78 29 3a 28  ) ((x)>(y)?(x):(
0330: 79 29 29 0a 0a 23 69 66 6e 64 65 66 20 53 51 4c  y))..#ifndef SQL
0340: 49 54 45 5f 41 4d 41 4c 47 41 4d 41 54 49 4f 4e  ITE_AMALGAMATION
0350: 0a 2f 2a 20 4d 61 63 72 6f 20 74 6f 20 6d 61 72  ./* Macro to mar
0360: 6b 20 70 61 72 61 6d 65 74 65 72 73 20 61 73 20  k parameters as 
0370: 75 6e 75 73 65 64 20 61 6e 64 20 73 69 6c 65 6e  unused and silen
0380: 63 65 20 63 6f 6d 70 69 6c 65 72 20 77 61 72 6e  ce compiler warn
0390: 69 6e 67 73 2e 20 2a 2f 0a 23 64 65 66 69 6e 65  ings. */.#define
03a0: 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45   UNUSED_PARAMETE
03b0: 52 28 78 29 20 28 76 6f 69 64 29 28 78 29 0a 23  R(x) (void)(x).#
03c0: 65 6e 64 69 66 0a 0a 2f 2a 20 46 6f 72 77 61 72  endif../* Forwar
03d0: 64 20 72 65 66 65 72 65 6e 63 65 73 20 2a 2f 0a  d references */.
03e0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 41  typedef struct A
03f0: 73 79 6e 63 57 72 69 74 65 20 41 73 79 6e 63 57  syncWrite AsyncW
0400: 72 69 74 65 3b 0a 74 79 70 65 64 65 66 20 73 74  rite;.typedef st
0410: 72 75 63 74 20 41 73 79 6e 63 46 69 6c 65 20 41  ruct AsyncFile A
0420: 73 79 6e 63 46 69 6c 65 3b 0a 74 79 70 65 64 65  syncFile;.typede
0430: 66 20 73 74 72 75 63 74 20 41 73 79 6e 63 46 69  f struct AsyncFi
0440: 6c 65 44 61 74 61 20 41 73 79 6e 63 46 69 6c 65  leData AsyncFile
0450: 44 61 74 61 3b 0a 74 79 70 65 64 65 66 20 73 74  Data;.typedef st
0460: 72 75 63 74 20 41 73 79 6e 63 46 69 6c 65 4c 6f  ruct AsyncFileLo
0470: 63 6b 20 41 73 79 6e 63 46 69 6c 65 4c 6f 63 6b  ck AsyncFileLock
0480: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ;.typedef struct
0490: 20 41 73 79 6e 63 4c 6f 63 6b 20 41 73 79 6e 63   AsyncLock Async
04a0: 4c 6f 63 6b 3b 0a 0a 2f 2a 20 45 6e 61 62 6c 65  Lock;../* Enable
04b0: 20 66 6f 72 20 64 65 62 75 67 67 69 6e 67 20 2a   for debugging *
04c0: 2f 0a 23 69 66 6e 64 65 66 20 4e 44 45 42 55 47  /.#ifndef NDEBUG
04d0: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f  .#include <stdio
04e0: 2e 68 3e 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .h>.static int s
04f0: 71 6c 69 74 65 33 61 73 79 6e 63 5f 74 72 61 63  qlite3async_trac
0500: 65 20 3d 20 30 3b 0a 23 20 64 65 66 69 6e 65 20  e = 0;.# define 
0510: 41 53 59 4e 43 5f 54 52 41 43 45 28 58 29 20 69  ASYNC_TRACE(X) i
0520: 66 28 20 73 71 6c 69 74 65 33 61 73 79 6e 63 5f  f( sqlite3async_
0530: 74 72 61 63 65 20 29 20 61 73 79 6e 63 54 72 61  trace ) asyncTra
0540: 63 65 20 58 0a 73 74 61 74 69 63 20 76 6f 69 64  ce X.static void
0550: 20 61 73 79 6e 63 54 72 61 63 65 28 63 6f 6e 73   asyncTrace(cons
0560: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c  t char *zFormat,
0570: 20 2e 2e 2e 29 7b 0a 20 20 63 68 61 72 20 2a 7a   ...){.  char *z
0580: 3b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  ;.  va_list ap;.
0590: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a    va_start(ap, z
05a0: 46 6f 72 6d 61 74 29 3b 0a 20 20 7a 20 3d 20 73  Format);.  z = s
05b0: 71 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66 28  qlite3_vmprintf(
05c0: 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 20 20  zFormat, ap);.  
05d0: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 66 70  va_end(ap);.  fp
05e0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b  rintf(stderr, "[
05f0: 25 64 5d 20 25 73 22 2c 20 30 20 2f 2a 20 28 69  %d] %s", 0 /* (i
0600: 6e 74 29 70 74 68 72 65 61 64 5f 73 65 6c 66 28  nt)pthread_self(
0610: 29 20 2a 2f 2c 20 7a 29 3b 0a 20 20 73 71 6c 69  ) */, z);.  sqli
0620: 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 7d 0a 23  te3_free(z);.}.#
0630: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 41 53  else.# define AS
0640: 59 4e 43 5f 54 52 41 43 45 28 58 29 0a 23 65 6e  YNC_TRACE(X).#en
0650: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 54 48 52 45 41  dif../*.** THREA
0660: 44 20 53 41 46 45 54 59 20 4e 4f 54 45 53 0a 2a  D SAFETY NOTES.*
0670: 2a 0a 2a 2a 20 42 61 73 69 63 20 72 75 6c 65 73  *.** Basic rules
0680: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 42 6f  :.**.**     * Bo
0690: 74 68 20 72 65 61 64 20 61 6e 64 20 77 72 69 74  th read and writ
06a0: 65 20 61 63 63 65 73 73 20 74 6f 20 74 68 65 20  e access to the 
06b0: 67 6c 6f 62 61 6c 20 77 72 69 74 65 2d 6f 70 20  global write-op 
06c0: 71 75 65 75 65 20 6d 75 73 74 20 62 65 20 0a 2a  queue must be .*
06d0: 2a 20 20 20 20 20 20 20 70 72 6f 74 65 63 74 65  *       protecte
06e0: 64 20 62 79 20 74 68 65 20 61 73 79 6e 63 2e 71  d by the async.q
06f0: 75 65 75 65 4d 75 74 65 78 2e 20 41 73 20 61 72  ueueMutex. As ar
0700: 65 20 74 68 65 20 61 73 79 6e 63 2e 69 6f 45 72  e the async.ioEr
0710: 72 6f 72 20 61 6e 64 0a 2a 2a 20 20 20 20 20 20  ror and.**      
0720: 20 61 73 79 6e 63 2e 6e 46 69 6c 65 20 76 61 72   async.nFile var
0730: 69 61 62 6c 65 73 2e 0a 2a 2a 0a 2a 2a 20 20 20  iables..**.**   
0740: 20 20 2a 20 54 68 65 20 61 73 79 6e 63 2e 70 4c    * The async.pL
0750: 6f 63 6b 20 6c 69 73 74 20 61 6e 64 20 61 6c 6c  ock list and all
0760: 20 41 73 79 6e 63 4c 6f 63 6b 20 61 6e 64 20 41   AsyncLock and A
0770: 73 79 6e 63 46 69 6c 65 4c 6f 63 6b 0a 2a 2a 20  syncFileLock.** 
0780: 20 20 20 20 20 20 73 74 72 75 63 74 75 72 65 73        structures
0790: 20 6d 75 73 74 20 62 65 20 70 72 6f 74 65 63 74   must be protect
07a0: 65 64 20 62 79 20 74 68 65 20 61 73 79 6e 63 2e  ed by the async.
07b0: 6c 6f 63 6b 4d 75 74 65 78 20 6d 75 74 65 78 2e  lockMutex mutex.
07c0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 54 68 65  .**.**     * The
07d0: 20 66 69 6c 65 20 68 61 6e 64 6c 65 73 20 66 72   file handles fr
07e0: 6f 6d 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e  om the underlyin
07f0: 67 20 73 79 73 74 65 6d 20 61 72 65 20 6e 6f 74  g system are not
0800: 20 61 73 73 75 6d 65 64 20 74 6f 20 0a 2a 2a 20   assumed to .** 
0810: 20 20 20 20 20 20 62 65 20 74 68 72 65 61 64 20        be thread 
0820: 73 61 66 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20  safe..**.**     
0830: 2a 20 53 65 65 20 74 68 65 20 6c 61 73 74 20 74  * See the last t
0840: 77 6f 20 70 61 72 61 67 72 61 70 68 73 20 75 6e  wo paragraphs un
0850: 64 65 72 20 22 54 68 65 20 57 72 69 74 65 72 20  der "The Writer 
0860: 54 68 72 65 61 64 22 20 66 6f 72 0a 2a 2a 20 20  Thread" for.**  
0870: 20 20 20 20 20 61 6e 20 61 73 73 75 6d 70 74 69       an assumpti
0880: 6f 6e 20 74 6f 20 64 6f 20 77 69 74 68 20 66 69  on to do with fi
0890: 6c 65 2d 68 61 6e 64 6c 65 20 73 79 6e 63 68 72  le-handle synchr
08a0: 6f 6e 69 7a 61 74 69 6f 6e 20 62 79 20 74 68 65  onization by the
08b0: 20 4f 73 2e 0a 2a 2a 0a 2a 2a 20 44 65 61 64 6c   Os..**.** Deadl
08c0: 6f 63 6b 20 70 72 65 76 65 6e 74 69 6f 6e 3a 0a  ock prevention:.
08d0: 2a 2a 0a 2a 2a 20 20 20 20 20 54 68 65 72 65 20  **.**     There 
08e0: 61 72 65 20 74 68 72 65 65 20 6d 75 74 65 78 20  are three mutex 
08f0: 75 73 65 64 20 62 79 20 74 68 65 20 73 79 73 74  used by the syst
0900: 65 6d 3a 20 74 68 65 20 22 77 72 69 74 65 72 22  em: the "writer"
0910: 20 6d 75 74 65 78 2c 20 0a 2a 2a 20 20 20 20 20   mutex, .**     
0920: 74 68 65 20 22 71 75 65 75 65 22 20 6d 75 74 65  the "queue" mute
0930: 78 20 61 6e 64 20 74 68 65 20 22 6c 6f 63 6b 22  x and the "lock"
0940: 20 6d 75 74 65 78 2e 20 52 75 6c 65 73 20 61 72   mutex. Rules ar
0950: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 49  e:.**.**     * I
0960: 74 20 69 73 20 69 6c 6c 65 67 61 6c 20 74 6f 20  t is illegal to 
0970: 62 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 77 72 69  block on the wri
0980: 74 65 72 20 6d 75 74 65 78 20 77 68 65 6e 20 61  ter mutex when a
0990: 6e 79 20 6f 74 68 65 72 20 6d 75 74 65 78 0a 2a  ny other mutex.*
09a0: 2a 20 20 20 20 20 20 20 61 72 65 20 68 65 6c 64  *       are held
09b0: 2c 20 61 6e 64 20 0a 2a 2a 0a 2a 2a 20 20 20 20  , and .**.**    
09c0: 20 2a 20 49 74 20 69 73 20 69 6c 6c 65 67 61 6c   * It is illegal
09d0: 20 74 6f 20 62 6c 6f 63 6b 20 6f 6e 20 74 68 65   to block on the
09e0: 20 71 75 65 75 65 20 6d 75 74 65 78 20 77 68 65   queue mutex whe
09f0: 6e 20 74 68 65 20 6c 6f 63 6b 20 6d 75 74 65 78  n the lock mutex
0a00: 0a 2a 2a 20 20 20 20 20 20 20 69 73 20 68 65 6c  .**       is hel
0a10: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 69 2e 65  d..**.**     i.e
0a20: 2e 20 6d 75 74 65 78 27 73 20 6d 75 73 74 20 62  . mutex's must b
0a30: 65 20 67 72 61 62 62 65 64 20 69 6e 20 74 68 65  e grabbed in the
0a40: 20 6f 72 64 65 72 20 22 77 72 69 74 65 72 22 2c   order "writer",
0a50: 20 22 71 75 65 75 65 22 2c 20 22 6c 6f 63 6b 22   "queue", "lock"
0a60: 2e 0a 2a 2a 0a 2a 2a 20 46 69 6c 65 20 73 79 73  ..**.** File sys
0a70: 74 65 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20 28  tem operations (
0a80: 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c 69 74  invoked by SQLit
0a90: 65 20 74 68 72 65 61 64 29 3a 0a 2a 2a 0a 2a 2a  e thread):.**.**
0aa0: 20 20 20 20 20 78 4f 70 65 6e 0a 2a 2a 20 20 20       xOpen.**   
0ab0: 20 20 78 44 65 6c 65 74 65 0a 2a 2a 20 20 20 20    xDelete.**    
0ac0: 20 78 46 69 6c 65 45 78 69 73 74 73 0a 2a 2a 0a   xFileExists.**.
0ad0: 2a 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 6f  ** File handle o
0ae0: 70 65 72 61 74 69 6f 6e 73 20 28 69 6e 76 6f 6b  perations (invok
0af0: 65 64 20 62 79 20 53 51 4c 69 74 65 20 74 68 72  ed by SQLite thr
0b00: 65 61 64 29 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  ead):.**.**     
0b10: 20 20 20 20 61 73 79 6e 63 57 72 69 74 65 2c 20      asyncWrite, 
0b20: 61 73 79 6e 63 43 6c 6f 73 65 2c 20 61 73 79 6e  asyncClose, asyn
0b30: 63 54 72 75 6e 63 61 74 65 2c 20 61 73 79 6e 63  cTruncate, async
0b40: 53 79 6e 63 20 0a 2a 2a 20 20 20 20 0a 2a 2a 20  Sync .**    .** 
0b50: 20 20 20 20 54 68 65 20 6f 70 65 72 61 74 69 6f      The operatio
0b60: 6e 73 20 61 62 6f 76 65 20 61 64 64 20 61 6e 20  ns above add an 
0b70: 65 6e 74 72 79 20 74 6f 20 74 68 65 20 67 6c 6f  entry to the glo
0b80: 62 61 6c 20 77 72 69 74 65 2d 6f 70 20 6c 69 73  bal write-op lis
0b90: 74 2e 20 54 68 65 79 0a 2a 2a 20 20 20 20 20 70  t. They.**     p
0ba0: 72 65 70 61 72 65 20 74 68 65 20 65 6e 74 72 79  repare the entry
0bb0: 2c 20 61 63 71 75 69 72 65 20 74 68 65 20 61 73  , acquire the as
0bc0: 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78 20 6d  ync.queueMutex m
0bd0: 6f 6d 65 6e 74 61 72 69 6c 79 20 77 68 69 6c 65  omentarily while
0be0: 0a 2a 2a 20 20 20 20 20 6c 69 73 74 20 70 6f 69  .**     list poi
0bf0: 6e 74 65 72 73 20 61 72 65 20 20 6d 61 6e 69 70  nters are  manip
0c00: 75 6c 61 74 65 64 20 74 6f 20 69 6e 73 65 72 74  ulated to insert
0c10: 20 74 68 65 20 6e 65 77 20 65 6e 74 72 79 2c 20   the new entry, 
0c20: 74 68 65 6e 20 72 65 6c 65 61 73 65 0a 2a 2a 20  then release.** 
0c30: 20 20 20 20 74 68 65 20 6d 75 74 65 78 20 61 6e      the mutex an
0c40: 64 20 73 69 67 6e 61 6c 20 74 68 65 20 77 72 69  d signal the wri
0c50: 74 65 72 20 74 68 72 65 61 64 20 74 6f 20 77 61  ter thread to wa
0c60: 6b 65 20 75 70 20 69 6e 20 63 61 73 65 20 69 74  ke up in case it
0c70: 20 68 61 70 70 65 6e 73 0a 2a 2a 20 20 20 20 20   happens.**     
0c80: 74 6f 20 62 65 20 61 73 6c 65 65 70 2e 0a 2a 2a  to be asleep..**
0c90: 0a 2a 2a 20 20 20 20 0a 2a 2a 20 20 20 20 20 20  .**    .**      
0ca0: 20 20 20 61 73 79 6e 63 52 65 61 64 2c 20 61 73     asyncRead, as
0cb0: 79 6e 63 46 69 6c 65 53 69 7a 65 2e 0a 2a 2a 0a  yncFileSize..**.
0cc0: 2a 2a 20 20 20 20 20 52 65 61 64 20 6f 70 65 72  **     Read oper
0cd0: 61 74 69 6f 6e 73 2e 20 42 6f 74 68 20 6f 66 20  ations. Both of 
0ce0: 74 68 65 73 65 20 72 65 61 64 20 66 72 6f 6d 20  these read from 
0cf0: 62 6f 74 68 20 74 68 65 20 75 6e 64 65 72 6c 79  both the underly
0d00: 69 6e 67 20 66 69 6c 65 0a 2a 2a 20 20 20 20 20  ing file.**     
0d10: 66 69 72 73 74 20 74 68 65 6e 20 61 64 6a 75 73  first then adjus
0d20: 74 20 74 68 65 69 72 20 72 65 73 75 6c 74 20 62  t their result b
0d30: 61 73 65 64 20 6f 6e 20 70 65 6e 64 69 6e 67 20  ased on pending 
0d40: 77 72 69 74 65 73 20 69 6e 20 74 68 65 20 0a 2a  writes in the .*
0d50: 2a 20 20 20 20 20 77 72 69 74 65 2d 6f 70 20 71  *     write-op q
0d60: 75 65 75 65 2e 20 20 20 53 6f 20 61 73 79 6e 63  ueue.   So async
0d70: 2e 71 75 65 75 65 4d 75 74 65 78 20 69 73 20 68  .queueMutex is h
0d80: 65 6c 64 20 66 6f 72 20 74 68 65 20 64 75 72 61  eld for the dura
0d90: 74 69 6f 6e 0a 2a 2a 20 20 20 20 20 6f 66 20 74  tion.**     of t
0da0: 68 65 73 65 20 6f 70 65 72 61 74 69 6f 6e 73 20  hese operations 
0db0: 74 6f 20 70 72 65 76 65 6e 74 20 6f 74 68 65 72  to prevent other
0dc0: 20 74 68 72 65 61 64 73 20 66 72 6f 6d 20 63 68   threads from ch
0dd0: 61 6e 67 69 6e 67 20 74 68 65 0a 2a 2a 20 20 20  anging the.**   
0de0: 20 20 71 75 65 75 65 20 69 6e 20 6d 69 64 20 6f    queue in mid o
0df0: 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a 20 20 20 20  peration..**    
0e00: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 20 61  .**.**         a
0e10: 73 79 6e 63 4c 6f 63 6b 2c 20 61 73 79 6e 63 55  syncLock, asyncU
0e20: 6e 6c 6f 63 6b 2c 20 61 73 79 6e 63 43 68 65 63  nlock, asyncChec
0e30: 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 0a 2a 2a  kReservedLock.**
0e40: 20 20 20 20 0a 2a 2a 20 20 20 20 20 54 68 65 73      .**     Thes
0e50: 65 20 70 72 69 6d 69 74 69 76 65 73 20 69 6d 70  e primitives imp
0e60: 6c 65 6d 65 6e 74 20 69 6e 2d 70 72 6f 63 65 73  lement in-proces
0e70: 73 20 6c 6f 63 6b 69 6e 67 20 75 73 69 6e 67 20  s locking using 
0e80: 61 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20  a hash table.** 
0e90: 20 20 20 20 6f 6e 20 74 68 65 20 66 69 6c 65 20      on the file 
0ea0: 6e 61 6d 65 2e 20 20 46 69 6c 65 73 20 61 72 65  name.  Files are
0eb0: 20 6c 6f 63 6b 65 64 20 63 6f 72 72 65 63 74 6c   locked correctl
0ec0: 79 20 66 6f 72 20 63 6f 6e 6e 65 63 74 69 6f 6e  y for connection
0ed0: 73 20 63 6f 6d 69 6e 67 0a 2a 2a 20 20 20 20 20  s coming.**     
0ee0: 66 72 6f 6d 20 74 68 65 20 73 61 6d 65 20 70 72  from the same pr
0ef0: 6f 63 65 73 73 2e 20 20 42 75 74 20 6f 74 68 65  ocess.  But othe
0f00: 72 20 70 72 6f 63 65 73 73 65 73 20 63 61 6e 6e  r processes cann
0f10: 6f 74 20 73 65 65 20 74 68 65 73 65 20 6c 6f 63  ot see these loc
0f20: 6b 73 0a 2a 2a 20 20 20 20 20 61 6e 64 20 77 69  ks.**     and wi
0f30: 6c 6c 20 74 68 65 72 65 66 6f 72 65 20 6e 6f 74  ll therefore not
0f40: 20 68 6f 6e 6f 72 20 74 68 65 6d 2e 0a 2a 2a 0a   honor them..**.
0f50: 2a 2a 0a 2a 2a 20 54 68 65 20 77 72 69 74 65 72  **.** The writer
0f60: 20 74 68 72 65 61 64 3a 0a 2a 2a 0a 2a 2a 20 20   thread:.**.**  
0f70: 20 20 20 54 68 65 20 61 73 79 6e 63 2e 77 72 69     The async.wri
0f80: 74 65 72 4d 75 74 65 78 20 69 73 20 75 73 65 64  terMutex is used
0f90: 20 74 6f 20 6d 61 6b 65 20 73 75 72 65 20 6f 6e   to make sure on
0fa0: 6c 79 20 74 68 65 72 65 20 69 73 20 6f 6e 6c 79  ly there is only
0fb0: 0a 2a 2a 20 20 20 20 20 61 20 73 69 6e 67 6c 65  .**     a single
0fc0: 20 77 72 69 74 65 72 20 74 68 72 65 61 64 20 72   writer thread r
0fd0: 75 6e 6e 69 6e 67 20 61 74 20 61 20 74 69 6d 65  unning at a time
0fe0: 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 49 6e 73 69  ..**.**     Insi
0ff0: 64 65 20 74 68 65 20 77 72 69 74 65 72 20 74 68  de the writer th
1000: 72 65 61 64 20 69 73 20 61 20 6c 6f 6f 70 20 74  read is a loop t
1010: 68 61 74 20 77 6f 72 6b 73 20 6c 69 6b 65 20 74  hat works like t
1020: 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  his:.**.**      
1030: 20 20 20 57 48 49 4c 45 20 28 77 72 69 74 65 2d     WHILE (write-
1040: 6f 70 20 6c 69 73 74 20 69 73 20 6e 6f 74 20 65  op list is not e
1050: 6d 70 74 79 29 0a 2a 2a 20 20 20 20 20 20 20 20  mpty).**        
1060: 20 20 20 20 20 44 6f 20 49 4f 20 6f 70 65 72 61       Do IO opera
1070: 74 69 6f 6e 20 61 74 20 68 65 61 64 20 6f 66 20  tion at head of 
1080: 77 72 69 74 65 2d 6f 70 20 6c 69 73 74 0a 2a 2a  write-op list.**
1090: 20 20 20 20 20 20 20 20 20 20 20 20 20 52 65 6d               Rem
10a0: 6f 76 65 20 65 6e 74 72 79 20 66 72 6f 6d 20 68  ove entry from h
10b0: 65 61 64 20 6f 66 20 77 72 69 74 65 2d 6f 70 20  ead of write-op 
10c0: 6c 69 73 74 0a 2a 2a 20 20 20 20 20 20 20 20 20  list.**         
10d0: 45 4e 44 20 57 48 49 4c 45 0a 2a 2a 0a 2a 2a 20  END WHILE.**.** 
10e0: 20 20 20 20 54 68 65 20 61 73 79 6e 63 2e 71 75      The async.qu
10f0: 65 75 65 4d 75 74 65 78 20 69 73 20 61 6c 77 61  eueMutex is alwa
1100: 79 73 20 68 65 6c 64 20 64 75 72 69 6e 67 20 74  ys held during t
1110: 68 65 20 3c 77 72 69 74 65 2d 6f 70 20 6c 69 73  he <write-op lis
1120: 74 20 69 73 20 0a 2a 2a 20 20 20 20 20 6e 6f 74  t is .**     not
1130: 20 65 6d 70 74 79 3e 20 74 65 73 74 2c 20 61 6e   empty> test, an
1140: 64 20 77 68 65 6e 20 74 68 65 20 65 6e 74 72 79  d when the entry
1150: 20 69 73 20 72 65 6d 6f 76 65 64 20 66 72 6f 6d   is removed from
1160: 20 74 68 65 20 68 65 61 64 0a 2a 2a 20 20 20 20   the head.**    
1170: 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 6f 70   of the write-op
1180: 20 6c 69 73 74 2e 20 53 6f 6d 65 74 69 6d 65 73   list. Sometimes
1190: 20 69 74 20 69 73 20 68 65 6c 64 20 66 6f 72 20   it is held for 
11a0: 74 68 65 20 69 6e 74 65 72 69 6d 0a 2a 2a 20 20  the interim.**  
11b0: 20 20 20 70 65 72 69 6f 64 20 28 77 68 69 6c 65     period (while
11c0: 20 74 68 65 20 49 4f 20 69 73 20 70 65 72 66 6f   the IO is perfo
11d0: 72 6d 65 64 29 2c 20 61 6e 64 20 73 6f 6d 65 74  rmed), and somet
11e0: 69 6d 65 73 20 69 74 20 69 73 0a 2a 2a 20 20 20  imes it is.**   
11f0: 20 20 72 65 6c 69 6e 71 75 69 73 68 65 64 2e 20    relinquished. 
1200: 49 74 20 69 73 20 72 65 6c 69 6e 71 75 69 73 68  It is relinquish
1210: 65 64 20 69 66 20 28 61 29 20 74 68 65 20 49 4f  ed if (a) the IO
1220: 20 6f 70 20 69 73 20 61 6e 0a 2a 2a 20 20 20 20   op is an.**    
1230: 20 41 53 59 4e 43 5f 43 4c 4f 53 45 20 6f 72 20   ASYNC_CLOSE or 
1240: 28 62 29 20 77 68 65 6e 20 74 68 65 20 66 69 6c  (b) when the fil
1250: 65 20 68 61 6e 64 6c 65 20 77 61 73 20 6f 70 65  e handle was ope
1260: 6e 65 64 2c 20 74 77 6f 20 6f 66 0a 2a 2a 20 20  ned, two of.**  
1270: 20 20 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e     the underlyin
1280: 67 20 73 79 73 74 65 6d 73 20 68 61 6e 64 6c 65  g systems handle
1290: 73 20 77 65 72 65 20 6f 70 65 6e 65 64 20 6f 6e  s were opened on
12a0: 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 20 20 20   the same.**    
12b0: 20 66 69 6c 65 2d 73 79 73 74 65 6d 20 65 6e 74   file-system ent
12c0: 72 79 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 49 66  ry..**.**     If
12d0: 20 63 6f 6e 64 69 74 69 6f 6e 20 28 62 29 20 61   condition (b) a
12e0: 62 6f 76 65 20 69 73 20 74 72 75 65 2c 20 74 68  bove is true, th
12f0: 65 6e 20 6f 6e 65 20 66 69 6c 65 2d 68 61 6e 64  en one file-hand
1300: 6c 65 20 0a 2a 2a 20 20 20 20 20 28 41 73 79 6e  le .**     (Asyn
1310: 63 46 69 6c 65 2e 70 42 61 73 65 52 65 61 64 29  cFile.pBaseRead)
1320: 20 69 73 20 75 73 65 64 20 65 78 63 6c 75 73 69   is used exclusi
1330: 76 65 6c 79 20 62 79 20 73 71 6c 69 74 65 20 74  vely by sqlite t
1340: 68 72 65 61 64 73 20 74 6f 20 72 65 61 64 20 74  hreads to read t
1350: 68 65 0a 2a 2a 20 20 20 20 20 66 69 6c 65 2c 20  he.**     file, 
1360: 74 68 65 20 6f 74 68 65 72 20 28 41 73 79 6e 63  the other (Async
1370: 46 69 6c 65 2e 70 42 61 73 65 57 72 69 74 65 29  File.pBaseWrite)
1380: 20 62 79 20 73 71 6c 69 74 65 33 5f 61 73 79 6e   by sqlite3_asyn
1390: 63 5f 66 6c 75 73 68 28 29 20 0a 2a 2a 20 20 20  c_flush() .**   
13a0: 20 20 74 68 72 65 61 64 73 20 74 6f 20 70 65 72    threads to per
13b0: 66 6f 72 6d 20 77 72 69 74 65 28 29 20 6f 70 65  form write() ope
13c0: 72 61 74 69 6f 6e 73 2e 20 54 68 69 73 20 6d 65  rations. This me
13d0: 61 6e 73 20 74 68 61 74 20 72 65 61 64 20 0a 2a  ans that read .*
13e0: 2a 20 20 20 20 20 6f 70 65 72 61 74 69 6f 6e 73  *     operations
13f0: 20 61 72 65 20 6e 6f 74 20 62 6c 6f 63 6b 65 64   are not blocked
1400: 20 62 79 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73   by asynchronous
1410: 20 77 72 69 74 65 73 20 28 61 6c 74 68 6f 75 67   writes (althoug
1420: 68 20 0a 2a 2a 20 20 20 20 20 61 73 79 6e 63 68  h .**     asynch
1430: 72 6f 6e 6f 75 73 20 77 72 69 74 65 73 20 6d 61  ronous writes ma
1440: 79 20 73 74 69 6c 6c 20 62 65 20 62 6c 6f 63 6b  y still be block
1450: 65 64 20 62 79 20 72 65 61 64 73 29 2e 0a 2a 2a  ed by reads)..**
1460: 0a 2a 2a 20 20 20 20 20 54 68 69 73 20 61 73 73  .**     This ass
1470: 75 6d 65 73 20 74 68 61 74 20 74 68 65 20 4f 53  umes that the OS
1480: 20 6b 65 65 70 73 20 74 77 6f 20 68 61 6e 64 6c   keeps two handl
1490: 65 73 20 6f 70 65 6e 20 6f 6e 20 74 68 65 20 73  es open on the s
14a0: 61 6d 65 20 66 69 6c 65 0a 2a 2a 20 20 20 20 20  ame file.**     
14b0: 70 72 6f 70 65 72 6c 79 20 69 6e 20 73 79 6e 63  properly in sync
14c0: 2e 20 54 68 61 74 20 69 73 2c 20 61 6e 79 20 72  . That is, any r
14d0: 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 20 74 68  ead operation th
14e0: 61 74 20 73 74 61 72 74 73 20 61 66 74 65 72 20  at starts after 
14f0: 61 0a 2a 2a 20 20 20 20 20 77 72 69 74 65 20 6f  a.**     write o
1500: 70 65 72 61 74 69 6f 6e 20 6f 6e 20 74 68 65 20  peration on the 
1510: 73 61 6d 65 20 66 69 6c 65 20 73 79 73 74 65 6d  same file system
1520: 20 65 6e 74 72 79 20 68 61 73 20 63 6f 6d 70 6c   entry has compl
1530: 65 74 65 64 20 72 65 74 75 72 6e 73 0a 2a 2a 20  eted returns.** 
1540: 20 20 20 20 64 61 74 61 20 63 6f 6e 73 69 73 74      data consist
1550: 65 6e 74 20 77 69 74 68 20 74 68 65 20 77 72 69  ent with the wri
1560: 74 65 2e 20 57 65 20 61 6c 73 6f 20 61 73 73 75  te. We also assu
1570: 6d 65 20 74 68 61 74 20 69 66 20 6f 6e 65 20 74  me that if one t
1580: 68 72 65 61 64 20 0a 2a 2a 20 20 20 20 20 72 65  hread .**     re
1590: 61 64 73 20 61 20 66 69 6c 65 20 77 68 69 6c 65  ads a file while
15a0: 20 61 6e 6f 74 68 65 72 20 69 73 20 77 72 69 74   another is writ
15b0: 69 6e 67 20 69 74 20 61 6c 6c 20 62 79 74 65 73  ing it all bytes
15c0: 20 6f 74 68 65 72 20 74 68 61 6e 20 74 68 65 0a   other than the.
15d0: 2a 2a 20 20 20 20 20 6f 6e 65 73 20 61 63 74 75  **     ones actu
15e0: 61 6c 6c 79 20 62 65 69 6e 67 20 77 72 69 74 74  ally being writt
15f0: 65 6e 20 63 6f 6e 74 61 69 6e 20 76 61 6c 69 64  en contain valid
1600: 20 64 61 74 61 2e 0a 2a 2a 0a 2a 2a 20 20 20 20   data..**.**    
1610: 20 49 66 20 74 68 65 20 61 62 6f 76 65 20 61 73   If the above as
1620: 73 75 6d 70 74 69 6f 6e 73 20 61 72 65 20 6e 6f  sumptions are no
1630: 74 20 74 72 75 65 2c 20 73 65 74 20 74 68 65 20  t true, set the 
1640: 70 72 65 70 72 6f 63 65 73 73 6f 72 20 73 79 6d  preprocessor sym
1650: 62 6f 6c 0a 2a 2a 20 20 20 20 20 53 51 4c 49 54  bol.**     SQLIT
1660: 45 5f 41 53 59 4e 43 5f 54 57 4f 5f 46 49 4c 45  E_ASYNC_TWO_FILE
1670: 48 41 4e 44 4c 45 53 20 74 6f 20 30 2e 0a 2a 2f  HANDLES to 0..*/
1680: 0a 0a 0a 23 69 66 6e 64 65 66 20 4e 44 45 42 55  ...#ifndef NDEBU
1690: 47 0a 23 20 64 65 66 69 6e 65 20 54 45 53 54 4f  G.# define TESTO
16a0: 4e 4c 59 28 20 58 20 29 20 58 0a 23 65 6c 73 65  NLY( X ) X.#else
16b0: 0a 23 20 64 65 66 69 6e 65 20 54 45 53 54 4f 4e  .# define TESTON
16c0: 4c 59 28 20 58 20 29 0a 23 65 6e 64 69 66 0a 0a  LY( X ).#endif..
16d0: 2f 2a 0a 2a 2a 20 50 4f 52 54 49 4e 47 20 46 55  /*.** PORTING FU
16e0: 4e 43 54 49 4f 4e 53 0a 2a 2a 0a 2a 2a 20 54 68  NCTIONS.**.** Th
16f0: 65 72 65 20 61 72 65 20 74 77 6f 20 64 65 66 69  ere are two defi
1700: 6e 69 74 69 6f 6e 73 20 6f 66 20 74 68 65 20 66  nitions of the f
1710: 6f 6c 6c 6f 77 69 6e 67 20 66 75 6e 63 74 69 6f  ollowing functio
1720: 6e 73 2e 20 4f 6e 65 20 66 6f 72 20 70 74 68 72  ns. One for pthr
1730: 65 61 64 73 0a 2a 2a 20 63 6f 6d 70 61 74 69 62  eads.** compatib
1740: 6c 65 20 73 79 73 74 65 6d 73 20 61 6e 64 20 6f  le systems and o
1750: 6e 65 20 66 6f 72 20 57 69 6e 33 32 2e 20 54 68  ne for Win32. Th
1760: 65 73 65 20 66 75 6e 63 74 69 6f 6e 73 20 69 73  ese functions is
1770: 6f 6c 61 74 65 20 74 68 65 20 4f 53 0a 2a 2a 20  olate the OS.** 
1780: 73 70 65 63 69 66 69 63 20 63 6f 64 65 20 72 65  specific code re
1790: 71 75 69 72 65 64 20 62 79 20 65 61 63 68 20 70  quired by each p
17a0: 6c 61 74 66 6f 72 6d 2e 0a 2a 2a 0a 2a 2a 20 54  latform..**.** T
17b0: 68 65 20 73 79 73 74 65 6d 20 75 73 65 73 20 74  he system uses t
17c0: 68 72 65 65 20 6d 75 74 65 78 65 73 20 61 6e 64  hree mutexes and
17d0: 20 61 20 73 69 6e 67 6c 65 20 63 6f 6e 64 69 74   a single condit
17e0: 69 6f 6e 20 76 61 72 69 61 62 6c 65 2e 20 54 6f  ion variable. To
17f0: 0a 2a 2a 20 62 6c 6f 63 6b 20 6f 6e 20 61 20 6d  .** block on a m
1800: 75 74 65 78 2c 20 61 73 79 6e 63 5f 6d 75 74 65  utex, async_mute
1810: 78 5f 65 6e 74 65 72 28 29 20 69 73 20 63 61 6c  x_enter() is cal
1820: 6c 65 64 2e 20 54 68 65 20 70 61 72 61 6d 65 74  led. The paramet
1830: 65 72 20 70 61 73 73 65 64 0a 2a 2a 20 74 6f 20  er passed.** to 
1840: 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65  async_mutex_ente
1850: 72 28 29 2c 20 77 68 69 63 68 20 6d 75 73 74 20  r(), which must 
1860: 62 65 20 6f 6e 65 20 6f 66 20 41 53 59 4e 43 5f  be one of ASYNC_
1870: 4d 55 54 45 58 5f 4c 4f 43 4b 2c 0a 2a 2a 20 41  MUTEX_LOCK,.** A
1880: 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45  SYNC_MUTEX_QUEUE
1890: 20 6f 72 20 41 53 59 4e 43 5f 4d 55 54 45 58 5f   or ASYNC_MUTEX_
18a0: 57 52 49 54 45 52 2c 20 69 64 65 6e 74 69 66 69  WRITER, identifi
18b0: 65 73 20 77 68 69 63 68 20 6f 66 20 74 68 65 20  es which of the 
18c0: 74 68 72 65 65 0a 2a 2a 20 6d 75 74 65 78 65 73  three.** mutexes
18d0: 20 74 6f 20 6c 6f 63 6b 2e 20 53 69 6d 69 6c 61   to lock. Simila
18e0: 72 6c 79 2c 20 74 6f 20 75 6e 6c 6f 63 6b 20 61  rly, to unlock a
18f0: 20 6d 75 74 65 78 2c 20 61 73 79 6e 63 5f 6d 75   mutex, async_mu
1900: 74 65 78 5f 6c 65 61 76 65 28 29 20 69 73 0a 2a  tex_leave() is.*
1910: 2a 20 63 61 6c 6c 65 64 20 77 69 74 68 20 61 20  * called with a 
1920: 70 61 72 61 6d 65 74 65 72 20 69 64 65 6e 74 69  parameter identi
1930: 66 79 69 6e 67 20 74 68 65 20 6d 75 74 65 78 20  fying the mutex 
1940: 62 65 69 6e 67 20 75 6e 6c 6f 63 6b 65 64 2e 20  being unlocked. 
1950: 4d 75 74 65 78 65 73 0a 2a 2a 20 61 72 65 20 6e  Mutexes.** are n
1960: 6f 74 20 72 65 63 75 72 73 69 76 65 20 2d 20 69  ot recursive - i
1970: 74 20 69 73 20 61 6e 20 65 72 72 6f 72 20 74 6f  t is an error to
1980: 20 63 61 6c 6c 20 61 73 79 6e 63 5f 6d 75 74 65   call async_mute
1990: 78 5f 65 6e 74 65 72 28 29 20 74 6f 0a 2a 2a 20  x_enter() to.** 
19a0: 6c 6f 63 6b 20 61 20 6d 75 74 65 78 20 74 68 61  lock a mutex tha
19b0: 74 20 69 73 20 61 6c 72 65 61 64 79 20 6c 6f 63  t is already loc
19c0: 6b 65 64 2c 20 6f 72 20 74 6f 20 63 61 6c 6c 20  ked, or to call 
19d0: 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76  async_mutex_leav
19e0: 65 28 29 0a 2a 2a 20 74 6f 20 75 6e 6c 6f 63 6b  e().** to unlock
19f0: 20 61 20 6d 75 74 65 78 20 74 68 61 74 20 69 73   a mutex that is
1a00: 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 6c   not currently l
1a10: 6f 63 6b 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  ocked..**.** The
1a20: 20 61 73 79 6e 63 5f 63 6f 6e 64 5f 77 61 69 74   async_cond_wait
1a30: 28 29 20 61 6e 64 20 61 73 79 6e 63 5f 63 6f 6e  () and async_con
1a40: 64 5f 73 69 67 6e 61 6c 28 29 20 66 75 6e 63 74  d_signal() funct
1a50: 69 6f 6e 73 20 61 72 65 20 6d 6f 64 65 6c 6c 65  ions are modelle
1a60: 64 0a 2a 2a 20 6f 6e 20 74 68 65 20 70 74 68 72  d.** on the pthr
1a70: 65 61 64 73 20 66 75 6e 63 74 69 6f 6e 73 20 77  eads functions w
1a80: 69 74 68 20 73 69 6d 69 6c 61 72 20 6e 61 6d 65  ith similar name
1a90: 73 2e 20 54 68 65 20 66 69 72 73 74 20 70 61 72  s. The first par
1aa0: 61 6d 65 74 65 72 20 74 6f 0a 2a 2a 20 62 6f 74  ameter to.** bot
1ab0: 68 20 66 75 6e 63 74 69 6f 6e 73 20 69 73 20 61  h functions is a
1ac0: 6c 77 61 79 73 20 41 53 59 4e 43 5f 43 4f 4e 44  lways ASYNC_COND
1ad0: 5f 51 55 45 55 45 2e 20 57 68 65 6e 20 61 73 79  _QUEUE. When asy
1ae0: 6e 63 5f 63 6f 6e 64 5f 77 61 69 74 28 29 0a 2a  nc_cond_wait().*
1af0: 2a 20 69 73 20 63 61 6c 6c 65 64 20 74 68 65 20  * is called the 
1b00: 6d 75 74 65 78 20 69 64 65 6e 74 69 66 69 65 64  mutex identified
1b10: 20 62 79 20 74 68 65 20 73 65 63 6f 6e 64 20 70   by the second p
1b20: 61 72 61 6d 65 74 65 72 20 6d 75 73 74 20 62 65  arameter must be
1b30: 20 68 65 6c 64 2e 0a 2a 2a 20 54 68 65 20 6d 75   held..** The mu
1b40: 74 65 78 20 69 73 20 75 6e 6c 6f 63 6b 65 64 2c  tex is unlocked,
1b50: 20 61 6e 64 20 74 68 65 20 63 61 6c 6c 69 6e 67   and the calling
1b60: 20 74 68 72 65 61 64 20 73 69 6d 75 6c 74 61 6e   thread simultan
1b70: 65 6f 75 73 6c 79 20 62 65 67 69 6e 73 20 0a 2a  eously begins .*
1b80: 2a 20 77 61 69 74 69 6e 67 20 66 6f 72 20 74 68  * waiting for th
1b90: 65 20 63 6f 6e 64 69 74 69 6f 6e 20 76 61 72 69  e condition vari
1ba0: 61 62 6c 65 20 74 6f 20 62 65 20 73 69 67 6e 61  able to be signa
1bb0: 6c 6c 65 64 20 62 79 20 61 6e 6f 74 68 65 72 20  lled by another 
1bc0: 74 68 72 65 61 64 2e 0a 2a 2a 20 41 66 74 65 72  thread..** After
1bd0: 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20   another thread 
1be0: 73 69 67 6e 61 6c 73 20 74 68 65 20 63 6f 6e 64  signals the cond
1bf0: 69 74 69 6f 6e 20 76 61 72 69 61 62 6c 65 2c 20  ition variable, 
1c00: 74 68 65 20 63 61 6c 6c 69 6e 67 0a 2a 2a 20 74  the calling.** t
1c10: 68 72 65 61 64 20 73 74 6f 70 73 20 77 61 69 74  hread stops wait
1c20: 69 6e 67 2c 20 6c 6f 63 6b 73 20 6d 75 74 65 78  ing, locks mutex
1c30: 20 65 4d 75 74 65 78 20 61 6e 64 20 72 65 74 75   eMutex and retu
1c40: 72 6e 73 2e 20 54 68 65 20 0a 2a 2a 20 61 73 79  rns. The .** asy
1c50: 6e 63 5f 63 6f 6e 64 5f 73 69 67 6e 61 6c 28 29  nc_cond_signal()
1c60: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65   function is use
1c70: 64 20 74 6f 20 73 69 67 6e 61 6c 20 74 68 65 20  d to signal the 
1c80: 63 6f 6e 64 69 74 69 6f 6e 20 76 61 72 69 61 62  condition variab
1c90: 6c 65 2e 20 0a 2a 2a 20 49 74 20 69 73 20 61 73  le. .** It is as
1ca0: 73 75 6d 65 64 20 74 68 61 74 20 74 68 65 20 6d  sumed that the m
1cb0: 75 74 65 78 20 75 73 65 64 20 62 79 20 74 68 65  utex used by the
1cc0: 20 74 68 72 65 61 64 20 63 61 6c 6c 69 6e 67 20   thread calling 
1cd0: 61 73 79 6e 63 5f 63 6f 6e 64 5f 77 61 69 74 28  async_cond_wait(
1ce0: 29 20 0a 2a 2a 20 69 73 20 68 65 6c 64 20 62 79  ) .** is held by
1cf0: 20 74 68 65 20 63 61 6c 6c 65 72 20 6f 66 20 61   the caller of a
1d00: 73 79 6e 63 5f 63 6f 6e 64 5f 73 69 67 6e 61 6c  sync_cond_signal
1d10: 28 29 20 28 6f 74 68 65 72 77 69 73 65 20 74 68  () (otherwise th
1d20: 65 72 65 20 77 6f 75 6c 64 20 62 65 20 0a 2a 2a  ere would be .**
1d30: 20 61 20 72 61 63 65 20 63 6f 6e 64 69 74 69 6f   a race conditio
1d40: 6e 29 2e 0a 2a 2a 0a 2a 2a 20 49 74 20 69 73 20  n)..**.** It is 
1d50: 67 75 61 72 61 6e 74 65 65 64 20 74 68 61 74 20  guaranteed that 
1d60: 6e 6f 20 6f 74 68 65 72 20 74 68 72 65 61 64 20  no other thread 
1d70: 77 69 6c 6c 20 63 61 6c 6c 20 61 73 79 6e 63 5f  will call async_
1d80: 63 6f 6e 64 5f 77 61 69 74 28 29 20 77 68 65 6e  cond_wait() when
1d90: 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 61 6c 72  .** there is alr
1da0: 65 61 64 79 20 61 20 74 68 72 65 61 64 20 77 61  eady a thread wa
1db0: 69 74 69 6e 67 20 6f 6e 20 74 68 65 20 63 6f 6e  iting on the con
1dc0: 64 69 74 69 6f 6e 20 76 61 72 69 61 62 6c 65 2e  dition variable.
1dd0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 73 79 6e 63  .**.** The async
1de0: 5f 73 63 68 65 64 5f 79 69 65 6c 64 28 29 20 66  _sched_yield() f
1df0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
1e00: 64 20 74 6f 20 73 75 67 67 65 73 74 20 74 6f 20  d to suggest to 
1e10: 74 68 65 20 6f 70 65 72 61 74 69 6e 67 0a 2a 2a  the operating.**
1e20: 20 73 79 73 74 65 6d 20 74 68 61 74 20 69 74 20   system that it 
1e30: 77 6f 75 6c 64 20 62 65 20 61 20 67 6f 6f 64 20  would be a good 
1e40: 74 69 6d 65 20 74 6f 20 73 68 69 66 74 20 74 68  time to shift th
1e50: 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
1e60: 20 6f 66 66 20 74 68 65 0a 2a 2a 20 43 50 55 2e   off the.** CPU.
1e70: 20 54 68 65 20 73 79 73 74 65 6d 20 77 69 6c 6c   The system will
1e80: 20 73 74 69 6c 6c 20 77 6f 72 6b 20 69 66 20 74   still work if t
1e90: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
1ea0: 6e 6f 74 20 69 6d 70 6c 65 6d 65 6e 74 65 64 0a  not implemented.
1eb0: 2a 2a 20 28 69 74 20 69 73 20 6e 6f 74 20 63 75  ** (it is not cu
1ec0: 72 72 65 6e 74 6c 79 20 69 6d 70 6c 65 6d 65 6e  rrently implemen
1ed0: 74 65 64 20 66 6f 72 20 77 69 6e 33 32 29 2c 20  ted for win32), 
1ee0: 62 75 74 20 69 74 20 6d 69 67 68 74 20 62 65 20  but it might be 
1ef0: 6d 61 72 67 69 6e 61 6c 6c 79 0a 2a 2a 20 6d 6f  marginally.** mo
1f00: 72 65 20 65 66 66 69 63 69 65 6e 74 20 69 66 20  re efficient if 
1f10: 69 74 20 69 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  it is..*/.static
1f20: 20 76 6f 69 64 20 61 73 79 6e 63 5f 6d 75 74 65   void async_mute
1f30: 78 5f 65 6e 74 65 72 28 69 6e 74 20 65 4d 75 74  x_enter(int eMut
1f40: 65 78 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64  ex);.static void
1f50: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61   async_mutex_lea
1f60: 76 65 28 69 6e 74 20 65 4d 75 74 65 78 29 3b 0a  ve(int eMutex);.
1f70: 73 74 61 74 69 63 20 76 6f 69 64 20 61 73 79 6e  static void asyn
1f80: 63 5f 63 6f 6e 64 5f 77 61 69 74 28 69 6e 74 20  c_cond_wait(int 
1f90: 65 43 6f 6e 64 2c 20 69 6e 74 20 65 4d 75 74 65  eCond, int eMute
1fa0: 78 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64 20  x);.static void 
1fb0: 61 73 79 6e 63 5f 63 6f 6e 64 5f 73 69 67 6e 61  async_cond_signa
1fc0: 6c 28 69 6e 74 20 65 43 6f 6e 64 29 3b 0a 73 74  l(int eCond);.st
1fd0: 61 74 69 63 20 76 6f 69 64 20 61 73 79 6e 63 5f  atic void async_
1fe0: 73 63 68 65 64 5f 79 69 65 6c 64 28 76 6f 69 64  sched_yield(void
1ff0: 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 72 65 20  );../*.** There 
2000: 61 72 65 20 61 6c 73 6f 20 74 77 6f 20 64 65 66  are also two def
2010: 69 6e 69 74 69 6f 6e 73 20 6f 66 20 74 68 65 20  initions of the 
2020: 66 6f 6c 6c 6f 77 69 6e 67 2e 20 61 73 79 6e 63  following. async
2030: 5f 6f 73 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  _os_initialize()
2040: 0a 2a 2a 20 69 73 20 63 61 6c 6c 65 64 20 77 68  .** is called wh
2050: 65 6e 20 74 68 65 20 61 73 79 6e 63 68 72 6f 6e  en the asynchron
2060: 6f 75 73 20 56 46 53 20 69 73 20 66 69 72 73 74  ous VFS is first
2070: 20 69 6e 73 74 61 6c 6c 65 64 2c 20 61 6e 64 20   installed, and 
2080: 6f 73 5f 73 68 75 74 64 6f 77 6e 28 29 0a 2a 2a  os_shutdown().**
2090: 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65 6e 20   is called when 
20a0: 69 74 20 69 73 20 75 6e 69 6e 73 74 61 6c 6c 65  it is uninstalle
20b0: 64 20 28 66 72 6f 6d 20 77 69 74 68 69 6e 20 73  d (from within s
20c0: 71 6c 69 74 65 33 61 73 79 6e 63 5f 73 68 75 74  qlite3async_shut
20d0: 64 6f 77 6e 28 29 29 2e 0a 2a 2a 0a 2a 2a 20 46  down())..**.** F
20e0: 6f 72 20 70 74 68 72 65 61 64 73 20 62 75 69 6c  or pthreads buil
20f0: 64 73 2c 20 62 6f 74 68 20 6f 66 20 74 68 65 73  ds, both of thes
2100: 65 20 66 75 6e 63 74 69 6f 6e 73 20 61 72 65 20  e functions are 
2110: 6e 6f 2d 6f 70 73 2e 20 46 6f 72 20 77 69 6e 33  no-ops. For win3
2120: 32 2c 0a 2a 2a 20 74 68 65 79 20 70 72 6f 76 69  2,.** they provi
2130: 64 65 20 61 6e 20 6f 70 70 6f 72 74 75 6e 69 74  de an opportunit
2140: 79 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  y to initialize 
2150: 61 6e 64 20 66 69 6e 61 6c 69 7a 65 20 74 68 65  and finalize the
2160: 20 72 65 71 75 69 72 65 64 0a 2a 2a 20 6d 75 74   required.** mut
2170: 65 78 20 61 6e 64 20 63 6f 6e 64 69 74 69 6f 6e  ex and condition
2180: 20 76 61 72 69 61 62 6c 65 73 2e 0a 2a 2a 0a 2a   variables..**.*
2190: 2a 20 49 66 20 61 73 79 6e 63 5f 6f 73 5f 69 6e  * If async_os_in
21a0: 69 74 69 61 6c 69 7a 65 28 29 20 72 65 74 75 72  itialize() retur
21b0: 6e 73 20 6f 74 68 65 72 20 74 68 61 6e 20 7a 65  ns other than ze
21c0: 72 6f 2c 20 74 68 65 6e 20 74 68 65 20 69 6e 69  ro, then the ini
21d0: 74 69 61 6c 69 7a 61 74 69 6f 6e 0a 2a 2a 20 66  tialization.** f
21e0: 61 69 6c 73 20 61 6e 64 20 53 51 4c 49 54 45 5f  ails and SQLITE_
21f0: 45 52 52 4f 52 20 69 73 20 72 65 74 75 72 6e 65  ERROR is returne
2200: 64 20 74 6f 20 74 68 65 20 75 73 65 72 2e 0a 2a  d to the user..*
2210: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 73 79  /.static int asy
2220: 6e 63 5f 6f 73 5f 69 6e 69 74 69 61 6c 69 7a 65  nc_os_initialize
2230: 28 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20 76  (void);.static v
2240: 6f 69 64 20 61 73 79 6e 63 5f 6f 73 5f 73 68 75  oid async_os_shu
2250: 74 64 6f 77 6e 28 76 6f 69 64 29 3b 0a 0a 2f 2a  tdown(void);../*
2260: 20 56 61 6c 75 65 73 20 66 6f 72 20 75 73 65 20   Values for use 
2270: 61 73 20 74 68 65 20 27 65 4d 75 74 65 78 27 20  as the 'eMutex' 
2280: 61 72 67 75 6d 65 6e 74 20 6f 66 20 74 68 65 20  argument of the 
2290: 61 62 6f 76 65 20 66 75 6e 63 74 69 6f 6e 73 2e  above functions.
22a0: 20 54 68 65 0a 2a 2a 20 69 6e 74 65 67 65 72 20   The.** integer 
22b0: 76 61 6c 75 65 73 20 61 73 73 69 67 6e 65 64 20  values assigned 
22c0: 74 6f 20 74 68 65 73 65 20 63 6f 6e 73 74 61 6e  to these constan
22d0: 74 73 20 61 72 65 20 69 6d 70 6f 72 74 61 6e 74  ts are important
22e0: 20 66 6f 72 20 61 73 73 65 72 74 28 29 0a 2a 2a   for assert().**
22f0: 20 73 74 61 74 65 6d 65 6e 74 73 20 74 68 61 74   statements that
2300: 20 76 65 72 69 66 79 20 74 68 61 74 20 6d 75 74   verify that mut
2310: 65 78 65 73 20 61 72 65 20 6c 6f 63 6b 65 64 20  exes are locked 
2320: 69 6e 20 74 68 65 20 63 6f 72 72 65 63 74 20 6f  in the correct o
2330: 72 64 65 72 2e 0a 2a 2a 20 53 70 65 63 69 66 69  rder..** Specifi
2340: 63 61 6c 6c 79 2c 20 69 74 20 69 73 20 75 6e 73  cally, it is uns
2350: 61 66 65 20 74 6f 20 74 72 79 20 74 6f 20 6c 6f  afe to try to lo
2360: 63 6b 20 6d 75 74 65 78 20 4e 20 77 68 69 6c 65  ck mutex N while
2370: 20 68 6f 6c 64 69 6e 67 20 61 20 6c 6f 63 6b 20   holding a lock 
2380: 0a 2a 2a 20 6f 6e 20 6d 75 74 65 78 20 4d 20 69  .** on mutex M i
2390: 66 20 28 4d 3c 3d 4e 29 2e 0a 2a 2f 0a 23 64 65  f (M<=N)..*/.#de
23a0: 66 69 6e 65 20 41 53 59 4e 43 5f 4d 55 54 45 58  fine ASYNC_MUTEX
23b0: 5f 4c 4f 43 4b 20 20 20 20 30 0a 23 64 65 66 69  _LOCK    0.#defi
23c0: 6e 65 20 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51  ne ASYNC_MUTEX_Q
23d0: 55 45 55 45 20 20 20 31 0a 23 64 65 66 69 6e 65  UEUE   1.#define
23e0: 20 41 53 59 4e 43 5f 4d 55 54 45 58 5f 57 52 49   ASYNC_MUTEX_WRI
23f0: 54 45 52 20 20 32 0a 0a 2f 2a 20 56 61 6c 75 65  TER  2../* Value
2400: 73 20 66 6f 72 20 75 73 65 20 61 73 20 74 68 65  s for use as the
2410: 20 27 65 43 6f 6e 64 27 20 61 72 67 75 6d 65 6e   'eCond' argumen
2420: 74 20 6f 66 20 74 68 65 20 61 62 6f 76 65 20 66  t of the above f
2430: 75 6e 63 74 69 6f 6e 73 2e 20 2a 2f 0a 23 64 65  unctions. */.#de
2440: 66 69 6e 65 20 41 53 59 4e 43 5f 43 4f 4e 44 5f  fine ASYNC_COND_
2450: 51 55 45 55 45 20 20 20 20 30 0a 0a 2f 2a 2a 2a  QUEUE    0../***
2460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2480: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2490: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
24a0: 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 53 74 61 72 74 20  ******.** Start 
24b0: 6f 66 20 4f 53 20 73 70 65 63 69 66 69 63 20 63  of OS specific c
24c0: 6f 64 65 2e 0a 2a 2f 0a 23 69 66 20 53 51 4c 49  ode..*/.#if SQLI
24d0: 54 45 5f 4f 53 5f 57 49 4e 20 7c 7c 20 64 65 66  TE_OS_WIN || def
24e0: 69 6e 65 64 28 5f 57 49 4e 33 32 29 20 7c 7c 20  ined(_WIN32) || 
24f0: 64 65 66 69 6e 65 64 28 57 49 4e 33 32 29 20 7c  defined(WIN32) |
2500: 7c 20 64 65 66 69 6e 65 64 28 5f 5f 43 59 47 57  | defined(__CYGW
2510: 49 4e 5f 5f 29 20 7c 7c 20 64 65 66 69 6e 65 64  IN__) || defined
2520: 28 5f 5f 4d 49 4e 47 57 33 32 5f 5f 29 20 7c 7c  (__MINGW32__) ||
2530: 20 64 65 66 69 6e 65 64 28 5f 5f 42 4f 52 4c 41   defined(__BORLA
2540: 4e 44 43 5f 5f 29 0a 0a 23 69 6e 63 6c 75 64 65  NDC__)..#include
2550: 20 3c 77 69 6e 64 6f 77 73 2e 68 3e 0a 0a 2f 2a   <windows.h>../*
2560: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62   The following b
2570: 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68  lock contains th
2580: 65 20 77 69 6e 33 32 20 73 70 65 63 69 66 69 63  e win32 specific
2590: 20 63 6f 64 65 2e 20 2a 2f 0a 0a 23 64 65 66 69   code. */..#defi
25a0: 6e 65 20 6d 75 74 65 78 5f 68 65 6c 64 28 58 29  ne mutex_held(X)
25b0: 20 28 47 65 74 43 75 72 72 65 6e 74 54 68 72 65   (GetCurrentThre
25c0: 61 64 49 64 28 29 3d 3d 70 72 69 6d 69 74 69 76  adId()==primitiv
25d0: 65 73 2e 61 48 6f 6c 64 65 72 5b 58 5d 29 0a 0a  es.aHolder[X])..
25e0: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 41 73  static struct As
25f0: 79 6e 63 50 72 69 6d 69 74 69 76 65 73 20 7b 0a  yncPrimitives {.
2600: 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 0a 20 20    int isInit;.  
2610: 44 57 4f 52 44 20 61 48 6f 6c 64 65 72 5b 33 5d  DWORD aHolder[3]
2620: 3b 0a 20 20 43 52 49 54 49 43 41 4c 5f 53 45 43  ;.  CRITICAL_SEC
2630: 54 49 4f 4e 20 61 4d 75 74 65 78 5b 33 5d 3b 0a  TION aMutex[3];.
2640: 20 20 48 41 4e 44 4c 45 20 61 43 6f 6e 64 5b 31    HANDLE aCond[1
2650: 5d 3b 0a 7d 20 70 72 69 6d 69 74 69 76 65 73 20  ];.} primitives 
2660: 3d 20 7b 20 30 20 7d 3b 0a 0a 73 74 61 74 69 63  = { 0 };..static
2670: 20 69 6e 74 20 61 73 79 6e 63 5f 6f 73 5f 69 6e   int async_os_in
2680: 69 74 69 61 6c 69 7a 65 28 76 6f 69 64 29 7b 0a  itialize(void){.
2690: 20 20 69 66 28 20 21 70 72 69 6d 69 74 69 76 65    if( !primitive
26a0: 73 2e 69 73 49 6e 69 74 20 29 7b 0a 20 20 20 20  s.isInit ){.    
26b0: 70 72 69 6d 69 74 69 76 65 73 2e 61 43 6f 6e 64  primitives.aCond
26c0: 5b 30 5d 20 3d 20 43 72 65 61 74 65 45 76 65 6e  [0] = CreateEven
26d0: 74 28 4e 55 4c 4c 2c 20 54 52 55 45 2c 20 46 41  t(NULL, TRUE, FA
26e0: 4c 53 45 2c 20 30 29 3b 0a 20 20 20 20 69 66 28  LSE, 0);.    if(
26f0: 20 70 72 69 6d 69 74 69 76 65 73 2e 61 43 6f 6e   primitives.aCon
2700: 64 5b 30 5d 3d 3d 4e 55 4c 4c 20 29 7b 0a 20 20  d[0]==NULL ){.  
2710: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
2720: 20 20 7d 0a 20 20 20 20 49 6e 69 74 69 61 6c 69    }.    Initiali
2730: 7a 65 43 72 69 74 69 63 61 6c 53 65 63 74 69 6f  zeCriticalSectio
2740: 6e 28 26 70 72 69 6d 69 74 69 76 65 73 2e 61 4d  n(&primitives.aM
2750: 75 74 65 78 5b 30 5d 29 3b 0a 20 20 20 20 49 6e  utex[0]);.    In
2760: 69 74 69 61 6c 69 7a 65 43 72 69 74 69 63 61 6c  itializeCritical
2770: 53 65 63 74 69 6f 6e 28 26 70 72 69 6d 69 74 69  Section(&primiti
2780: 76 65 73 2e 61 4d 75 74 65 78 5b 31 5d 29 3b 0a  ves.aMutex[1]);.
2790: 20 20 20 20 49 6e 69 74 69 61 6c 69 7a 65 43 72      InitializeCr
27a0: 69 74 69 63 61 6c 53 65 63 74 69 6f 6e 28 26 70  iticalSection(&p
27b0: 72 69 6d 69 74 69 76 65 73 2e 61 4d 75 74 65 78  rimitives.aMutex
27c0: 5b 32 5d 29 3b 0a 20 20 20 20 70 72 69 6d 69 74  [2]);.    primit
27d0: 69 76 65 73 2e 69 73 49 6e 69 74 20 3d 20 31 3b  ives.isInit = 1;
27e0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b  .  }.  return 0;
27f0: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  .}.static void a
2800: 73 79 6e 63 5f 6f 73 5f 73 68 75 74 64 6f 77 6e  sync_os_shutdown
2810: 28 76 6f 69 64 29 7b 0a 20 20 69 66 28 20 70 72  (void){.  if( pr
2820: 69 6d 69 74 69 76 65 73 2e 69 73 49 6e 69 74 20  imitives.isInit 
2830: 29 7b 0a 20 20 20 20 44 65 6c 65 74 65 43 72 69  ){.    DeleteCri
2840: 74 69 63 61 6c 53 65 63 74 69 6f 6e 28 26 70 72  ticalSection(&pr
2850: 69 6d 69 74 69 76 65 73 2e 61 4d 75 74 65 78 5b  imitives.aMutex[
2860: 30 5d 29 3b 0a 20 20 20 20 44 65 6c 65 74 65 43  0]);.    DeleteC
2870: 72 69 74 69 63 61 6c 53 65 63 74 69 6f 6e 28 26  riticalSection(&
2880: 70 72 69 6d 69 74 69 76 65 73 2e 61 4d 75 74 65  primitives.aMute
2890: 78 5b 31 5d 29 3b 0a 20 20 20 20 44 65 6c 65 74  x[1]);.    Delet
28a0: 65 43 72 69 74 69 63 61 6c 53 65 63 74 69 6f 6e  eCriticalSection
28b0: 28 26 70 72 69 6d 69 74 69 76 65 73 2e 61 4d 75  (&primitives.aMu
28c0: 74 65 78 5b 32 5d 29 3b 0a 20 20 20 20 43 6c 6f  tex[2]);.    Clo
28d0: 73 65 48 61 6e 64 6c 65 28 70 72 69 6d 69 74 69  seHandle(primiti
28e0: 76 65 73 2e 61 43 6f 6e 64 5b 30 5d 29 3b 0a 20  ves.aCond[0]);. 
28f0: 20 20 20 70 72 69 6d 69 74 69 76 65 73 2e 69 73     primitives.is
2900: 49 6e 69 74 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a  Init = 0;.  }.}.
2910: 0a 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e  ./* The followin
2920: 67 20 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73  g block contains
2930: 20 74 68 65 20 57 69 6e 33 32 20 73 70 65 63 69   the Win32 speci
2940: 66 69 63 20 63 6f 64 65 2e 20 2a 2f 0a 73 74 61  fic code. */.sta
2950: 74 69 63 20 76 6f 69 64 20 61 73 79 6e 63 5f 6d  tic void async_m
2960: 75 74 65 78 5f 65 6e 74 65 72 28 69 6e 74 20 65  utex_enter(int e
2970: 4d 75 74 65 78 29 7b 0a 20 20 61 73 73 65 72 74  Mutex){.  assert
2980: 28 20 65 4d 75 74 65 78 3d 3d 30 20 7c 7c 20 65  ( eMutex==0 || e
2990: 4d 75 74 65 78 3d 3d 31 20 7c 7c 20 65 4d 75 74  Mutex==1 || eMut
29a0: 65 78 3d 3d 32 20 29 3b 0a 20 20 61 73 73 65 72  ex==2 );.  asser
29b0: 74 28 20 65 4d 75 74 65 78 21 3d 32 20 7c 7c 20  t( eMutex!=2 || 
29c0: 28 21 6d 75 74 65 78 5f 68 65 6c 64 28 30 29 20  (!mutex_held(0) 
29d0: 26 26 20 21 6d 75 74 65 78 5f 68 65 6c 64 28 31  && !mutex_held(1
29e0: 29 20 26 26 20 21 6d 75 74 65 78 5f 68 65 6c 64  ) && !mutex_held
29f0: 28 32 29 29 20 29 3b 0a 20 20 61 73 73 65 72 74  (2)) );.  assert
2a00: 28 20 65 4d 75 74 65 78 21 3d 31 20 7c 7c 20 28  ( eMutex!=1 || (
2a10: 21 6d 75 74 65 78 5f 68 65 6c 64 28 30 29 20 26  !mutex_held(0) &
2a20: 26 20 21 6d 75 74 65 78 5f 68 65 6c 64 28 31 29  & !mutex_held(1)
2a30: 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 65  ) );.  assert( e
2a40: 4d 75 74 65 78 21 3d 30 20 7c 7c 20 28 21 6d 75  Mutex!=0 || (!mu
2a50: 74 65 78 5f 68 65 6c 64 28 30 29 29 20 29 3b 0a  tex_held(0)) );.
2a60: 20 20 45 6e 74 65 72 43 72 69 74 69 63 61 6c 53    EnterCriticalS
2a70: 65 63 74 69 6f 6e 28 26 70 72 69 6d 69 74 69 76  ection(&primitiv
2a80: 65 73 2e 61 4d 75 74 65 78 5b 65 4d 75 74 65 78  es.aMutex[eMutex
2a90: 5d 29 3b 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20  ]);.  TESTONLY( 
2aa0: 70 72 69 6d 69 74 69 76 65 73 2e 61 48 6f 6c 64  primitives.aHold
2ab0: 65 72 5b 65 4d 75 74 65 78 5d 20 3d 20 47 65 74  er[eMutex] = Get
2ac0: 43 75 72 72 65 6e 74 54 68 72 65 61 64 49 64 28  CurrentThreadId(
2ad0: 29 3b 20 29 0a 7d 0a 73 74 61 74 69 63 20 76 6f  ); ).}.static vo
2ae0: 69 64 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c  id async_mutex_l
2af0: 65 61 76 65 28 69 6e 74 20 65 4d 75 74 65 78 29  eave(int eMutex)
2b00: 7b 0a 20 20 61 73 73 65 72 74 28 20 65 4d 75 74  {.  assert( eMut
2b10: 65 78 3d 3d 30 20 7c 7c 20 65 4d 75 74 65 78 3d  ex==0 || eMutex=
2b20: 3d 31 20 7c 7c 20 65 4d 75 74 65 78 3d 3d 32 20  =1 || eMutex==2 
2b30: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6d 75 74  );.  assert( mut
2b40: 65 78 5f 68 65 6c 64 28 65 4d 75 74 65 78 29 20  ex_held(eMutex) 
2b50: 29 3b 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 70  );.  TESTONLY( p
2b60: 72 69 6d 69 74 69 76 65 73 2e 61 48 6f 6c 64 65  rimitives.aHolde
2b70: 72 5b 65 4d 75 74 65 78 5d 20 3d 20 30 3b 20 29  r[eMutex] = 0; )
2b80: 0a 20 20 4c 65 61 76 65 43 72 69 74 69 63 61 6c  .  LeaveCritical
2b90: 53 65 63 74 69 6f 6e 28 26 70 72 69 6d 69 74 69  Section(&primiti
2ba0: 76 65 73 2e 61 4d 75 74 65 78 5b 65 4d 75 74 65  ves.aMutex[eMute
2bb0: 78 5d 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f  x]);.}.static vo
2bc0: 69 64 20 61 73 79 6e 63 5f 63 6f 6e 64 5f 77 61  id async_cond_wa
2bd0: 69 74 28 69 6e 74 20 65 43 6f 6e 64 2c 20 69 6e  it(int eCond, in
2be0: 74 20 65 4d 75 74 65 78 29 7b 0a 20 20 52 65 73  t eMutex){.  Res
2bf0: 65 74 45 76 65 6e 74 28 70 72 69 6d 69 74 69 76  etEvent(primitiv
2c00: 65 73 2e 61 43 6f 6e 64 5b 65 43 6f 6e 64 5d 29  es.aCond[eCond])
2c10: 3b 0a 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f  ;.  async_mutex_
2c20: 6c 65 61 76 65 28 65 4d 75 74 65 78 29 3b 0a 20  leave(eMutex);. 
2c30: 20 57 61 69 74 46 6f 72 53 69 6e 67 6c 65 4f 62   WaitForSingleOb
2c40: 6a 65 63 74 28 70 72 69 6d 69 74 69 76 65 73 2e  ject(primitives.
2c50: 61 43 6f 6e 64 5b 65 43 6f 6e 64 5d 2c 20 49 4e  aCond[eCond], IN
2c60: 46 49 4e 49 54 45 29 3b 0a 20 20 61 73 79 6e 63  FINITE);.  async
2c70: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 65 4d 75  _mutex_enter(eMu
2c80: 74 65 78 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76  tex);.}.static v
2c90: 6f 69 64 20 61 73 79 6e 63 5f 63 6f 6e 64 5f 73  oid async_cond_s
2ca0: 69 67 6e 61 6c 28 69 6e 74 20 65 43 6f 6e 64 29  ignal(int eCond)
2cb0: 7b 0a 20 20 61 73 73 65 72 74 28 20 6d 75 74 65  {.  assert( mute
2cc0: 78 5f 68 65 6c 64 28 41 53 59 4e 43 5f 4d 55 54  x_held(ASYNC_MUT
2cd0: 45 58 5f 51 55 45 55 45 29 20 29 3b 0a 20 20 53  EX_QUEUE) );.  S
2ce0: 65 74 45 76 65 6e 74 28 70 72 69 6d 69 74 69 76  etEvent(primitiv
2cf0: 65 73 2e 61 43 6f 6e 64 5b 65 43 6f 6e 64 5d 29  es.aCond[eCond])
2d00: 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20  ;.}.static void 
2d10: 61 73 79 6e 63 5f 73 63 68 65 64 5f 79 69 65 6c  async_sched_yiel
2d20: 64 28 76 6f 69 64 29 7b 0a 20 20 53 6c 65 65 70  d(void){.  Sleep
2d30: 28 30 29 3b 0a 7d 0a 23 65 6c 73 65 0a 0a 2f 2a  (0);.}.#else../*
2d40: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62   The following b
2d50: 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68  lock contains th
2d60: 65 20 70 74 68 72 65 61 64 73 20 73 70 65 63 69  e pthreads speci
2d70: 66 69 63 20 63 6f 64 65 2e 20 2a 2f 0a 23 69 6e  fic code. */.#in
2d80: 63 6c 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68  clude <pthread.h
2d90: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 63 68 65  >.#include <sche
2da0: 64 2e 68 3e 0a 0a 23 64 65 66 69 6e 65 20 6d 75  d.h>..#define mu
2db0: 74 65 78 5f 68 65 6c 64 28 58 29 20 70 74 68 72  tex_held(X) pthr
2dc0: 65 61 64 5f 65 71 75 61 6c 28 70 72 69 6d 69 74  ead_equal(primit
2dd0: 69 76 65 73 2e 61 48 6f 6c 64 65 72 5b 58 5d 2c  ives.aHolder[X],
2de0: 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29   pthread_self())
2df0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 20 61 73  ..static int  as
2e00: 79 6e 63 5f 6f 73 5f 69 6e 69 74 69 61 6c 69 7a  ync_os_initializ
2e10: 65 28 76 6f 69 64 29 20 7b 72 65 74 75 72 6e 20  e(void) {return 
2e20: 30 3b 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20  0;}.static void 
2e30: 61 73 79 6e 63 5f 6f 73 5f 73 68 75 74 64 6f 77  async_os_shutdow
2e40: 6e 28 76 6f 69 64 29 20 7b 7d 0a 0a 73 74 61 74  n(void) {}..stat
2e50: 69 63 20 73 74 72 75 63 74 20 41 73 79 6e 63 50  ic struct AsyncP
2e60: 72 69 6d 69 74 69 76 65 73 20 7b 0a 20 20 70 74  rimitives {.  pt
2e70: 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61 4d  hread_mutex_t aM
2e80: 75 74 65 78 5b 33 5d 3b 0a 20 20 70 74 68 72 65  utex[3];.  pthre
2e90: 61 64 5f 63 6f 6e 64 5f 74 20 61 43 6f 6e 64 5b  ad_cond_t aCond[
2ea0: 31 5d 3b 0a 20 20 70 74 68 72 65 61 64 5f 74 20  1];.  pthread_t 
2eb0: 61 48 6f 6c 64 65 72 5b 33 5d 3b 0a 7d 20 70 72  aHolder[3];.} pr
2ec0: 69 6d 69 74 69 76 65 73 20 3d 20 7b 0a 20 20 7b  imitives = {.  {
2ed0: 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49   PTHREAD_MUTEX_I
2ee0: 4e 49 54 49 41 4c 49 5a 45 52 2c 20 0a 20 20 20  NITIALIZER, .   
2ef0: 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49   PTHREAD_MUTEX_I
2f00: 4e 49 54 49 41 4c 49 5a 45 52 2c 20 0a 20 20 20  NITIALIZER, .   
2f10: 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49   PTHREAD_MUTEX_I
2f20: 4e 49 54 49 41 4c 49 5a 45 52 0a 20 20 7d 20 2c  NITIALIZER.  } ,
2f30: 20 7b 0a 20 20 20 20 50 54 48 52 45 41 44 5f 43   {.    PTHREAD_C
2f40: 4f 4e 44 5f 49 4e 49 54 49 41 4c 49 5a 45 52 0a  OND_INITIALIZER.
2f50: 20 20 7d 20 2c 20 7b 20 30 2c 20 30 2c 20 30 20    } , { 0, 0, 0 
2f60: 7d 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69  }.};..static voi
2f70: 64 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e  d async_mutex_en
2f80: 74 65 72 28 69 6e 74 20 65 4d 75 74 65 78 29 7b  ter(int eMutex){
2f90: 0a 20 20 61 73 73 65 72 74 28 20 65 4d 75 74 65  .  assert( eMute
2fa0: 78 3d 3d 30 20 7c 7c 20 65 4d 75 74 65 78 3d 3d  x==0 || eMutex==
2fb0: 31 20 7c 7c 20 65 4d 75 74 65 78 3d 3d 32 20 29  1 || eMutex==2 )
2fc0: 3b 0a 20 20 61 73 73 65 72 74 28 20 65 4d 75 74  ;.  assert( eMut
2fd0: 65 78 21 3d 32 20 7c 7c 20 28 21 6d 75 74 65 78  ex!=2 || (!mutex
2fe0: 5f 68 65 6c 64 28 30 29 20 26 26 20 21 6d 75 74  _held(0) && !mut
2ff0: 65 78 5f 68 65 6c 64 28 31 29 20 26 26 20 21 6d  ex_held(1) && !m
3000: 75 74 65 78 5f 68 65 6c 64 28 32 29 29 20 29 3b  utex_held(2)) );
3010: 0a 20 20 61 73 73 65 72 74 28 20 65 4d 75 74 65  .  assert( eMute
3020: 78 21 3d 31 20 7c 7c 20 28 21 6d 75 74 65 78 5f  x!=1 || (!mutex_
3030: 68 65 6c 64 28 30 29 20 26 26 20 21 6d 75 74 65  held(0) && !mute
3040: 78 5f 68 65 6c 64 28 31 29 29 20 29 3b 0a 20 20  x_held(1)) );.  
3050: 61 73 73 65 72 74 28 20 65 4d 75 74 65 78 21 3d  assert( eMutex!=
3060: 30 20 7c 7c 20 28 21 6d 75 74 65 78 5f 68 65 6c  0 || (!mutex_hel
3070: 64 28 30 29 29 20 29 3b 0a 20 20 70 74 68 72 65  d(0)) );.  pthre
3080: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 70  ad_mutex_lock(&p
3090: 72 69 6d 69 74 69 76 65 73 2e 61 4d 75 74 65 78  rimitives.aMutex
30a0: 5b 65 4d 75 74 65 78 5d 29 3b 0a 20 20 54 45 53  [eMutex]);.  TES
30b0: 54 4f 4e 4c 59 28 20 70 72 69 6d 69 74 69 76 65  TONLY( primitive
30c0: 73 2e 61 48 6f 6c 64 65 72 5b 65 4d 75 74 65 78  s.aHolder[eMutex
30d0: 5d 20 3d 20 70 74 68 72 65 61 64 5f 73 65 6c 66  ] = pthread_self
30e0: 28 29 3b 20 29 0a 7d 0a 73 74 61 74 69 63 20 76  (); ).}.static v
30f0: 6f 69 64 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f  oid async_mutex_
3100: 6c 65 61 76 65 28 69 6e 74 20 65 4d 75 74 65 78  leave(int eMutex
3110: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 65 4d 75  ){.  assert( eMu
3120: 74 65 78 3d 3d 30 20 7c 7c 20 65 4d 75 74 65 78  tex==0 || eMutex
3130: 3d 3d 31 20 7c 7c 20 65 4d 75 74 65 78 3d 3d 32  ==1 || eMutex==2
3140: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6d 75   );.  assert( mu
3150: 74 65 78 5f 68 65 6c 64 28 65 4d 75 74 65 78 29  tex_held(eMutex)
3160: 20 29 3b 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20   );.  TESTONLY( 
3170: 70 72 69 6d 69 74 69 76 65 73 2e 61 48 6f 6c 64  primitives.aHold
3180: 65 72 5b 65 4d 75 74 65 78 5d 20 3d 20 30 3b 20  er[eMutex] = 0; 
3190: 29 0a 20 20 70 74 68 72 65 61 64 5f 6d 75 74 65  ).  pthread_mute
31a0: 78 5f 75 6e 6c 6f 63 6b 28 26 70 72 69 6d 69 74  x_unlock(&primit
31b0: 69 76 65 73 2e 61 4d 75 74 65 78 5b 65 4d 75 74  ives.aMutex[eMut
31c0: 65 78 5d 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76  ex]);.}.static v
31d0: 6f 69 64 20 61 73 79 6e 63 5f 63 6f 6e 64 5f 77  oid async_cond_w
31e0: 61 69 74 28 69 6e 74 20 65 43 6f 6e 64 2c 20 69  ait(int eCond, i
31f0: 6e 74 20 65 4d 75 74 65 78 29 7b 0a 20 20 61 73  nt eMutex){.  as
3200: 73 65 72 74 28 20 65 4d 75 74 65 78 3d 3d 30 20  sert( eMutex==0 
3210: 7c 7c 20 65 4d 75 74 65 78 3d 3d 31 20 7c 7c 20  || eMutex==1 || 
3220: 65 4d 75 74 65 78 3d 3d 32 20 29 3b 0a 20 20 61  eMutex==2 );.  a
3230: 73 73 65 72 74 28 20 6d 75 74 65 78 5f 68 65 6c  ssert( mutex_hel
3240: 64 28 65 4d 75 74 65 78 29 20 29 3b 0a 20 20 54  d(eMutex) );.  T
3250: 45 53 54 4f 4e 4c 59 28 20 70 72 69 6d 69 74 69  ESTONLY( primiti
3260: 76 65 73 2e 61 48 6f 6c 64 65 72 5b 65 4d 75 74  ves.aHolder[eMut
3270: 65 78 5d 20 3d 20 30 3b 20 29 0a 20 20 70 74 68  ex] = 0; ).  pth
3280: 72 65 61 64 5f 63 6f 6e 64 5f 77 61 69 74 28 26  read_cond_wait(&
3290: 70 72 69 6d 69 74 69 76 65 73 2e 61 43 6f 6e 64  primitives.aCond
32a0: 5b 65 43 6f 6e 64 5d 2c 20 26 70 72 69 6d 69 74  [eCond], &primit
32b0: 69 76 65 73 2e 61 4d 75 74 65 78 5b 65 4d 75 74  ives.aMutex[eMut
32c0: 65 78 5d 29 3b 0a 20 20 54 45 53 54 4f 4e 4c 59  ex]);.  TESTONLY
32d0: 28 20 70 72 69 6d 69 74 69 76 65 73 2e 61 48 6f  ( primitives.aHo
32e0: 6c 64 65 72 5b 65 4d 75 74 65 78 5d 20 3d 20 70  lder[eMutex] = p
32f0: 74 68 72 65 61 64 5f 73 65 6c 66 28 29 3b 20 29  thread_self(); )
3300: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  .}.static void a
3310: 73 79 6e 63 5f 63 6f 6e 64 5f 73 69 67 6e 61 6c  sync_cond_signal
3320: 28 69 6e 74 20 65 43 6f 6e 64 29 7b 0a 20 20 61  (int eCond){.  a
3330: 73 73 65 72 74 28 20 6d 75 74 65 78 5f 68 65 6c  ssert( mutex_hel
3340: 64 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55  d(ASYNC_MUTEX_QU
3350: 45 55 45 29 20 29 3b 0a 20 20 70 74 68 72 65 61  EUE) );.  pthrea
3360: 64 5f 63 6f 6e 64 5f 73 69 67 6e 61 6c 28 26 70  d_cond_signal(&p
3370: 72 69 6d 69 74 69 76 65 73 2e 61 43 6f 6e 64 5b  rimitives.aCond[
3380: 65 43 6f 6e 64 5d 29 3b 0a 7d 0a 73 74 61 74 69  eCond]);.}.stati
3390: 63 20 76 6f 69 64 20 61 73 79 6e 63 5f 73 63 68  c void async_sch
33a0: 65 64 5f 79 69 65 6c 64 28 76 6f 69 64 29 7b 0a  ed_yield(void){.
33b0: 20 20 73 63 68 65 64 5f 79 69 65 6c 64 28 29 3b    sched_yield();
33c0: 0a 7d 0a 23 65 6e 64 69 66 0a 2f 2a 0a 2a 2a 20  .}.#endif./*.** 
33d0: 45 6e 64 20 6f 66 20 4f 53 20 73 70 65 63 69 66  End of OS specif
33e0: 69 63 20 63 6f 64 65 2e 0a 2a 2a 2a 2a 2a 2a 2a  ic code..*******
33f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3400: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3410: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3420: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3430: 2a 2a 2f 0a 0a 23 64 65 66 69 6e 65 20 61 73 73  **/..#define ass
3440: 65 72 74 5f 6d 75 74 65 78 5f 69 73 5f 68 65 6c  ert_mutex_is_hel
3450: 64 28 58 29 20 61 73 73 65 72 74 28 20 6d 75 74  d(X) assert( mut
3460: 65 78 5f 68 65 6c 64 28 58 29 20 29 0a 0a 0a 23  ex_held(X) )...#
3470: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 41 53  ifndef SQLITE_AS
3480: 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e 44  YNC_TWO_FILEHAND
3490: 4c 45 53 0a 2f 2a 20 23 64 65 66 69 6e 65 20 53  LES./* #define S
34a0: 51 4c 49 54 45 5f 41 53 59 4e 43 5f 54 57 4f 5f  QLITE_ASYNC_TWO_
34b0: 46 49 4c 45 48 41 4e 44 4c 45 53 20 30 20 2a 2f  FILEHANDLES 0 */
34c0: 0a 23 64 65 66 69 6e 65 20 53 51 4c 49 54 45 5f  .#define SQLITE_
34d0: 41 53 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41  ASYNC_TWO_FILEHA
34e0: 4e 44 4c 45 53 20 31 0a 23 65 6e 64 69 66 0a 0a  NDLES 1.#endif..
34f0: 2f 2a 0a 2a 2a 20 53 74 61 74 65 20 69 6e 66 6f  /*.** State info
3500: 72 6d 61 74 69 6f 6e 20 69 73 20 68 65 6c 64 20  rmation is held 
3510: 69 6e 20 74 68 65 20 73 74 61 74 69 63 20 76 61  in the static va
3520: 72 69 61 62 6c 65 20 22 61 73 79 6e 63 22 20 64  riable "async" d
3530: 65 66 69 6e 65 64 0a 2a 2a 20 61 73 20 74 68 65  efined.** as the
3540: 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75 63   following struc
3550: 74 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 42 6f 74 68  ture..**.** Both
3560: 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 20 61   async.ioError a
3570: 6e 64 20 61 73 79 6e 63 2e 6e 46 69 6c 65 20 61  nd async.nFile a
3580: 72 65 20 70 72 6f 74 65 63 74 65 64 20 62 79 20  re protected by 
3590: 61 73 79 6e 63 2e 71 75 65 75 65 4d 75 74 65 78  async.queueMutex
35a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75  ..*/.static stru
35b0: 63 74 20 54 65 73 74 41 73 79 6e 63 53 74 61 74  ct TestAsyncStat
35c0: 69 63 44 61 74 61 20 7b 0a 20 20 41 73 79 6e 63  icData {.  Async
35d0: 57 72 69 74 65 20 2a 70 51 75 65 75 65 46 69 72  Write *pQueueFir
35e0: 73 74 3b 20 20 20 20 20 2f 2a 20 4e 65 78 74 20  st;     /* Next 
35f0: 77 72 69 74 65 20 6f 70 65 72 61 74 69 6f 6e 20  write operation 
3600: 74 6f 20 62 65 20 70 72 6f 63 65 73 73 65 64 20  to be processed 
3610: 2a 2f 0a 20 20 41 73 79 6e 63 57 72 69 74 65 20  */.  AsyncWrite 
3620: 2a 70 51 75 65 75 65 4c 61 73 74 3b 20 20 20 20  *pQueueLast;    
3630: 20 20 2f 2a 20 4c 61 73 74 20 77 72 69 74 65 20    /* Last write 
3640: 6f 70 65 72 61 74 69 6f 6e 20 6f 6e 20 74 68 65  operation on the
3650: 20 6c 69 73 74 20 2a 2f 0a 20 20 41 73 79 6e 63   list */.  Async
3660: 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 3b 20 20 20 20  Lock *pLock;    
3670: 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6e 6b 65          /* Linke
3680: 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 41 73  d list of all As
3690: 79 6e 63 4c 6f 63 6b 20 73 74 72 75 63 74 75 72  yncLock structur
36a0: 65 73 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65  es */.  volatile
36b0: 20 69 6e 74 20 69 6f 44 65 6c 61 79 3b 20 20 20   int ioDelay;   
36c0: 20 20 20 20 20 2f 2a 20 45 78 74 72 61 20 64 65       /* Extra de
36d0: 6c 61 79 20 62 65 74 77 65 65 6e 20 77 72 69 74  lay between writ
36e0: 65 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f 0a  e operations */.
36f0: 20 20 76 6f 6c 61 74 69 6c 65 20 69 6e 74 20 65    volatile int e
3700: 48 61 6c 74 3b 20 20 20 20 20 20 20 20 20 20 2f  Halt;          /
3710: 2a 20 4f 6e 65 20 6f 66 20 74 68 65 20 53 51 4c  * One of the SQL
3720: 49 54 45 41 53 59 4e 43 5f 48 41 4c 54 5f 58 58  ITEASYNC_HALT_XX
3730: 58 20 76 61 6c 75 65 73 20 2a 2f 0a 20 20 76 6f  X values */.  vo
3740: 6c 61 74 69 6c 65 20 69 6e 74 20 62 4c 6f 63 6b  latile int bLock
3750: 46 69 6c 65 73 3b 20 20 20 20 20 2f 2a 20 43 75  Files;     /* Cu
3760: 72 72 65 6e 74 20 76 61 6c 75 65 20 6f 66 20 22  rrent value of "
3770: 6c 6f 63 6b 66 69 6c 65 73 22 20 70 61 72 61 6d  lockfiles" param
3780: 65 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69 6f  eter */.  int io
3790: 45 72 72 6f 72 3b 20 20 20 20 20 20 20 20 20 20  Error;          
37a0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
37b0: 66 20 61 6e 20 49 4f 20 65 72 72 6f 72 20 68 61  f an IO error ha
37c0: 73 20 6f 63 63 75 72 72 65 64 20 2a 2f 0a 20 20  s occurred */.  
37d0: 69 6e 74 20 6e 46 69 6c 65 3b 20 20 20 20 20 20  int nFile;      
37e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
37f0: 4e 75 6d 62 65 72 20 6f 66 20 6f 70 65 6e 20 66  Number of open f
3800: 69 6c 65 73 20 28 66 72 6f 6d 20 73 71 6c 69 74  iles (from sqlit
3810: 65 20 70 6f 76 29 20 2a 2f 0a 7d 20 61 73 79 6e  e pov) */.} asyn
3820: 63 20 3d 20 7b 20 30 2c 30 2c 30 2c 30 2c 30 2c  c = { 0,0,0,0,0,
3830: 31 2c 30 2c 30 20 7d 3b 0a 0a 2f 2a 20 50 6f 73  1,0,0 };../* Pos
3840: 73 69 62 6c 65 20 76 61 6c 75 65 73 20 6f 66 20  sible values of 
3850: 41 73 79 6e 63 57 72 69 74 65 2e 6f 70 20 2a 2f  AsyncWrite.op */
3860: 0a 23 64 65 66 69 6e 65 20 41 53 59 4e 43 5f 4e  .#define ASYNC_N
3870: 4f 4f 50 20 20 20 20 20 20 20 20 20 20 30 0a 23  OOP          0.#
3880: 64 65 66 69 6e 65 20 41 53 59 4e 43 5f 57 52 49  define ASYNC_WRI
3890: 54 45 20 20 20 20 20 20 20 20 20 31 0a 23 64 65  TE         1.#de
38a0: 66 69 6e 65 20 41 53 59 4e 43 5f 53 59 4e 43 20  fine ASYNC_SYNC 
38b0: 20 20 20 20 20 20 20 20 20 32 0a 23 64 65 66 69           2.#defi
38c0: 6e 65 20 41 53 59 4e 43 5f 54 52 55 4e 43 41 54  ne ASYNC_TRUNCAT
38d0: 45 20 20 20 20 20 20 33 0a 23 64 65 66 69 6e 65  E      3.#define
38e0: 20 41 53 59 4e 43 5f 43 4c 4f 53 45 20 20 20 20   ASYNC_CLOSE    
38f0: 20 20 20 20 20 34 0a 23 64 65 66 69 6e 65 20 41       4.#define A
3900: 53 59 4e 43 5f 44 45 4c 45 54 45 20 20 20 20 20  SYNC_DELETE     
3910: 20 20 20 35 0a 23 64 65 66 69 6e 65 20 41 53 59     5.#define ASY
3920: 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56 45  NC_OPENEXCLUSIVE
3930: 20 36 0a 23 64 65 66 69 6e 65 20 41 53 59 4e 43   6.#define ASYNC
3940: 5f 55 4e 4c 4f 43 4b 20 20 20 20 20 20 20 20 37  _UNLOCK        7
3950: 0a 0a 2f 2a 20 4e 61 6d 65 73 20 6f 66 20 6f 70  ../* Names of op
3960: 63 6f 64 65 73 2e 20 20 55 73 65 64 20 66 6f 72  codes.  Used for
3970: 20 64 65 62 75 67 67 69 6e 67 20 6f 6e 6c 79 2e   debugging only.
3980: 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68  .** Make sure th
3990: 65 73 65 20 73 74 61 79 20 69 6e 20 73 79 6e 63  ese stay in sync
39a0: 20 77 69 74 68 20 74 68 65 20 6d 61 63 72 6f 73   with the macros
39b0: 20 61 62 6f 76 65 21 0a 2a 2f 0a 73 74 61 74 69   above!.*/.stati
39c0: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a  c const char *az
39d0: 4f 70 63 6f 64 65 4e 61 6d 65 5b 5d 20 3d 20 7b  OpcodeName[] = {
39e0: 0a 20 20 22 4e 4f 4f 50 22 2c 20 22 57 52 49 54  .  "NOOP", "WRIT
39f0: 45 22 2c 20 22 53 59 4e 43 22 2c 20 22 54 52 55  E", "SYNC", "TRU
3a00: 4e 43 41 54 45 22 2c 20 22 43 4c 4f 53 45 22 2c  NCATE", "CLOSE",
3a10: 20 22 44 45 4c 45 54 45 22 2c 20 22 4f 50 45 4e   "DELETE", "OPEN
3a20: 45 58 22 2c 20 22 55 4e 4c 4f 43 4b 22 0a 7d 3b  EX", "UNLOCK".};
3a30: 0a 0a 2f 2a 0a 2a 2a 20 45 6e 74 72 69 65 73 20  ../*.** Entries 
3a40: 6f 6e 20 74 68 65 20 77 72 69 74 65 2d 6f 70 20  on the write-op 
3a50: 71 75 65 75 65 20 61 72 65 20 69 6e 73 74 61 6e  queue are instan
3a60: 63 65 73 20 6f 66 20 74 68 65 20 41 73 79 6e 63  ces of the Async
3a70: 57 72 69 74 65 0a 2a 2a 20 73 74 72 75 63 74 75  Write.** structu
3a80: 72 65 2c 20 64 65 66 69 6e 65 64 20 68 65 72 65  re, defined here
3a90: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65  ..**.** The inte
3aa0: 72 70 72 65 74 61 74 69 6f 6e 20 6f 66 20 74 68  rpretation of th
3ab0: 65 20 69 4f 66 66 73 65 74 20 61 6e 64 20 6e 42  e iOffset and nB
3ac0: 79 74 65 20 76 61 72 69 61 62 6c 65 73 20 76 61  yte variables va
3ad0: 72 69 65 73 20 64 65 70 65 6e 64 69 6e 67 20 0a  ries depending .
3ae0: 2a 2a 20 6f 6e 20 74 68 65 20 76 61 6c 75 65 20  ** on the value 
3af0: 6f 66 20 41 73 79 6e 63 57 72 69 74 65 2e 6f 70  of AsyncWrite.op
3b00: 3a 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43 5f 4e 4f  :.**.** ASYNC_NO
3b10: 4f 50 3a 0a 2a 2a 20 20 20 20 20 4e 6f 20 76 61  OP:.**     No va
3b20: 6c 75 65 73 20 75 73 65 64 2e 0a 2a 2a 0a 2a 2a  lues used..**.**
3b30: 20 41 53 59 4e 43 5f 57 52 49 54 45 3a 0a 2a 2a   ASYNC_WRITE:.**
3b40: 20 20 20 20 20 69 4f 66 66 73 65 74 20 2d 3e 20       iOffset -> 
3b50: 4f 66 66 73 65 74 20 69 6e 20 66 69 6c 65 20 74  Offset in file t
3b60: 6f 20 77 72 69 74 65 20 74 6f 2e 0a 2a 2a 20 20  o write to..**  
3b70: 20 20 20 6e 42 79 74 65 20 20 20 2d 3e 20 4e 75     nByte   -> Nu
3b80: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66  mber of bytes of
3b90: 20 64 61 74 61 20 74 6f 20 77 72 69 74 65 20 28   data to write (
3ba0: 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 7a 42  pointed to by zB
3bb0: 75 66 29 2e 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43  uf)..**.** ASYNC
3bc0: 5f 53 59 4e 43 3a 0a 2a 2a 20 20 20 20 20 6e 42  _SYNC:.**     nB
3bd0: 79 74 65 20 20 20 2d 3e 20 66 6c 61 67 73 20 74  yte   -> flags t
3be0: 6f 20 70 61 73 73 20 74 6f 20 73 71 6c 69 74 65  o pass to sqlite
3bf0: 33 4f 73 53 79 6e 63 28 29 2e 0a 2a 2a 0a 2a 2a  3OsSync()..**.**
3c00: 20 41 53 59 4e 43 5f 54 52 55 4e 43 41 54 45 3a   ASYNC_TRUNCATE:
3c10: 0a 2a 2a 20 20 20 20 20 69 4f 66 66 73 65 74 20  .**     iOffset 
3c20: 2d 3e 20 53 69 7a 65 20 74 6f 20 74 72 75 6e 63  -> Size to trunc
3c30: 61 74 65 20 66 69 6c 65 20 74 6f 2e 0a 2a 2a 20  ate file to..** 
3c40: 20 20 20 20 6e 42 79 74 65 20 20 20 2d 3e 20 55      nByte   -> U
3c50: 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 41 53 59  nused..**.** ASY
3c60: 4e 43 5f 43 4c 4f 53 45 3a 0a 2a 2a 20 20 20 20  NC_CLOSE:.**    
3c70: 20 69 4f 66 66 73 65 74 20 2d 3e 20 55 6e 75 73   iOffset -> Unus
3c80: 65 64 2e 0a 2a 2a 20 20 20 20 20 6e 42 79 74 65  ed..**     nByte
3c90: 20 20 20 2d 3e 20 55 6e 75 73 65 64 2e 0a 2a 2a     -> Unused..**
3ca0: 0a 2a 2a 20 41 53 59 4e 43 5f 44 45 4c 45 54 45  .** ASYNC_DELETE
3cb0: 3a 0a 2a 2a 20 20 20 20 20 69 4f 66 66 73 65 74  :.**     iOffset
3cc0: 20 2d 3e 20 43 6f 6e 74 61 69 6e 73 20 74 68 65   -> Contains the
3cd0: 20 22 73 79 6e 63 44 69 72 22 20 66 6c 61 67 2e   "syncDir" flag.
3ce0: 0a 2a 2a 20 20 20 20 20 6e 42 79 74 65 20 20 20  .**     nByte   
3cf0: 2d 3e 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  -> Number of byt
3d00: 65 73 20 6f 66 20 7a 42 75 66 20 70 6f 69 6e 74  es of zBuf point
3d10: 73 20 74 6f 20 28 66 69 6c 65 20 6e 61 6d 65 29  s to (file name)
3d20: 2e 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43 5f 4f 50  ..**.** ASYNC_OP
3d30: 45 4e 45 58 43 4c 55 53 49 56 45 3a 0a 2a 2a 20  ENEXCLUSIVE:.** 
3d40: 20 20 20 20 69 4f 66 66 73 65 74 20 2d 3e 20 56      iOffset -> V
3d50: 61 6c 75 65 20 6f 66 20 22 64 65 6c 66 6c 61 67  alue of "delflag
3d60: 22 2e 0a 2a 2a 20 20 20 20 20 6e 42 79 74 65 20  "..**     nByte 
3d70: 20 20 2d 3e 20 4e 75 6d 62 65 72 20 6f 66 20 62    -> Number of b
3d80: 79 74 65 73 20 6f 66 20 7a 42 75 66 20 70 6f 69  ytes of zBuf poi
3d90: 6e 74 73 20 74 6f 20 28 66 69 6c 65 20 6e 61 6d  nts to (file nam
3da0: 65 29 2e 0a 2a 2a 0a 2a 2a 20 41 53 59 4e 43 5f  e)..**.** ASYNC_
3db0: 55 4e 4c 4f 43 4b 3a 0a 2a 2a 20 20 20 20 20 6e  UNLOCK:.**     n
3dc0: 42 79 74 65 20 20 20 2d 3e 20 41 72 67 75 6d 65  Byte   -> Argume
3dd0: 6e 74 20 74 6f 20 73 71 6c 69 74 65 33 4f 73 55  nt to sqlite3OsU
3de0: 6e 6c 6f 63 6b 28 29 2e 0a 2a 2a 0a 2a 2a 0a 2a  nlock()..**.**.*
3df0: 2a 20 46 6f 72 20 61 6e 20 41 53 59 4e 43 5f 57  * For an ASYNC_W
3e00: 52 49 54 45 20 6f 70 65 72 61 74 69 6f 6e 2c 20  RITE operation, 
3e10: 7a 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 74  zBuf points to t
3e20: 68 65 20 64 61 74 61 20 74 6f 20 77 72 69 74 65  he data to write
3e30: 20 74 6f 20 74 68 65 20 66 69 6c 65 2e 20 0a 2a   to the file. .*
3e40: 2a 20 54 68 69 73 20 73 70 61 63 65 20 69 73 20  * This space is 
3e50: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 29  sqlite3_malloc()
3e60: 64 20 61 6c 6f 6e 67 20 77 69 74 68 20 74 68 65  d along with the
3e70: 20 41 73 79 6e 63 57 72 69 74 65 20 73 74 72 75   AsyncWrite stru
3e80: 63 74 75 72 65 20 69 6e 20 61 0a 2a 2a 20 73 69  cture in a.** si
3e90: 6e 67 6c 65 20 62 6c 6f 62 2c 20 73 6f 20 69 73  ngle blob, so is
3ea0: 20 64 65 6c 65 74 65 64 20 77 68 65 6e 20 73 71   deleted when sq
3eb0: 6c 69 74 65 33 5f 66 72 65 65 28 29 20 69 73 20  lite3_free() is 
3ec0: 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 70 61  called on the pa
3ed0: 72 65 6e 74 20 0a 2a 2a 20 73 74 72 75 63 74 75  rent .** structu
3ee0: 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 41 73  re..*/.struct As
3ef0: 79 6e 63 57 72 69 74 65 20 7b 0a 20 20 41 73 79  yncWrite {.  Asy
3f00: 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 46 69 6c  ncFileData *pFil
3f10: 65 44 61 74 61 3b 20 20 20 20 2f 2a 20 46 69 6c  eData;    /* Fil
3f20: 65 20 74 6f 20 77 72 69 74 65 20 64 61 74 61 20  e to write data 
3f30: 74 6f 20 6f 72 20 73 79 6e 63 20 2a 2f 0a 20 20  to or sync */.  
3f40: 69 6e 74 20 6f 70 3b 20 20 20 20 20 20 20 20 20  int op;         
3f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3f60: 4f 6e 65 20 6f 66 20 41 53 59 4e 43 5f 78 78 78  One of ASYNC_xxx
3f70: 20 65 74 63 2e 20 2a 2f 0a 20 20 73 71 6c 69 74   etc. */.  sqlit
3f80: 65 5f 69 6e 74 36 34 20 69 4f 66 66 73 65 74 3b  e_int64 iOffset;
3f90: 20 20 20 20 20 20 20 20 2f 2a 20 53 65 65 20 61          /* See a
3fa0: 62 6f 76 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  bove */.  int nB
3fb0: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  yte;          /*
3fc0: 20 53 65 65 20 61 62 6f 76 65 20 2a 2f 0a 20 20   See above */.  
3fd0: 63 68 61 72 20 2a 7a 42 75 66 3b 20 20 20 20 20  char *zBuf;     
3fe0: 20 20 20 20 2f 2a 20 44 61 74 61 20 74 6f 20 77      /* Data to w
3ff0: 72 69 74 65 20 74 6f 20 66 69 6c 65 20 28 6f 72  rite to file (or
4000: 20 4e 55 4c 4c 20 69 66 20 6f 70 21 3d 41 53 59   NULL if op!=ASY
4010: 4e 43 5f 57 52 49 54 45 29 20 2a 2f 0a 20 20 41  NC_WRITE) */.  A
4020: 73 79 6e 63 57 72 69 74 65 20 2a 70 4e 65 78 74  syncWrite *pNext
4030: 3b 20 20 2f 2a 20 4e 65 78 74 20 77 72 69 74 65  ;  /* Next write
4040: 20 6f 70 65 72 61 74 69 6f 6e 20 28 74 6f 20 61   operation (to a
4050: 6e 79 20 66 69 6c 65 29 20 2a 2f 0a 7d 3b 0a 0a  ny file) */.};..
4060: 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63  /*.** An instanc
4070: 65 20 6f 66 20 74 68 69 73 20 73 74 72 75 63 74  e of this struct
4080: 75 72 65 20 69 73 20 63 72 65 61 74 65 64 20 66  ure is created f
4090: 6f 72 20 65 61 63 68 20 64 69 73 74 69 6e 63 74  or each distinct
40a0: 20 6f 70 65 6e 20 66 69 6c 65 20 0a 2a 2a 20 28   open file .** (
40b0: 69 2e 65 2e 20 69 66 20 74 77 6f 20 68 61 6e 64  i.e. if two hand
40c0: 6c 65 73 20 61 72 65 20 6f 70 65 6e 65 64 20 6f  les are opened o
40d0: 6e 20 74 68 65 20 6f 6e 65 20 66 69 6c 65 2c 20  n the one file, 
40e0: 6f 6e 6c 79 20 6f 6e 65 20 6f 66 20 74 68 65 73  only one of thes
40f0: 65 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 73 20  e.** structures 
4100: 69 73 20 61 6c 6c 6f 63 61 74 65 64 29 20 61 6e  is allocated) an
4110: 64 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20  d stored in the 
4120: 61 73 79 6e 63 2e 61 4c 6f 63 6b 20 68 61 73 68  async.aLock hash
4130: 20 74 61 62 6c 65 2e 20 54 68 65 0a 2a 2a 20 6b   table. The.** k
4140: 65 79 73 20 66 6f 72 20 61 73 79 6e 63 2e 61 4c  eys for async.aL
4150: 6f 63 6b 20 61 72 65 20 74 68 65 20 66 75 6c 6c  ock are the full
4160: 20 70 61 74 68 6e 61 6d 65 73 20 6f 66 20 74 68   pathnames of th
4170: 65 20 6f 70 65 6e 65 64 20 66 69 6c 65 73 2e 0a  e opened files..
4180: 2a 2a 0a 2a 2a 20 41 73 79 6e 63 4c 6f 63 6b 2e  **.** AsyncLock.
4190: 70 4c 69 73 74 20 70 6f 69 6e 74 73 20 74 6f 20  pList points to 
41a0: 74 68 65 20 68 65 61 64 20 6f 66 20 61 20 6c 69  the head of a li
41b0: 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 41 73 79  nked list of Asy
41c0: 6e 63 46 69 6c 65 4c 6f 63 6b 0a 2a 2a 20 73 74  ncFileLock.** st
41d0: 72 75 63 74 75 72 65 73 2c 20 6f 6e 65 20 66 6f  ructures, one fo
41e0: 72 20 65 61 63 68 20 68 61 6e 64 6c 65 20 63 75  r each handle cu
41f0: 72 72 65 6e 74 6c 79 20 6f 70 65 6e 20 6f 6e 20  rrently open on 
4200: 74 68 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20  the file..**.** 
4210: 49 66 20 74 68 65 20 6f 70 65 6e 65 64 20 66 69  If the opened fi
4220: 6c 65 20 69 73 20 6e 6f 74 20 61 20 6d 61 69 6e  le is not a main
4230: 2d 64 61 74 61 62 61 73 65 20 28 74 68 65 20 53  -database (the S
4240: 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f  QLITE_OPEN_MAIN_
4250: 44 42 20 69 73 0a 2a 2a 20 6e 6f 74 20 70 61 73  DB is.** not pas
4260: 73 65 64 20 74 6f 20 74 68 65 20 73 71 6c 69 74  sed to the sqlit
4270: 65 33 4f 73 4f 70 65 6e 28 29 20 63 61 6c 6c 29  e3OsOpen() call)
4280: 2c 20 6f 72 20 69 66 20 61 73 79 6e 63 2e 62 4c  , or if async.bL
4290: 6f 63 6b 46 69 6c 65 73 20 69 73 20 0a 2a 2a 20  ockFiles is .** 
42a0: 66 61 6c 73 65 2c 20 76 61 72 69 61 62 6c 65 73  false, variables
42b0: 20 41 73 79 6e 63 4c 6f 63 6b 2e 70 46 69 6c 65   AsyncLock.pFile
42c0: 20 61 6e 64 20 41 73 79 6e 63 4c 6f 63 6b 2e 65   and AsyncLock.e
42d0: 4c 6f 63 6b 20 61 72 65 20 6e 65 76 65 72 20 75  Lock are never u
42e0: 73 65 64 2e 20 0a 2a 2a 20 4f 74 68 65 72 77 69  sed. .** Otherwi
42f0: 73 65 2c 20 70 46 69 6c 65 20 69 73 20 61 20 66  se, pFile is a f
4300: 69 6c 65 20 68 61 6e 64 6c 65 20 6f 70 65 6e 65  ile handle opene
4310: 64 20 6f 6e 20 74 68 65 20 66 69 6c 65 20 69 6e  d on the file in
4320: 20 71 75 65 73 74 69 6f 6e 20 61 6e 64 20 0a 2a   question and .*
4330: 2a 20 75 73 65 64 20 74 6f 20 6f 62 74 61 69 6e  * used to obtain
4340: 20 74 68 65 20 66 69 6c 65 2d 73 79 73 74 65 6d   the file-system
4350: 20 6c 6f 63 6b 73 20 72 65 71 75 69 72 65 64 20   locks required 
4360: 62 79 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  by database conn
4370: 65 63 74 69 6f 6e 73 20 0a 2a 2a 20 77 69 74 68  ections .** with
4380: 69 6e 20 74 68 69 73 20 70 72 6f 63 65 73 73 2e  in this process.
4390: 0a 2a 2a 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d 65  .**.** See comme
43a0: 6e 74 73 20 61 62 6f 76 65 20 74 68 65 20 61 73  nts above the as
43b0: 79 6e 63 4c 6f 63 6b 28 29 20 66 75 6e 63 74 69  yncLock() functi
43c0: 6f 6e 20 66 6f 72 20 6d 6f 72 65 20 64 65 74 61  on for more deta
43d0: 69 6c 73 20 6f 6e 20 0a 2a 2a 20 74 68 65 20 69  ils on .** the i
43e0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
43f0: 20 64 61 74 61 62 61 73 65 20 6c 6f 63 6b 69 6e   database lockin
4400: 67 20 75 73 65 64 20 62 79 20 74 68 69 73 20 62  g used by this b
4410: 61 63 6b 65 6e 64 2e 0a 2a 2f 0a 73 74 72 75 63  ackend..*/.struc
4420: 74 20 41 73 79 6e 63 4c 6f 63 6b 20 7b 0a 20 20  t AsyncLock {.  
4430: 63 68 61 72 20 2a 7a 46 69 6c 65 3b 0a 20 20 69  char *zFile;.  i
4440: 6e 74 20 6e 46 69 6c 65 3b 0a 20 20 73 71 6c 69  nt nFile;.  sqli
4450: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 3b  te3_file *pFile;
4460: 0a 20 20 69 6e 74 20 65 4c 6f 63 6b 3b 0a 20 20  .  int eLock;.  
4470: 41 73 79 6e 63 46 69 6c 65 4c 6f 63 6b 20 2a 70  AsyncFileLock *p
4480: 4c 69 73 74 3b 0a 20 20 41 73 79 6e 63 4c 6f 63  List;.  AsyncLoc
4490: 6b 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20  k *pNext;       
44a0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20 6c      /* Next in l
44b0: 69 6e 6b 65 64 20 6c 69 73 74 20 68 65 61 64 65  inked list heade
44c0: 64 20 62 79 20 61 73 79 6e 63 2e 70 4c 6f 63 6b  d by async.pLock
44d0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e   */.};../*.** An
44e0: 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65   instance of the
44f0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75 63   following struc
4500: 74 75 72 65 20 69 73 20 61 6c 6c 6f 63 61 74 65  ture is allocate
4510: 64 20 61 6c 6f 6e 67 20 77 69 74 68 20 65 61 63  d along with eac
4520: 68 0a 2a 2a 20 41 73 79 6e 63 46 69 6c 65 44 61  h.** AsyncFileDa
4530: 74 61 20 73 74 72 75 63 74 75 72 65 20 28 73 65  ta structure (se
4540: 65 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 2e  e AsyncFileData.
4550: 6c 6f 63 6b 29 2c 20 62 75 74 20 69 73 20 6f 6e  lock), but is on
4560: 6c 79 20 75 73 65 64 20 69 66 20 74 68 65 0a 2a  ly used if the.*
4570: 2a 20 66 69 6c 65 20 77 61 73 20 6f 70 65 6e 65  * file was opene
4580: 64 20 77 69 74 68 20 74 68 65 20 53 51 4c 49 54  d with the SQLIT
4590: 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 2e 0a  E_OPEN_MAIN_DB..
45a0: 2a 2f 0a 73 74 72 75 63 74 20 41 73 79 6e 63 46  */.struct AsyncF
45b0: 69 6c 65 4c 6f 63 6b 20 7b 0a 20 20 69 6e 74 20  ileLock {.  int 
45c0: 65 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20  eLock;          
45d0: 20 20 20 20 20 20 2f 2a 20 49 6e 74 65 72 6e 61        /* Interna
45e0: 6c 6c 79 20 76 69 73 69 62 6c 65 20 6c 6f 63 6b  lly visible lock
45f0: 20 73 74 61 74 65 20 28 73 71 6c 69 74 65 20 70   state (sqlite p
4600: 6f 76 29 20 2a 2f 0a 20 20 69 6e 74 20 65 41 73  ov) */.  int eAs
4610: 79 6e 63 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20  yncLock;        
4620: 20 20 20 2f 2a 20 4c 6f 63 6b 2d 73 74 61 74 65     /* Lock-state
4630: 20 77 69 74 68 20 77 72 69 74 65 2d 71 75 65 75   with write-queu
4640: 65 20 75 6e 6c 6f 63 6b 20 2a 2f 0a 20 20 41 73  e unlock */.  As
4650: 79 6e 63 46 69 6c 65 4c 6f 63 6b 20 2a 70 4e 65  yncFileLock *pNe
4660: 78 74 3b 0a 7d 3b 0a 0a 2f 2a 20 0a 2a 2a 20 54  xt;.};../* .** T
4670: 68 65 20 41 73 79 6e 63 46 69 6c 65 20 73 74 72  he AsyncFile str
4680: 75 63 74 75 72 65 20 69 73 20 61 20 73 75 62 63  ucture is a subc
4690: 6c 61 73 73 20 6f 66 20 73 71 6c 69 74 65 33 5f  lass of sqlite3_
46a0: 66 69 6c 65 20 75 73 65 64 20 66 6f 72 20 0a 2a  file used for .*
46b0: 2a 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49  * asynchronous I
46c0: 4f 2e 20 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 6f 66  O. .**.** All of
46d0: 20 74 68 65 20 61 63 74 75 61 6c 20 64 61 74 61   the actual data
46e0: 20 66 6f 72 20 74 68 65 20 73 74 72 75 63 74 75   for the structu
46f0: 72 65 20 69 73 20 73 74 6f 72 65 64 20 69 6e 20  re is stored in 
4700: 74 68 65 20 73 74 72 75 63 74 75 72 65 0a 2a 2a  the structure.**
4710: 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 41   pointed to by A
4720: 73 79 6e 63 46 69 6c 65 2e 70 44 61 74 61 2c 20  syncFile.pData, 
4730: 77 68 69 63 68 20 69 73 20 61 6c 6c 6f 63 61 74  which is allocat
4740: 65 64 20 61 73 20 70 61 72 74 20 6f 66 20 74 68  ed as part of th
4750: 65 0a 2a 2a 20 73 71 6c 69 74 65 33 4f 73 4f 70  e.** sqlite3OsOp
4760: 65 6e 28 29 20 75 73 69 6e 67 20 73 71 6c 69 74  en() using sqlit
4770: 65 33 5f 6d 61 6c 6c 6f 63 28 29 2e 20 54 68 65  e3_malloc(). The
4780: 20 72 65 61 73 6f 6e 20 66 6f 72 20 74 68 69 73   reason for this
4790: 20 69 73 20 74 68 61 74 20 74 68 65 0a 2a 2a 20   is that the.** 
47a0: 6c 69 66 65 74 69 6d 65 20 6f 66 20 74 68 65 20  lifetime of the 
47b0: 41 73 79 6e 63 46 69 6c 65 20 73 74 72 75 63 74  AsyncFile struct
47c0: 75 72 65 20 69 73 20 65 6e 64 65 64 20 62 79 20  ure is ended by 
47d0: 74 68 65 20 63 61 6c 6c 65 72 20 61 66 74 65 72  the caller after
47e0: 20 4f 73 43 6c 6f 73 65 28 29 0a 2a 2a 20 69 73   OsClose().** is
47f0: 20 63 61 6c 6c 65 64 2c 20 62 75 74 20 74 68 65   called, but the
4800: 20 64 61 74 61 20 69 6e 20 41 73 79 6e 63 46 69   data in AsyncFi
4810: 6c 65 44 61 74 61 20 6d 61 79 20 62 65 20 72 65  leData may be re
4820: 71 75 69 72 65 64 20 62 79 20 74 68 65 0a 2a 2a  quired by the.**
4830: 20 77 72 69 74 65 72 20 74 68 72 65 61 64 20 61   writer thread a
4840: 66 74 65 72 20 74 68 61 74 20 70 6f 69 6e 74 2e  fter that point.
4850: 0a 2a 2f 0a 73 74 72 75 63 74 20 41 73 79 6e 63  .*/.struct Async
4860: 46 69 6c 65 20 7b 0a 20 20 73 71 6c 69 74 65 33  File {.  sqlite3
4870: 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 2a 70 4d 65  _io_methods *pMe
4880: 74 68 6f 64 3b 0a 20 20 41 73 79 6e 63 46 69 6c  thod;.  AsyncFil
4890: 65 44 61 74 61 20 2a 70 44 61 74 61 3b 0a 7d 3b  eData *pData;.};
48a0: 0a 73 74 72 75 63 74 20 41 73 79 6e 63 46 69 6c  .struct AsyncFil
48b0: 65 44 61 74 61 20 7b 0a 20 20 63 68 61 72 20 2a  eData {.  char *
48c0: 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  zName;          
48d0: 20 20 20 20 20 2f 2a 20 55 6e 64 65 72 6c 79 69       /* Underlyi
48e0: 6e 67 20 4f 53 20 66 69 6c 65 6e 61 6d 65 20 2d  ng OS filename -
48f0: 20 75 73 65 64 20 66 6f 72 20 64 65 62 75 67 67   used for debugg
4900: 69 6e 67 20 2a 2f 0a 20 20 69 6e 74 20 6e 4e 61  ing */.  int nNa
4910: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
4920: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
4930: 20 63 68 61 72 61 63 74 65 72 73 20 69 6e 20 7a   characters in z
4940: 4e 61 6d 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  Name */.  sqlite
4950: 33 5f 66 69 6c 65 20 2a 70 42 61 73 65 52 65 61  3_file *pBaseRea
4960: 64 3b 20 20 20 2f 2a 20 52 65 61 64 20 68 61 6e  d;   /* Read han
4970: 64 6c 65 20 74 6f 20 74 68 65 20 75 6e 64 65 72  dle to the under
4980: 6c 79 69 6e 67 20 4f 73 20 66 69 6c 65 20 2a 2f  lying Os file */
4990: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
49a0: 2a 70 42 61 73 65 57 72 69 74 65 3b 20 20 2f 2a  *pBaseWrite;  /*
49b0: 20 57 72 69 74 65 20 68 61 6e 64 6c 65 20 74 6f   Write handle to
49c0: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20   the underlying 
49d0: 4f 73 20 66 69 6c 65 20 2a 2f 0a 20 20 41 73 79  Os file */.  Asy
49e0: 6e 63 46 69 6c 65 4c 6f 63 6b 20 6c 6f 63 6b 3b  ncFileLock lock;
49f0: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 63 6b 20          /* Lock 
4a00: 73 74 61 74 65 20 66 6f 72 20 74 68 69 73 20 68  state for this h
4a10: 61 6e 64 6c 65 20 2a 2f 0a 20 20 41 73 79 6e 63  andle */.  Async
4a20: 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 3b 20 20 20 20  Lock *pLock;    
4a30: 20 20 20 20 20 20 2f 2a 20 41 73 79 6e 63 4c 6f        /* AsyncLo
4a40: 63 6b 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68  ck object for th
4a50: 69 73 20 66 69 6c 65 20 73 79 73 74 65 6d 20 65  is file system e
4a60: 6e 74 72 79 20 2a 2f 0a 20 20 41 73 79 6e 63 57  ntry */.  AsyncW
4a70: 72 69 74 65 20 63 6c 6f 73 65 4f 70 3b 20 20 20  rite closeOp;   
4a80: 20 20 20 20 20 2f 2a 20 50 72 65 61 6c 6c 6f 63       /* Prealloc
4a90: 61 74 65 64 20 63 6c 6f 73 65 20 6f 70 65 72 61  ated close opera
4aa0: 74 69 6f 6e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  tion */.};../*.*
4ab0: 2a 20 41 64 64 20 61 6e 20 65 6e 74 72 79 20 74  * Add an entry t
4ac0: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  o the end of the
4ad0: 20 67 6c 6f 62 61 6c 20 77 72 69 74 65 2d 6f 70   global write-op
4ae0: 20 6c 69 73 74 2e 20 70 57 72 69 74 65 20 73 68   list. pWrite sh
4af0: 6f 75 6c 64 20 70 6f 69 6e 74 20 0a 2a 2a 20 74  ould point .** t
4b00: 6f 20 61 6e 20 41 73 79 6e 63 57 72 69 74 65 20  o an AsyncWrite 
4b10: 73 74 72 75 63 74 75 72 65 20 61 6c 6c 6f 63 61  structure alloca
4b20: 74 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65  ted using sqlite
4b30: 33 5f 6d 61 6c 6c 6f 63 28 29 2e 20 20 54 68 65  3_malloc().  The
4b40: 20 77 72 69 74 65 72 0a 2a 2a 20 74 68 72 65 61   writer.** threa
4b50: 64 20 77 69 6c 6c 20 63 61 6c 6c 20 73 71 6c 69  d will call sqli
4b60: 74 65 33 5f 66 72 65 65 28 29 20 74 6f 20 66 72  te3_free() to fr
4b70: 65 65 20 74 68 65 20 73 74 72 75 63 74 75 72 65  ee the structure
4b80: 20 61 66 74 65 72 20 74 68 65 20 73 70 65 63 69   after the speci
4b90: 66 69 65 64 0a 2a 2a 20 6f 70 65 72 61 74 69 6f  fied.** operatio
4ba0: 6e 20 68 61 73 20 62 65 65 6e 20 63 6f 6d 70 6c  n has been compl
4bb0: 65 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 63 65  eted..**.** Once
4bc0: 20 61 6e 20 41 73 79 6e 63 57 72 69 74 65 20 73   an AsyncWrite s
4bd0: 74 72 75 63 74 75 72 65 20 68 61 73 20 62 65 65  tructure has bee
4be0: 6e 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 6c  n added to the l
4bf0: 69 73 74 2c 20 69 74 20 62 65 63 6f 6d 65 73 20  ist, it becomes 
4c00: 74 68 65 0a 2a 2a 20 70 72 6f 70 65 72 74 79 20  the.** property 
4c10: 6f 66 20 74 68 65 20 77 72 69 74 65 72 20 74 68  of the writer th
4c20: 72 65 61 64 20 61 6e 64 20 6d 75 73 74 20 6e 6f  read and must no
4c30: 74 20 62 65 20 72 65 61 64 20 6f 72 20 6d 6f 64  t be read or mod
4c40: 69 66 69 65 64 20 62 79 20 74 68 65 0a 2a 2a 20  ified by the.** 
4c50: 63 61 6c 6c 65 72 2e 20 20 0a 2a 2f 0a 73 74 61  caller.  .*/.sta
4c60: 74 69 63 20 76 6f 69 64 20 61 64 64 41 73 79 6e  tic void addAsyn
4c70: 63 57 72 69 74 65 28 41 73 79 6e 63 57 72 69 74  cWrite(AsyncWrit
4c80: 65 20 2a 70 57 72 69 74 65 29 7b 0a 20 20 2f 2a  e *pWrite){.  /*
4c90: 20 57 65 20 6d 75 73 74 20 68 6f 6c 64 20 74 68   We must hold th
4ca0: 65 20 71 75 65 75 65 20 6d 75 74 65 78 20 69 6e  e queue mutex in
4cb0: 20 6f 72 64 65 72 20 74 6f 20 6d 6f 64 69 66 79   order to modify
4cc0: 20 74 68 65 20 71 75 65 75 65 20 70 6f 69 6e 74   the queue point
4cd0: 65 72 73 20 2a 2f 0a 20 20 69 66 28 20 70 57 72  ers */.  if( pWr
4ce0: 69 74 65 2d 3e 6f 70 21 3d 41 53 59 4e 43 5f 55  ite->op!=ASYNC_U
4cf0: 4e 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 61 73 79  NLOCK ){.    asy
4d00: 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 41  nc_mutex_enter(A
4d10: 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45  SYNC_MUTEX_QUEUE
4d20: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 64 64  );.  }..  /* Add
4d30: 20 74 68 65 20 72 65 63 6f 72 64 20 74 6f 20 74   the record to t
4d40: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 77 72  he end of the wr
4d50: 69 74 65 2d 6f 70 20 71 75 65 75 65 20 2a 2f 0a  ite-op queue */.
4d60: 20 20 61 73 73 65 72 74 28 20 21 70 57 72 69 74    assert( !pWrit
4d70: 65 2d 3e 70 4e 65 78 74 20 29 3b 0a 20 20 69 66  e->pNext );.  if
4d80: 28 20 61 73 79 6e 63 2e 70 51 75 65 75 65 4c 61  ( async.pQueueLa
4d90: 73 74 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  st ){.    assert
4da0: 28 20 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69  ( async.pQueueFi
4db0: 72 73 74 20 29 3b 0a 20 20 20 20 61 73 79 6e 63  rst );.    async
4dc0: 2e 70 51 75 65 75 65 4c 61 73 74 2d 3e 70 4e 65  .pQueueLast->pNe
4dd0: 78 74 20 3d 20 70 57 72 69 74 65 3b 0a 20 20 7d  xt = pWrite;.  }
4de0: 65 6c 73 65 7b 0a 20 20 20 20 61 73 79 6e 63 2e  else{.    async.
4df0: 70 51 75 65 75 65 46 69 72 73 74 20 3d 20 70 57  pQueueFirst = pW
4e00: 72 69 74 65 3b 0a 20 20 7d 0a 20 20 61 73 79 6e  rite;.  }.  asyn
4e10: 63 2e 70 51 75 65 75 65 4c 61 73 74 20 3d 20 70  c.pQueueLast = p
4e20: 57 72 69 74 65 3b 0a 20 20 41 53 59 4e 43 5f 54  Write;.  ASYNC_T
4e30: 52 41 43 45 28 28 22 50 55 53 48 20 25 70 20 28  RACE(("PUSH %p (
4e40: 25 73 20 25 73 20 25 64 29 5c 6e 22 2c 20 70 57  %s %s %d)\n", pW
4e50: 72 69 74 65 2c 20 61 7a 4f 70 63 6f 64 65 4e 61  rite, azOpcodeNa
4e60: 6d 65 5b 70 57 72 69 74 65 2d 3e 6f 70 5d 2c 0a  me[pWrite->op],.
4e70: 20 20 20 20 20 20 20 20 20 70 57 72 69 74 65 2d           pWrite-
4e80: 3e 70 46 69 6c 65 44 61 74 61 20 3f 20 70 57 72  >pFileData ? pWr
4e90: 69 74 65 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e  ite->pFileData->
4ea0: 7a 4e 61 6d 65 20 3a 20 22 2d 22 2c 20 70 57 72  zName : "-", pWr
4eb0: 69 74 65 2d 3e 69 4f 66 66 73 65 74 29 29 3b 0a  ite->iOffset));.
4ec0: 0a 20 20 69 66 28 20 70 57 72 69 74 65 2d 3e 6f  .  if( pWrite->o
4ed0: 70 3d 3d 41 53 59 4e 43 5f 43 4c 4f 53 45 20 29  p==ASYNC_CLOSE )
4ee0: 7b 0a 20 20 20 20 61 73 79 6e 63 2e 6e 46 69 6c  {.    async.nFil
4ef0: 65 2d 2d 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54  e--;.  }..  /* T
4f00: 68 65 20 77 72 69 74 65 72 20 74 68 72 65 61 64  he writer thread
4f10: 20 6d 69 67 68 74 20 68 61 76 65 20 62 65 65 6e   might have been
4f20: 20 69 64 6c 65 20 62 65 63 61 75 73 65 20 74 68   idle because th
4f30: 65 72 65 20 77 61 73 20 6e 6f 74 68 69 6e 67 0a  ere was nothing.
4f40: 20 20 2a 2a 20 6f 6e 20 74 68 65 20 77 72 69 74    ** on the writ
4f50: 65 2d 6f 70 20 71 75 65 75 65 20 66 6f 72 20 69  e-op queue for i
4f60: 74 20 74 6f 20 64 6f 2e 20 20 53 6f 20 77 61 6b  t to do.  So wak
4f70: 65 20 69 74 20 75 70 2e 20 2a 2f 0a 20 20 61 73  e it up. */.  as
4f80: 79 6e 63 5f 63 6f 6e 64 5f 73 69 67 6e 61 6c 28  ync_cond_signal(
4f90: 41 53 59 4e 43 5f 43 4f 4e 44 5f 51 55 45 55 45  ASYNC_COND_QUEUE
4fa0: 29 3b 0a 0a 20 20 2f 2a 20 44 72 6f 70 20 74 68  );..  /* Drop th
4fb0: 65 20 71 75 65 75 65 20 6d 75 74 65 78 20 2a 2f  e queue mutex */
4fc0: 0a 20 20 69 66 28 20 70 57 72 69 74 65 2d 3e 6f  .  if( pWrite->o
4fd0: 70 21 3d 41 53 59 4e 43 5f 55 4e 4c 4f 43 4b 20  p!=ASYNC_UNLOCK 
4fe0: 29 7b 0a 20 20 20 20 61 73 79 6e 63 5f 6d 75 74  ){.    async_mut
4ff0: 65 78 5f 6c 65 61 76 65 28 41 53 59 4e 43 5f 4d  ex_leave(ASYNC_M
5000: 55 54 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 7d  UTEX_QUEUE);.  }
5010: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 63 72 65 6d  .}../*.** Increm
5020: 65 6e 74 20 61 73 79 6e 63 2e 6e 46 69 6c 65 20  ent async.nFile 
5030: 69 6e 20 61 20 74 68 72 65 61 64 2d 73 61 66 65  in a thread-safe
5040: 20 6d 61 6e 6e 65 72 2e 0a 2a 2f 0a 73 74 61 74   manner..*/.stat
5050: 69 63 20 76 6f 69 64 20 69 6e 63 72 4f 70 65 6e  ic void incrOpen
5060: 46 69 6c 65 43 6f 75 6e 74 28 76 6f 69 64 29 7b  FileCount(void){
5070: 0a 20 20 2f 2a 20 57 65 20 6d 75 73 74 20 68 6f  .  /* We must ho
5080: 6c 64 20 74 68 65 20 71 75 65 75 65 20 6d 75 74  ld the queue mut
5090: 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 6d  ex in order to m
50a0: 6f 64 69 66 79 20 61 73 79 6e 63 2e 6e 46 69 6c  odify async.nFil
50b0: 65 20 2a 2f 0a 20 20 61 73 79 6e 63 5f 6d 75 74  e */.  async_mut
50c0: 65 78 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d  ex_enter(ASYNC_M
50d0: 55 54 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 69  UTEX_QUEUE);.  i
50e0: 66 28 20 61 73 79 6e 63 2e 6e 46 69 6c 65 3d 3d  f( async.nFile==
50f0: 30 20 29 7b 0a 20 20 20 20 61 73 79 6e 63 2e 69  0 ){.    async.i
5100: 6f 45 72 72 6f 72 20 3d 20 53 51 4c 49 54 45 5f  oError = SQLITE_
5110: 4f 4b 3b 0a 20 20 7d 0a 20 20 61 73 79 6e 63 2e  OK;.  }.  async.
5120: 6e 46 69 6c 65 2b 2b 3b 0a 20 20 61 73 79 6e 63  nFile++;.  async
5130: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59  _mutex_leave(ASY
5140: 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b  NC_MUTEX_QUEUE);
5150: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  .}../*.** This i
5160: 73 20 61 20 75 74 69 6c 69 74 79 20 66 75 6e 63  s a utility func
5170: 74 69 6f 6e 20 74 6f 20 61 6c 6c 6f 63 61 74 65  tion to allocate
5180: 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 61 20   and populate a 
5190: 6e 65 77 20 41 73 79 6e 63 57 72 69 74 65 0a 2a  new AsyncWrite.*
51a0: 2a 20 73 74 72 75 63 74 75 72 65 20 61 6e 64 20  * structure and 
51b0: 69 6e 73 65 72 74 20 69 74 20 28 76 69 61 20 61  insert it (via a
51c0: 64 64 41 73 79 6e 63 57 72 69 74 65 28 29 20 29  ddAsyncWrite() )
51d0: 20 69 6e 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c   into the global
51e0: 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63   list..*/.static
51f0: 20 69 6e 74 20 61 64 64 4e 65 77 41 73 79 6e 63   int addNewAsync
5200: 57 72 69 74 65 28 0a 20 20 41 73 79 6e 63 46 69  Write(.  AsyncFi
5210: 6c 65 44 61 74 61 20 2a 70 46 69 6c 65 44 61 74  leData *pFileDat
5220: 61 2c 20 0a 20 20 69 6e 74 20 6f 70 2c 20 0a 20  a, .  int op, . 
5230: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
5240: 4f 66 66 73 65 74 2c 20 0a 20 20 69 6e 74 20 6e  Offset, .  int n
5250: 42 79 74 65 2c 0a 20 20 63 6f 6e 73 74 20 63 68  Byte,.  const ch
5260: 61 72 20 2a 7a 42 79 74 65 0a 29 7b 0a 20 20 41  ar *zByte.){.  A
5270: 73 79 6e 63 57 72 69 74 65 20 2a 70 3b 0a 20 20  syncWrite *p;.  
5280: 69 66 28 20 6f 70 21 3d 41 53 59 4e 43 5f 43 4c  if( op!=ASYNC_CL
5290: 4f 53 45 20 26 26 20 61 73 79 6e 63 2e 69 6f 45  OSE && async.ioE
52a0: 72 72 6f 72 20 29 7b 0a 20 20 20 20 72 65 74 75  rror ){.    retu
52b0: 72 6e 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72  rn async.ioError
52c0: 3b 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c 69  ;.  }.  p = sqli
52d0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
52e0: 66 28 41 73 79 6e 63 57 72 69 74 65 29 20 2b 20  f(AsyncWrite) + 
52f0: 28 7a 42 79 74 65 3f 6e 42 79 74 65 3a 30 29 29  (zByte?nByte:0))
5300: 3b 0a 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20  ;.  if( !p ){.  
5310: 20 20 2f 2a 20 54 68 65 20 75 70 70 65 72 20 6c    /* The upper l
5320: 61 79 65 72 20 64 6f 65 73 20 6e 6f 74 20 65 78  ayer does not ex
5330: 70 65 63 74 20 6f 70 65 72 61 74 69 6f 6e 73 20  pect operations 
5340: 6c 69 6b 65 20 4f 73 57 72 69 74 65 28 29 20 74  like OsWrite() t
5350: 6f 0a 20 20 20 20 2a 2a 20 72 65 74 75 72 6e 20  o.    ** return 
5360: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 2e 20 54 68  SQLITE_NOMEM. Th
5370: 69 73 20 69 73 20 70 61 72 74 6c 79 20 62 65 63  is is partly bec
5380: 61 75 73 65 20 75 6e 64 65 72 20 6e 6f 72 6d 61  ause under norma
5390: 6c 20 63 6f 6e 64 69 74 69 6f 6e 73 0a 20 20 20  l conditions.   
53a0: 20 2a 2a 20 53 51 4c 69 74 65 20 69 73 20 72 65   ** SQLite is re
53b0: 71 75 69 72 65 64 20 74 6f 20 64 6f 20 72 6f 6c  quired to do rol
53c0: 6c 62 61 63 6b 20 77 69 74 68 6f 75 74 20 63 61  lback without ca
53d0: 6c 6c 69 6e 67 20 6d 61 6c 6c 6f 63 28 29 2e 20  lling malloc(). 
53e0: 53 6f 0a 20 20 20 20 2a 2a 20 69 66 20 6d 61 6c  So.    ** if mal
53f0: 6c 6f 63 28 29 20 66 61 69 6c 73 20 68 65 72 65  loc() fails here
5400: 2c 20 74 72 65 61 74 20 69 74 20 61 73 20 61 6e  , treat it as an
5410: 20 49 2f 4f 20 65 72 72 6f 72 2e 20 54 68 65 20   I/O error. The 
5420: 61 62 6f 76 65 0a 20 20 20 20 2a 2a 20 6c 61 79  above.    ** lay
5430: 65 72 20 6b 6e 6f 77 73 20 68 6f 77 20 74 6f 20  er knows how to 
5440: 68 61 6e 64 6c 65 20 74 68 61 74 2e 0a 20 20 20  handle that..   
5450: 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 53   */.    return S
5460: 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d  QLITE_IOERR;.  }
5470: 0a 20 20 70 2d 3e 6f 70 20 3d 20 6f 70 3b 0a 20  .  p->op = op;. 
5480: 20 70 2d 3e 69 4f 66 66 73 65 74 20 3d 20 69 4f   p->iOffset = iO
5490: 66 66 73 65 74 3b 0a 20 20 70 2d 3e 6e 42 79 74  ffset;.  p->nByt
54a0: 65 20 3d 20 6e 42 79 74 65 3b 0a 20 20 70 2d 3e  e = nByte;.  p->
54b0: 70 46 69 6c 65 44 61 74 61 20 3d 20 70 46 69 6c  pFileData = pFil
54c0: 65 44 61 74 61 3b 0a 20 20 70 2d 3e 70 4e 65 78  eData;.  p->pNex
54d0: 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 7a 42 79  t = 0;.  if( zBy
54e0: 74 65 20 29 7b 0a 20 20 20 20 70 2d 3e 7a 42 75  te ){.    p->zBu
54f0: 66 20 3d 20 28 63 68 61 72 20 2a 29 26 70 5b 31  f = (char *)&p[1
5500: 5d 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 2d  ];.    memcpy(p-
5510: 3e 7a 42 75 66 2c 20 7a 42 79 74 65 2c 20 6e 42  >zBuf, zByte, nB
5520: 79 74 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  yte);.  }else{. 
5530: 20 20 20 70 2d 3e 7a 42 75 66 20 3d 20 30 3b 0a     p->zBuf = 0;.
5540: 20 20 7d 0a 20 20 61 64 64 41 73 79 6e 63 57 72    }.  addAsyncWr
5550: 69 74 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e  ite(p);.  return
5560: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
5570: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74 68 65 20 66  *.** Close the f
5580: 69 6c 65 2e 20 54 68 69 73 20 6a 75 73 74 20 61  ile. This just a
5590: 64 64 73 20 61 6e 20 65 6e 74 72 79 20 74 6f 20  dds an entry to 
55a0: 74 68 65 20 77 72 69 74 65 2d 6f 70 20 6c 69 73  the write-op lis
55b0: 74 2c 20 74 68 65 20 66 69 6c 65 20 69 73 0a 2a  t, the file is.*
55c0: 2a 20 6e 6f 74 20 61 63 74 75 61 6c 6c 79 20 63  * not actually c
55d0: 6c 6f 73 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  losed..*/.static
55e0: 20 69 6e 74 20 61 73 79 6e 63 43 6c 6f 73 65 28   int asyncClose(
55f0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
5600: 69 6c 65 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c  ile){.  AsyncFil
5610: 65 44 61 74 61 20 2a 70 20 3d 20 28 28 41 73 79  eData *p = ((Asy
5620: 6e 63 46 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d  ncFile *)pFile)-
5630: 3e 70 44 61 74 61 3b 0a 0a 20 20 2f 2a 20 55 6e  >pData;..  /* Un
5640: 6c 6f 63 6b 20 74 68 65 20 66 69 6c 65 2c 20 69  lock the file, i
5650: 66 20 69 74 20 69 73 20 6c 6f 63 6b 65 64 20 2a  f it is locked *
5660: 2f 0a 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f  /.  async_mutex_
5670: 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54 45  enter(ASYNC_MUTE
5680: 58 5f 4c 4f 43 4b 29 3b 0a 20 20 70 2d 3e 6c 6f  X_LOCK);.  p->lo
5690: 63 6b 2e 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20  ck.eLock = 0;.  
56a0: 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76  async_mutex_leav
56b0: 65 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f  e(ASYNC_MUTEX_LO
56c0: 43 4b 29 3b 0a 0a 20 20 61 64 64 41 73 79 6e 63  CK);..  addAsync
56d0: 57 72 69 74 65 28 26 70 2d 3e 63 6c 6f 73 65 4f  Write(&p->closeO
56e0: 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  p);.  return SQL
56f0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
5700: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
5710: 6f 66 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74  of sqlite3OsWrit
5720: 65 28 29 20 66 6f 72 20 61 73 79 6e 63 68 72 6f  e() for asynchro
5730: 6e 6f 75 73 20 66 69 6c 65 73 2e 20 49 6e 73 74  nous files. Inst
5740: 65 61 64 20 6f 66 20 0a 2a 2a 20 77 72 69 74 69  ead of .** writi
5750: 6e 67 20 74 6f 20 74 68 65 20 75 6e 64 65 72 6c  ng to the underl
5760: 79 69 6e 67 20 66 69 6c 65 2c 20 74 68 69 73 20  ying file, this 
5770: 66 75 6e 63 74 69 6f 6e 20 61 64 64 73 20 61 6e  function adds an
5780: 20 65 6e 74 72 79 20 74 6f 20 74 68 65 20 65 6e   entry to the en
5790: 64 20 6f 66 0a 2a 2a 20 74 68 65 20 67 6c 6f 62  d of.** the glob
57a0: 61 6c 20 41 73 79 6e 63 57 72 69 74 65 20 6c 69  al AsyncWrite li
57b0: 73 74 2e 20 45 69 74 68 65 72 20 53 51 4c 49 54  st. Either SQLIT
57c0: 45 5f 4f 4b 20 6f 72 20 53 51 4c 49 54 45 5f 4e  E_OK or SQLITE_N
57d0: 4f 4d 45 4d 20 6d 61 79 20 62 65 0a 2a 2a 20 72  OMEM may be.** r
57e0: 65 74 75 72 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74  eturned..*/.stat
57f0: 69 63 20 69 6e 74 20 61 73 79 6e 63 57 72 69 74  ic int asyncWrit
5800: 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  e(.  sqlite3_fil
5810: 65 20 2a 70 46 69 6c 65 2c 20 0a 20 20 63 6f 6e  e *pFile, .  con
5820: 73 74 20 76 6f 69 64 20 2a 70 42 75 66 2c 20 0a  st void *pBuf, .
5830: 20 20 69 6e 74 20 61 6d 74 2c 20 0a 20 20 73 71    int amt, .  sq
5840: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 66  lite3_int64 iOff
5850: 0a 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 44  .){.  AsyncFileD
5860: 61 74 61 20 2a 70 20 3d 20 28 28 41 73 79 6e 63  ata *p = ((Async
5870: 46 69 6c 65 20 2a 29 70 46 69 6c 65 29 2d 3e 70  File *)pFile)->p
5880: 44 61 74 61 3b 0a 20 20 72 65 74 75 72 6e 20 61  Data;.  return a
5890: 64 64 4e 65 77 41 73 79 6e 63 57 72 69 74 65 28  ddNewAsyncWrite(
58a0: 70 2c 20 41 53 59 4e 43 5f 57 52 49 54 45 2c 20  p, ASYNC_WRITE, 
58b0: 69 4f 66 66 2c 20 61 6d 74 2c 20 70 42 75 66 29  iOff, amt, pBuf)
58c0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20  ;.}../*.** Read 
58d0: 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 66 69  data from the fi
58e0: 6c 65 2e 20 46 69 72 73 74 20 77 65 20 72 65 61  le. First we rea
58f0: 64 20 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 73  d from the files
5900: 79 73 74 65 6d 2c 20 74 68 65 6e 20 61 64 6a 75  ystem, then adju
5910: 73 74 20 0a 2a 2a 20 74 68 65 20 63 6f 6e 74 65  st .** the conte
5920: 6e 74 73 20 6f 66 20 74 68 65 20 62 75 66 66 65  nts of the buffe
5930: 72 20 62 61 73 65 64 20 6f 6e 20 41 53 59 4e 43  r based on ASYNC
5940: 5f 57 52 49 54 45 20 6f 70 65 72 61 74 69 6f 6e  _WRITE operation
5950: 73 20 69 6e 20 74 68 65 20 0a 2a 2a 20 77 72 69  s in the .** wri
5960: 74 65 2d 6f 70 20 71 75 65 75 65 2e 0a 2a 2a 0a  te-op queue..**.
5970: 2a 2a 20 54 68 69 73 20 6d 65 74 68 6f 64 20 68  ** This method h
5980: 6f 6c 64 73 20 74 68 65 20 6d 75 74 65 78 20 66  olds the mutex f
5990: 72 6f 6d 20 73 74 61 72 74 20 74 6f 20 66 69 6e  rom start to fin
59a0: 69 73 68 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ish..*/.static i
59b0: 6e 74 20 61 73 79 6e 63 52 65 61 64 28 0a 20 20  nt asyncRead(.  
59c0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
59d0: 69 6c 65 2c 20 0a 20 20 76 6f 69 64 20 2a 7a 4f  ile, .  void *zO
59e0: 75 74 2c 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c  ut, .  int iAmt,
59f0: 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36   .  sqlite3_int6
5a00: 34 20 69 4f 66 66 73 65 74 0a 29 7b 0a 20 20 41  4 iOffset.){.  A
5a10: 73 79 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 20  syncFileData *p 
5a20: 3d 20 28 28 41 73 79 6e 63 46 69 6c 65 20 2a 29  = ((AsyncFile *)
5a30: 70 46 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a 20  pFile)->pData;. 
5a40: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
5a50: 5f 4f 4b 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69  _OK;.  sqlite3_i
5a60: 6e 74 36 34 20 66 69 6c 65 73 69 7a 65 20 3d 20  nt64 filesize = 
5a70: 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  0;.  sqlite3_fil
5a80: 65 20 2a 70 42 61 73 65 20 3d 20 70 2d 3e 70 42  e *pBase = p->pB
5a90: 61 73 65 52 65 61 64 3b 0a 20 20 73 71 6c 69 74  aseRead;.  sqlit
5aa0: 65 33 5f 69 6e 74 36 34 20 69 41 6d 74 36 34 20  e3_int64 iAmt64 
5ab0: 3d 20 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  = (sqlite3_int64
5ac0: 29 69 41 6d 74 3b 0a 0a 20 20 2f 2a 20 47 72 61  )iAmt;..  /* Gra
5ad0: 62 20 74 68 65 20 77 72 69 74 65 20 71 75 65 75  b the write queu
5ae0: 65 20 6d 75 74 65 78 20 66 6f 72 20 74 68 65 20  e mutex for the 
5af0: 64 75 72 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  duration of the 
5b00: 63 61 6c 6c 20 2a 2f 0a 20 20 61 73 79 6e 63 5f  call */.  async_
5b10: 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e  mutex_enter(ASYN
5b20: 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b 0a  C_MUTEX_QUEUE);.
5b30: 0a 20 20 2f 2a 20 49 66 20 61 6e 20 49 2f 4f 20  .  /* If an I/O 
5b40: 65 72 72 6f 72 20 68 61 73 20 70 72 65 76 69 6f  error has previo
5b50: 75 73 6c 79 20 6f 63 63 75 72 72 65 64 20 69 6e  usly occurred in
5b60: 20 74 68 69 73 20 76 69 72 74 75 61 6c 20 66 69   this virtual fi
5b70: 6c 65 20 0a 20 20 2a 2a 20 73 79 73 74 65 6d 2c  le .  ** system,
5b80: 20 74 68 65 6e 20 61 6c 6c 20 73 75 62 73 65 71   then all subseq
5b90: 75 65 6e 74 20 6f 70 65 72 61 74 69 6f 6e 73 20  uent operations 
5ba0: 66 61 69 6c 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  fail..  */.  if(
5bb0: 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 21 3d   async.ioError!=
5bc0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
5bd0: 20 72 63 20 3d 20 61 73 79 6e 63 2e 69 6f 45 72   rc = async.ioEr
5be0: 72 6f 72 3b 0a 20 20 20 20 67 6f 74 6f 20 61 73  ror;.    goto as
5bf0: 79 6e 63 72 65 61 64 5f 6f 75 74 3b 0a 20 20 7d  yncread_out;.  }
5c00: 0a 0a 20 20 69 66 28 20 70 42 61 73 65 2d 3e 70  ..  if( pBase->p
5c10: 4d 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 73  Methods ){.    s
5c20: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 52 65  qlite3_int64 nRe
5c30: 61 64 3b 0a 20 20 20 20 72 63 20 3d 20 70 42 61  ad;.    rc = pBa
5c40: 73 65 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46  se->pMethods->xF
5c50: 69 6c 65 53 69 7a 65 28 70 42 61 73 65 2c 20 26  ileSize(pBase, &
5c60: 66 69 6c 65 73 69 7a 65 29 3b 0a 20 20 20 20 69  filesize);.    i
5c70: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
5c80: 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 61   ){.      goto a
5c90: 73 79 6e 63 72 65 61 64 5f 6f 75 74 3b 0a 20 20  syncread_out;.  
5ca0: 20 20 7d 0a 20 20 20 20 6e 52 65 61 64 20 3d 20    }.    nRead = 
5cb0: 4d 49 4e 28 66 69 6c 65 73 69 7a 65 20 2d 20 69  MIN(filesize - i
5cc0: 4f 66 66 73 65 74 2c 20 69 41 6d 74 36 34 29 3b  Offset, iAmt64);
5cd0: 0a 20 20 20 20 69 66 28 20 6e 52 65 61 64 3e 30  .    if( nRead>0
5ce0: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70   ){.      rc = p
5cf0: 42 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  Base->pMethods->
5d00: 78 52 65 61 64 28 70 42 61 73 65 2c 20 7a 4f 75  xRead(pBase, zOu
5d10: 74 2c 20 28 69 6e 74 29 6e 52 65 61 64 2c 20 69  t, (int)nRead, i
5d20: 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 41  Offset);.      A
5d30: 53 59 4e 43 5f 54 52 41 43 45 28 28 22 52 45 41  SYNC_TRACE(("REA
5d40: 44 20 25 73 20 25 64 20 62 79 74 65 73 20 61 74  D %s %d bytes at
5d50: 20 25 64 5c 6e 22 2c 20 70 2d 3e 7a 4e 61 6d 65   %d\n", p->zName
5d60: 2c 20 6e 52 65 61 64 2c 20 69 4f 66 66 73 65 74  , nRead, iOffset
5d70: 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ));.    }.  }.. 
5d80: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
5d90: 4f 4b 20 29 7b 0a 20 20 20 20 41 73 79 6e 63 57  OK ){.    AsyncW
5da0: 72 69 74 65 20 2a 70 57 72 69 74 65 3b 0a 20 20  rite *pWrite;.  
5db0: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20    char *zName = 
5dc0: 70 2d 3e 7a 4e 61 6d 65 3b 0a 0a 20 20 20 20 66  p->zName;..    f
5dd0: 6f 72 28 70 57 72 69 74 65 3d 61 73 79 6e 63 2e  or(pWrite=async.
5de0: 70 51 75 65 75 65 46 69 72 73 74 3b 20 70 57 72  pQueueFirst; pWr
5df0: 69 74 65 3b 20 70 57 72 69 74 65 20 3d 20 70 57  ite; pWrite = pW
5e00: 72 69 74 65 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  rite->pNext){.  
5e10: 20 20 20 20 69 66 28 20 70 57 72 69 74 65 2d 3e      if( pWrite->
5e20: 6f 70 3d 3d 41 53 59 4e 43 5f 57 52 49 54 45 20  op==ASYNC_WRITE 
5e30: 26 26 20 28 0a 20 20 20 20 20 20 20 20 28 70 57  && (.        (pW
5e40: 72 69 74 65 2d 3e 70 46 69 6c 65 44 61 74 61 3d  rite->pFileData=
5e50: 3d 70 29 20 7c 7c 0a 20 20 20 20 20 20 20 20 28  =p) ||.        (
5e60: 7a 4e 61 6d 65 20 26 26 20 70 57 72 69 74 65 2d  zName && pWrite-
5e70: 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d  >pFileData->zNam
5e80: 65 3d 3d 7a 4e 61 6d 65 29 0a 20 20 20 20 20 20  e==zName).      
5e90: 29 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  )){.        sqli
5ea0: 74 65 33 5f 69 6e 74 36 34 20 6e 43 6f 70 79 3b  te3_int64 nCopy;
5eb0: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
5ec0: 5f 69 6e 74 36 34 20 6e 42 79 74 65 36 34 20 3d  _int64 nByte64 =
5ed0: 20 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29   (sqlite3_int64)
5ee0: 70 57 72 69 74 65 2d 3e 6e 42 79 74 65 3b 0a 0a  pWrite->nByte;..
5ef0: 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20 76          /* Set v
5f00: 61 72 69 61 62 6c 65 20 69 42 65 67 69 6e 49 6e  ariable iBeginIn
5f10: 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74 20 69   to the offset i
5f20: 6e 20 62 75 66 66 65 72 20 70 57 72 69 74 65 2d  n buffer pWrite-
5f30: 3e 7a 42 75 66 5b 5d 20 66 72 6f 6d 0a 20 20 20  >zBuf[] from.   
5f40: 20 20 20 20 20 2a 2a 20 77 68 69 63 68 20 64 61       ** which da
5f50: 74 61 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 70  ta should be cop
5f60: 69 65 64 2e 20 53 65 74 20 69 42 65 67 69 6e 4f  ied. Set iBeginO
5f70: 75 74 20 74 6f 20 74 68 65 20 6f 66 66 73 65 74  ut to the offset
5f80: 20 77 69 74 68 69 6e 0a 20 20 20 20 20 20 20 20   within.        
5f90: 2a 2a 20 74 68 65 20 6f 75 74 70 75 74 20 62 75  ** the output bu
5fa0: 66 66 65 72 20 74 6f 20 77 68 69 63 68 20 64 61  ffer to which da
5fb0: 74 61 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 70  ta should be cop
5fc0: 69 65 64 2e 20 49 66 20 65 69 74 68 65 72 20 6f  ied. If either o
5fd0: 66 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 68 65  f.        ** the
5fe0: 73 65 20 6f 66 66 73 65 74 73 20 69 73 20 61 20  se offsets is a 
5ff0: 6e 65 67 61 74 69 76 65 20 6e 75 6d 62 65 72 2c  negative number,
6000: 20 73 65 74 20 74 68 65 6d 20 74 6f 20 30 2e 0a   set them to 0..
6010: 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20          */.     
6020: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
6030: 20 69 42 65 67 69 6e 4f 75 74 20 3d 20 28 70 57   iBeginOut = (pW
6040: 72 69 74 65 2d 3e 69 4f 66 66 73 65 74 2d 69 4f  rite->iOffset-iO
6050: 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 20 20  ffset);.        
6060: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 42  sqlite3_int64 iB
6070: 65 67 69 6e 49 6e 20 3d 20 2d 69 42 65 67 69 6e  eginIn = -iBegin
6080: 4f 75 74 3b 0a 20 20 20 20 20 20 20 20 69 66 28  Out;.        if(
6090: 20 69 42 65 67 69 6e 49 6e 3c 30 20 29 20 69 42   iBeginIn<0 ) iB
60a0: 65 67 69 6e 49 6e 20 3d 20 30 3b 0a 20 20 20 20  eginIn = 0;.    
60b0: 20 20 20 20 69 66 28 20 69 42 65 67 69 6e 4f 75      if( iBeginOu
60c0: 74 3c 30 20 29 20 69 42 65 67 69 6e 4f 75 74 20  t<0 ) iBeginOut 
60d0: 3d 20 30 3b 0a 0a 20 20 20 20 20 20 20 20 66 69  = 0;..        fi
60e0: 6c 65 73 69 7a 65 20 3d 20 4d 41 58 28 66 69 6c  lesize = MAX(fil
60f0: 65 73 69 7a 65 2c 20 70 57 72 69 74 65 2d 3e 69  esize, pWrite->i
6100: 4f 66 66 73 65 74 2b 6e 42 79 74 65 36 34 29 3b  Offset+nByte64);
6110: 0a 0a 20 20 20 20 20 20 20 20 6e 43 6f 70 79 20  ..        nCopy 
6120: 3d 20 4d 49 4e 28 6e 42 79 74 65 36 34 2d 69 42  = MIN(nByte64-iB
6130: 65 67 69 6e 49 6e 2c 20 69 41 6d 74 36 34 2d 69  eginIn, iAmt64-i
6140: 42 65 67 69 6e 4f 75 74 29 3b 0a 20 20 20 20 20  BeginOut);.     
6150: 20 20 20 69 66 28 20 6e 43 6f 70 79 3e 30 20 29     if( nCopy>0 )
6160: 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63  {.          memc
6170: 70 79 28 26 28 28 63 68 61 72 20 2a 29 7a 4f 75  py(&((char *)zOu
6180: 74 29 5b 69 42 65 67 69 6e 4f 75 74 5d 2c 20 26  t)[iBeginOut], &
6190: 70 57 72 69 74 65 2d 3e 7a 42 75 66 5b 69 42 65  pWrite->zBuf[iBe
61a0: 67 69 6e 49 6e 5d 2c 20 28 73 69 7a 65 5f 74 29  ginIn], (size_t)
61b0: 6e 43 6f 70 79 29 3b 0a 20 20 20 20 20 20 20 20  nCopy);.        
61c0: 20 20 41 53 59 4e 43 5f 54 52 41 43 45 28 28 22    ASYNC_TRACE(("
61d0: 4f 56 45 52 52 45 41 44 20 25 64 20 62 79 74 65  OVERREAD %d byte
61e0: 73 20 61 74 20 25 64 5c 6e 22 2c 20 6e 43 6f 70  s at %d\n", nCop
61f0: 79 2c 20 69 42 65 67 69 6e 4f 75 74 2b 69 4f 66  y, iBeginOut+iOf
6200: 66 73 65 74 29 29 3b 0a 20 20 20 20 20 20 20 20  fset));.        
6210: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  }.      }.    }.
6220: 20 20 7d 0a 0a 61 73 79 6e 63 72 65 61 64 5f 6f    }..asyncread_o
6230: 75 74 3a 0a 20 20 61 73 79 6e 63 5f 6d 75 74 65  ut:.  async_mute
6240: 78 5f 6c 65 61 76 65 28 41 53 59 4e 43 5f 4d 55  x_leave(ASYNC_MU
6250: 54 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 69 66  TEX_QUEUE);.  if
6260: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6270: 26 26 20 66 69 6c 65 73 69 7a 65 3c 28 69 4f 66  && filesize<(iOf
6280: 66 73 65 74 2b 69 41 6d 74 29 20 29 7b 0a 20 20  fset+iAmt) ){.  
6290: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f    rc = SQLITE_IO
62a0: 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 3b 0a  ERR_SHORT_READ;.
62b0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
62c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63 61  .}../*.** Trunca
62d0: 74 65 20 74 68 65 20 66 69 6c 65 20 74 6f 20 6e  te the file to n
62e0: 42 79 74 65 20 62 79 74 65 73 20 69 6e 20 6c 65  Byte bytes in le
62f0: 6e 67 74 68 2e 20 54 68 69 73 20 6a 75 73 74 20  ngth. This just 
6300: 61 64 64 73 20 61 6e 20 65 6e 74 72 79 20 74 6f  adds an entry to
6310: 20 0a 2a 2a 20 74 68 65 20 77 72 69 74 65 2d 6f   .** the write-o
6320: 70 20 6c 69 73 74 2c 20 6e 6f 20 49 4f 20 61 63  p list, no IO ac
6330: 74 75 61 6c 6c 79 20 74 61 6b 65 73 20 70 6c 61  tually takes pla
6340: 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ce..*/.static in
6350: 74 20 61 73 79 6e 63 54 72 75 6e 63 61 74 65 28  t asyncTruncate(
6360: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
6370: 69 6c 65 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  ile, sqlite3_int
6380: 36 34 20 6e 42 79 74 65 29 7b 0a 20 20 41 73 79  64 nByte){.  Asy
6390: 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 20 3d 20  ncFileData *p = 
63a0: 28 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 70 46  ((AsyncFile *)pF
63b0: 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a 20 20 72  ile)->pData;.  r
63c0: 65 74 75 72 6e 20 61 64 64 4e 65 77 41 73 79 6e  eturn addNewAsyn
63d0: 63 57 72 69 74 65 28 70 2c 20 41 53 59 4e 43 5f  cWrite(p, ASYNC_
63e0: 54 52 55 4e 43 41 54 45 2c 20 6e 42 79 74 65 2c  TRUNCATE, nByte,
63f0: 20 30 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   0, 0);.}../*.**
6400: 20 53 79 6e 63 20 74 68 65 20 66 69 6c 65 2e 20   Sync the file. 
6410: 54 68 69 73 20 6a 75 73 74 20 61 64 64 73 20 61  This just adds a
6420: 6e 20 65 6e 74 72 79 20 74 6f 20 74 68 65 20 77  n entry to the w
6430: 72 69 74 65 2d 6f 70 20 6c 69 73 74 2c 20 74 68  rite-op list, th
6440: 65 20 0a 2a 2a 20 73 79 6e 63 28 29 20 69 73 20  e .** sync() is 
6450: 64 6f 6e 65 20 6c 61 74 65 72 20 62 79 20 73 71  done later by sq
6460: 6c 69 74 65 33 5f 61 73 79 6e 63 5f 66 6c 75 73  lite3_async_flus
6470: 68 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  h()..*/.static i
6480: 6e 74 20 61 73 79 6e 63 53 79 6e 63 28 73 71 6c  nt asyncSync(sql
6490: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
64a0: 2c 20 69 6e 74 20 66 6c 61 67 73 29 7b 0a 20 20  , int flags){.  
64b0: 41 73 79 6e 63 46 69 6c 65 44 61 74 61 20 2a 70  AsyncFileData *p
64c0: 20 3d 20 28 28 41 73 79 6e 63 46 69 6c 65 20 2a   = ((AsyncFile *
64d0: 29 70 46 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a  )pFile)->pData;.
64e0: 20 20 72 65 74 75 72 6e 20 61 64 64 4e 65 77 41    return addNewA
64f0: 73 79 6e 63 57 72 69 74 65 28 70 2c 20 41 53 59  syncWrite(p, ASY
6500: 4e 43 5f 53 59 4e 43 2c 20 30 2c 20 66 6c 61 67  NC_SYNC, 0, flag
6510: 73 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  s, 0);.}../*.** 
6520: 52 65 61 64 20 74 68 65 20 73 69 7a 65 20 6f 66  Read the size of
6530: 20 74 68 65 20 66 69 6c 65 2e 20 46 69 72 73 74   the file. First
6540: 20 77 65 20 72 65 61 64 20 74 68 65 20 73 69 7a   we read the siz
6550: 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 73 79  e of the file sy
6560: 73 74 65 6d 20 0a 2a 2a 20 65 6e 74 72 79 2c 20  stem .** entry, 
6570: 74 68 65 6e 20 61 64 6a 75 73 74 20 66 6f 72 20  then adjust for 
6580: 61 6e 79 20 41 53 59 4e 43 5f 57 52 49 54 45 20  any ASYNC_WRITE 
6590: 6f 72 20 41 53 59 4e 43 5f 54 52 55 4e 43 41 54  or ASYNC_TRUNCAT
65a0: 45 20 6f 70 65 72 61 74 69 6f 6e 73 20 0a 2a 2a  E operations .**
65b0: 20 63 75 72 72 65 6e 74 6c 79 20 69 6e 20 74 68   currently in th
65c0: 65 20 77 72 69 74 65 2d 6f 70 20 6c 69 73 74 2e  e write-op list.
65d0: 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d 65 74   .**.** This met
65e0: 68 6f 64 20 68 6f 6c 64 73 20 74 68 65 20 6d 75  hod holds the mu
65f0: 74 65 78 20 66 72 6f 6d 20 73 74 61 72 74 20 74  tex from start t
6600: 6f 20 66 69 6e 69 73 68 2e 0a 2a 2f 0a 69 6e 74  o finish..*/.int
6610: 20 61 73 79 6e 63 46 69 6c 65 53 69 7a 65 28 73   asyncFileSize(s
6620: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
6630: 6c 65 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  le, sqlite3_int6
6640: 34 20 2a 70 69 53 69 7a 65 29 7b 0a 20 20 41 73  4 *piSize){.  As
6650: 79 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 20 3d  yncFileData *p =
6660: 20 28 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 70   ((AsyncFile *)p
6670: 46 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a 20 20  File)->pData;.  
6680: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6690: 4f 4b 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e  OK;.  sqlite3_in
66a0: 74 36 34 20 73 20 3d 20 30 3b 0a 20 20 73 71 6c  t64 s = 0;.  sql
66b0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 42 61 73 65  ite3_file *pBase
66c0: 3b 0a 0a 20 20 61 73 79 6e 63 5f 6d 75 74 65 78  ;..  async_mutex
66d0: 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54  _enter(ASYNC_MUT
66e0: 45 58 5f 51 55 45 55 45 29 3b 0a 0a 20 20 2f 2a  EX_QUEUE);..  /*
66f0: 20 52 65 61 64 20 74 68 65 20 66 69 6c 65 73 79   Read the filesy
6700: 73 74 65 6d 20 73 69 7a 65 20 66 72 6f 6d 20 74  stem size from t
6710: 68 65 20 62 61 73 65 20 66 69 6c 65 2e 20 49 66  he base file. If
6720: 20 70 4d 65 74 68 6f 64 73 20 69 73 20 4e 55 4c   pMethods is NUL
6730: 4c 2c 20 74 68 69 73 0a 20 20 2a 2a 20 6d 65 61  L, this.  ** mea
6740: 6e 73 20 74 68 65 20 66 69 6c 65 20 68 61 73 6e  ns the file hasn
6750: 27 74 20 62 65 65 6e 20 6f 70 65 6e 65 64 20 79  't been opened y
6760: 65 74 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65  et. In this case
6770: 20 61 6c 6c 20 72 65 6c 65 76 61 6e 74 20 64 61   all relevant da
6780: 74 61 20 0a 20 20 2a 2a 20 6d 75 73 74 20 62 65  ta .  ** must be
6790: 20 69 6e 20 74 68 65 20 77 72 69 74 65 2d 6f 70   in the write-op
67a0: 20 71 75 65 75 65 20 61 6e 79 77 61 79 2c 20 73   queue anyway, s
67b0: 6f 20 77 65 20 63 61 6e 20 6f 6d 69 74 20 72 65  o we can omit re
67c0: 61 64 69 6e 67 20 66 72 6f 6d 20 74 68 65 0a 20  ading from the. 
67d0: 20 2a 2a 20 66 69 6c 65 2d 73 79 73 74 65 6d 2e   ** file-system.
67e0: 0a 20 20 2a 2f 0a 20 20 70 42 61 73 65 20 3d 20  .  */.  pBase = 
67f0: 70 2d 3e 70 42 61 73 65 52 65 61 64 3b 0a 20 20  p->pBaseRead;.  
6800: 69 66 28 20 70 42 61 73 65 2d 3e 70 4d 65 74 68  if( pBase->pMeth
6810: 6f 64 73 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ods ){.    rc = 
6820: 70 42 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73 2d  pBase->pMethods-
6830: 3e 78 46 69 6c 65 53 69 7a 65 28 70 42 61 73 65  >xFileSize(pBase
6840: 2c 20 26 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  , &s);.  }..  if
6850: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6860: 29 7b 0a 20 20 20 20 41 73 79 6e 63 57 72 69 74  ){.    AsyncWrit
6870: 65 20 2a 70 57 72 69 74 65 3b 0a 20 20 20 20 66  e *pWrite;.    f
6880: 6f 72 28 70 57 72 69 74 65 3d 61 73 79 6e 63 2e  or(pWrite=async.
6890: 70 51 75 65 75 65 46 69 72 73 74 3b 20 70 57 72  pQueueFirst; pWr
68a0: 69 74 65 3b 20 70 57 72 69 74 65 20 3d 20 70 57  ite; pWrite = pW
68b0: 72 69 74 65 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  rite->pNext){.  
68c0: 20 20 20 20 69 66 28 20 70 57 72 69 74 65 2d 3e      if( pWrite->
68d0: 6f 70 3d 3d 41 53 59 4e 43 5f 44 45 4c 45 54 45  op==ASYNC_DELETE
68e0: 20 0a 20 20 20 20 20 20 20 26 26 20 70 2d 3e 7a   .       && p->z
68f0: 4e 61 6d 65 20 0a 20 20 20 20 20 20 20 26 26 20  Name .       && 
6900: 73 74 72 63 6d 70 28 70 2d 3e 7a 4e 61 6d 65 2c  strcmp(p->zName,
6910: 20 70 57 72 69 74 65 2d 3e 7a 42 75 66 29 3d 3d   pWrite->zBuf)==
6920: 30 20 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20  0 .      ){.    
6930: 20 20 20 20 73 20 3d 20 30 3b 0a 20 20 20 20 20      s = 0;.     
6940: 20 7d 65 6c 73 65 20 69 66 28 20 70 57 72 69 74   }else if( pWrit
6950: 65 2d 3e 70 46 69 6c 65 44 61 74 61 20 26 26 20  e->pFileData && 
6960: 28 0a 20 20 20 20 20 20 20 20 20 20 28 70 57 72  (.          (pWr
6970: 69 74 65 2d 3e 70 46 69 6c 65 44 61 74 61 3d 3d  ite->pFileData==
6980: 70 29 20 0a 20 20 20 20 20 20 20 7c 7c 20 28 70  p) .       || (p
6990: 2d 3e 7a 4e 61 6d 65 20 26 26 20 70 57 72 69 74  ->zName && pWrit
69a0: 65 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e  e->pFileData->zN
69b0: 61 6d 65 3d 3d 70 2d 3e 7a 4e 61 6d 65 29 20 0a  ame==p->zName) .
69c0: 20 20 20 20 20 20 29 29 7b 0a 20 20 20 20 20 20        )){.      
69d0: 20 20 73 77 69 74 63 68 28 20 70 57 72 69 74 65    switch( pWrite
69e0: 2d 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20 20 20  ->op ){.        
69f0: 20 20 63 61 73 65 20 41 53 59 4e 43 5f 57 52 49    case ASYNC_WRI
6a00: 54 45 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  TE:.            
6a10: 73 20 3d 20 4d 41 58 28 70 57 72 69 74 65 2d 3e  s = MAX(pWrite->
6a20: 69 4f 66 66 73 65 74 20 2b 20 28 73 71 6c 69 74  iOffset + (sqlit
6a30: 65 33 5f 69 6e 74 36 34 29 28 70 57 72 69 74 65  e3_int64)(pWrite
6a40: 2d 3e 6e 42 79 74 65 29 2c 20 73 29 3b 0a 20 20  ->nByte), s);.  
6a50: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
6a60: 0a 20 20 20 20 20 20 20 20 20 20 63 61 73 65 20  .          case 
6a70: 41 53 59 4e 43 5f 54 52 55 4e 43 41 54 45 3a 0a  ASYNC_TRUNCATE:.
6a80: 20 20 20 20 20 20 20 20 20 20 20 20 73 20 3d 20              s = 
6a90: 4d 49 4e 28 73 2c 20 70 57 72 69 74 65 2d 3e 69  MIN(s, pWrite->i
6aa0: 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 20  Offset);.       
6ab0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
6ac0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
6ad0: 20 20 7d 0a 20 20 20 20 2a 70 69 53 69 7a 65 20    }.    *piSize 
6ae0: 3d 20 73 3b 0a 20 20 7d 0a 20 20 61 73 79 6e 63  = s;.  }.  async
6af0: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59  _mutex_leave(ASY
6b00: 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b  NC_MUTEX_QUEUE);
6b10: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6b20: 0a 2f 2a 0a 2a 2a 20 4c 6f 63 6b 20 6f 72 20 75  ./*.** Lock or u
6b30: 6e 6c 6f 63 6b 20 74 68 65 20 61 63 74 75 61 6c  nlock the actual
6b40: 20 66 69 6c 65 2d 73 79 73 74 65 6d 20 65 6e 74   file-system ent
6b50: 72 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ry..*/.static in
6b60: 74 20 67 65 74 46 69 6c 65 4c 6f 63 6b 28 41 73  t getFileLock(As
6b70: 79 6e 63 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 29 7b  yncLock *pLock){
6b80: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
6b90: 54 45 5f 4f 4b 3b 0a 20 20 41 73 79 6e 63 46 69  TE_OK;.  AsyncFi
6ba0: 6c 65 4c 6f 63 6b 20 2a 70 49 74 65 72 3b 0a 20  leLock *pIter;. 
6bb0: 20 69 6e 74 20 65 52 65 71 75 69 72 65 64 20 3d   int eRequired =
6bc0: 20 30 3b 0a 0a 20 20 69 66 28 20 70 4c 6f 63 6b   0;..  if( pLock
6bd0: 2d 3e 70 46 69 6c 65 20 29 7b 0a 20 20 20 20 66  ->pFile ){.    f
6be0: 6f 72 28 70 49 74 65 72 3d 70 4c 6f 63 6b 2d 3e  or(pIter=pLock->
6bf0: 70 4c 69 73 74 3b 20 70 49 74 65 72 3b 20 70 49  pList; pIter; pI
6c00: 74 65 72 3d 70 49 74 65 72 2d 3e 70 4e 65 78 74  ter=pIter->pNext
6c10: 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ){.      assert(
6c20: 70 49 74 65 72 2d 3e 65 41 73 79 6e 63 4c 6f 63  pIter->eAsyncLoc
6c30: 6b 3e 3d 70 49 74 65 72 2d 3e 65 4c 6f 63 6b 29  k>=pIter->eLock)
6c40: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 49 74 65  ;.      if( pIte
6c50: 72 2d 3e 65 41 73 79 6e 63 4c 6f 63 6b 3e 65 52  r->eAsyncLock>eR
6c60: 65 71 75 69 72 65 64 20 29 7b 0a 20 20 20 20 20  equired ){.     
6c70: 20 20 20 65 52 65 71 75 69 72 65 64 20 3d 20 70     eRequired = p
6c80: 49 74 65 72 2d 3e 65 41 73 79 6e 63 4c 6f 63 6b  Iter->eAsyncLock
6c90: 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ;.        assert
6ca0: 28 65 52 65 71 75 69 72 65 64 3e 3d 30 20 26 26  (eRequired>=0 &&
6cb0: 20 65 52 65 71 75 69 72 65 64 3c 3d 53 51 4c 49   eRequired<=SQLI
6cc0: 54 45 5f 4c 4f 43 4b 5f 45 58 43 4c 55 53 49 56  TE_LOCK_EXCLUSIV
6cd0: 45 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  E);.      }.    
6ce0: 7d 0a 0a 20 20 20 20 69 66 28 20 65 52 65 71 75  }..    if( eRequ
6cf0: 69 72 65 64 3e 70 4c 6f 63 6b 2d 3e 65 4c 6f 63  ired>pLock->eLoc
6d00: 6b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  k ){.      rc = 
6d10: 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65 2d 3e 70 4d  pLock->pFile->pM
6d20: 65 74 68 6f 64 73 2d 3e 78 4c 6f 63 6b 28 70 4c  ethods->xLock(pL
6d30: 6f 63 6b 2d 3e 70 46 69 6c 65 2c 20 65 52 65 71  ock->pFile, eReq
6d40: 75 69 72 65 64 29 3b 0a 20 20 20 20 20 20 69 66  uired);.      if
6d50: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6d60: 29 7b 0a 20 20 20 20 20 20 20 20 70 4c 6f 63 6b  ){.        pLock
6d70: 2d 3e 65 4c 6f 63 6b 20 3d 20 65 52 65 71 75 69  ->eLock = eRequi
6d80: 72 65 64 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  red;.      }.   
6d90: 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28 20   }.    else if( 
6da0: 65 52 65 71 75 69 72 65 64 3c 70 4c 6f 63 6b 2d  eRequired<pLock-
6db0: 3e 65 4c 6f 63 6b 20 26 26 20 65 52 65 71 75 69  >eLock && eRequi
6dc0: 72 65 64 3c 3d 53 51 4c 49 54 45 5f 4c 4f 43 4b  red<=SQLITE_LOCK
6dd0: 5f 53 48 41 52 45 44 20 29 7b 0a 20 20 20 20 20  _SHARED ){.     
6de0: 20 72 63 20 3d 20 70 4c 6f 63 6b 2d 3e 70 46 69   rc = pLock->pFi
6df0: 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 55  le->pMethods->xU
6e00: 6e 6c 6f 63 6b 28 70 4c 6f 63 6b 2d 3e 70 46 69  nlock(pLock->pFi
6e10: 6c 65 2c 20 65 52 65 71 75 69 72 65 64 29 3b 0a  le, eRequired);.
6e20: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
6e30: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
6e40: 20 20 20 70 4c 6f 63 6b 2d 3e 65 4c 6f 63 6b 20     pLock->eLock 
6e50: 3d 20 65 52 65 71 75 69 72 65 64 3b 0a 20 20 20  = eRequired;.   
6e60: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
6e70: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6e80: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
6e90: 20 41 73 79 6e 63 4c 6f 63 6b 20 73 74 72 75 63   AsyncLock struc
6ea0: 74 75 72 65 20 66 72 6f 6d 20 74 68 65 20 67 6c  ture from the gl
6eb0: 6f 62 61 6c 20 61 73 79 6e 63 2e 70 4c 6f 63 6b  obal async.pLock
6ec0: 20 6c 69 73 74 20 0a 2a 2a 20 61 73 73 6f 63 69   list .** associ
6ed0: 61 74 65 64 20 77 69 74 68 20 74 68 65 20 66 69  ated with the fi
6ee0: 6c 65 2d 73 79 73 74 65 6d 20 65 6e 74 72 79 20  le-system entry 
6ef0: 69 64 65 6e 74 69 66 69 65 64 20 62 79 20 70 61  identified by pa
6f00: 74 68 20 7a 4e 61 6d 65 20 0a 2a 2a 20 28 61 20  th zName .** (a 
6f10: 73 74 72 69 6e 67 20 6f 66 20 6e 4e 61 6d 65 20  string of nName 
6f20: 62 79 74 65 73 29 2e 20 49 66 20 6e 6f 20 73 75  bytes). If no su
6f30: 63 68 20 73 74 72 75 63 74 75 72 65 20 65 78 69  ch structure exi
6f40: 73 74 73 2c 20 72 65 74 75 72 6e 20 30 2e 0a 2a  sts, return 0..*
6f50: 2f 0a 73 74 61 74 69 63 20 41 73 79 6e 63 4c 6f  /.static AsyncLo
6f60: 63 6b 20 2a 66 69 6e 64 4c 6f 63 6b 28 63 6f 6e  ck *findLock(con
6f70: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20  st char *zName, 
6f80: 69 6e 74 20 6e 4e 61 6d 65 29 7b 0a 20 20 41 73  int nName){.  As
6f90: 79 6e 63 4c 6f 63 6b 20 2a 70 20 3d 20 61 73 79  yncLock *p = asy
6fa0: 6e 63 2e 70 4c 6f 63 6b 3b 0a 20 20 77 68 69 6c  nc.pLock;.  whil
6fb0: 65 28 20 70 20 26 26 20 28 70 2d 3e 6e 46 69 6c  e( p && (p->nFil
6fc0: 65 21 3d 6e 4e 61 6d 65 20 7c 7c 20 6d 65 6d 63  e!=nName || memc
6fd0: 6d 70 28 70 2d 3e 7a 46 69 6c 65 2c 20 7a 4e 61  mp(p->zFile, zNa
6fe0: 6d 65 2c 20 6e 4e 61 6d 65 29 29 20 29 7b 0a 20  me, nName)) ){. 
6ff0: 20 20 20 70 20 3d 20 70 2d 3e 70 4e 65 78 74 3b     p = p->pNext;
7000: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b  .  }.  return p;
7010: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 6f  .}../*.** The fo
7020: 6c 6c 6f 77 69 6e 67 20 74 77 6f 20 6d 65 74 68  llowing two meth
7030: 6f 64 73 20 2d 20 61 73 79 6e 63 4c 6f 63 6b 28  ods - asyncLock(
7040: 29 20 61 6e 64 20 61 73 79 6e 63 55 6e 6c 6f 63  ) and asyncUnloc
7050: 6b 28 29 20 2d 20 61 72 65 20 75 73 65 64 0a 2a  k() - are used.*
7060: 2a 20 74 6f 20 6f 62 74 61 69 6e 20 61 6e 64 20  * to obtain and 
7070: 72 65 6c 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e  release locks on
7080: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 73 20   database files 
7090: 6f 70 65 6e 65 64 20 77 69 74 68 20 74 68 65 0a  opened with the.
70a0: 2a 2a 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20  ** asynchronous 
70b0: 62 61 63 6b 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74  backend..*/.stat
70c0: 69 63 20 69 6e 74 20 61 73 79 6e 63 4c 6f 63 6b  ic int asyncLock
70d0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
70e0: 46 69 6c 65 2c 20 69 6e 74 20 65 4c 6f 63 6b 29  File, int eLock)
70f0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
7100: 49 54 45 5f 4f 4b 3b 0a 20 20 41 73 79 6e 63 46  ITE_OK;.  AsyncF
7110: 69 6c 65 44 61 74 61 20 2a 70 20 3d 20 28 28 41  ileData *p = ((A
7120: 73 79 6e 63 46 69 6c 65 20 2a 29 70 46 69 6c 65  syncFile *)pFile
7130: 29 2d 3e 70 44 61 74 61 3b 0a 0a 20 20 69 66 28  )->pData;..  if(
7140: 20 70 2d 3e 7a 4e 61 6d 65 20 29 7b 0a 20 20 20   p->zName ){.   
7150: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74   async_mutex_ent
7160: 65 72 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c  er(ASYNC_MUTEX_L
7170: 4f 43 4b 29 3b 0a 20 20 20 20 69 66 28 20 70 2d  OCK);.    if( p-
7180: 3e 6c 6f 63 6b 2e 65 4c 6f 63 6b 3c 65 4c 6f 63  >lock.eLock<eLoc
7190: 6b 20 29 7b 0a 20 20 20 20 20 20 41 73 79 6e 63  k ){.      Async
71a0: 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 70 2d  Lock *pLock = p-
71b0: 3e 70 4c 6f 63 6b 3b 0a 20 20 20 20 20 20 41 73  >pLock;.      As
71c0: 79 6e 63 46 69 6c 65 4c 6f 63 6b 20 2a 70 49 74  yncFileLock *pIt
71d0: 65 72 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  er;.      assert
71e0: 28 70 4c 6f 63 6b 20 26 26 20 70 4c 6f 63 6b 2d  (pLock && pLock-
71f0: 3e 70 4c 69 73 74 29 3b 0a 20 20 20 20 20 20 66  >pList);.      f
7200: 6f 72 28 70 49 74 65 72 3d 70 4c 6f 63 6b 2d 3e  or(pIter=pLock->
7210: 70 4c 69 73 74 3b 20 70 49 74 65 72 3b 20 70 49  pList; pIter; pI
7220: 74 65 72 3d 70 49 74 65 72 2d 3e 70 4e 65 78 74  ter=pIter->pNext
7230: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  ){.        if( p
7240: 49 74 65 72 21 3d 26 70 2d 3e 6c 6f 63 6b 20 26  Iter!=&p->lock &
7250: 26 20 28 0a 20 20 20 20 20 20 20 20 20 20 28 65  & (.          (e
7260: 4c 6f 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f 43  Lock==SQLITE_LOC
7270: 4b 5f 45 58 43 4c 55 53 49 56 45 20 26 26 20 70  K_EXCLUSIVE && p
7280: 49 74 65 72 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c  Iter->eLock>=SQL
7290: 49 54 45 5f 4c 4f 43 4b 5f 53 48 41 52 45 44 29  ITE_LOCK_SHARED)
72a0: 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 28 65   ||.          (e
72b0: 4c 6f 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f 43  Lock==SQLITE_LOC
72c0: 4b 5f 50 45 4e 44 49 4e 47 20 26 26 20 70 49 74  K_PENDING && pIt
72d0: 65 72 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c 49 54  er->eLock>=SQLIT
72e0: 45 5f 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 29  E_LOCK_RESERVED)
72f0: 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 28 65   ||.          (e
7300: 4c 6f 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f 43  Lock==SQLITE_LOC
7310: 4b 5f 52 45 53 45 52 56 45 44 20 26 26 20 70 49  K_RESERVED && pI
7320: 74 65 72 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c 49  ter->eLock>=SQLI
7330: 54 45 5f 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44  TE_LOCK_RESERVED
7340: 29 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 28  ) ||.          (
7350: 65 4c 6f 63 6b 3d 3d 53 51 4c 49 54 45 5f 4c 4f  eLock==SQLITE_LO
7360: 43 4b 5f 53 48 41 52 45 44 20 26 26 20 70 49 74  CK_SHARED && pIt
7370: 65 72 2d 3e 65 4c 6f 63 6b 3e 3d 53 51 4c 49 54  er->eLock>=SQLIT
7380: 45 5f 4c 4f 43 4b 5f 50 45 4e 44 49 4e 47 29 0a  E_LOCK_PENDING).
7390: 20 20 20 20 20 20 20 20 29 29 7b 0a 20 20 20 20          )){.    
73a0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
73b0: 45 5f 42 55 53 59 3b 0a 20 20 20 20 20 20 20 20  E_BUSY;.        
73c0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
73d0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
73e0: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70 2d 3e  K ){.        p->
73f0: 6c 6f 63 6b 2e 65 4c 6f 63 6b 20 3d 20 65 4c 6f  lock.eLock = eLo
7400: 63 6b 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 6c  ck;.        p->l
7410: 6f 63 6b 2e 65 41 73 79 6e 63 4c 6f 63 6b 20 3d  ock.eAsyncLock =
7420: 20 4d 41 58 28 70 2d 3e 6c 6f 63 6b 2e 65 41 73   MAX(p->lock.eAs
7430: 79 6e 63 4c 6f 63 6b 2c 20 65 4c 6f 63 6b 29 3b  yncLock, eLock);
7440: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
7450: 73 73 65 72 74 28 70 2d 3e 6c 6f 63 6b 2e 65 41  ssert(p->lock.eA
7460: 73 79 6e 63 4c 6f 63 6b 3e 3d 70 2d 3e 6c 6f 63  syncLock>=p->loc
7470: 6b 2e 65 4c 6f 63 6b 29 3b 0a 20 20 20 20 20 20  k.eLock);.      
7480: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
7490: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  K ){.        rc 
74a0: 3d 20 67 65 74 46 69 6c 65 4c 6f 63 6b 28 70 4c  = getFileLock(pL
74b0: 6f 63 6b 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ock);.      }.  
74c0: 20 20 7d 0a 20 20 20 20 61 73 79 6e 63 5f 6d 75    }.    async_mu
74d0: 74 65 78 5f 6c 65 61 76 65 28 41 53 59 4e 43 5f  tex_leave(ASYNC_
74e0: 4d 55 54 45 58 5f 4c 4f 43 4b 29 3b 0a 20 20 7d  MUTEX_LOCK);.  }
74f0: 0a 0a 20 20 41 53 59 4e 43 5f 54 52 41 43 45 28  ..  ASYNC_TRACE(
7500: 28 22 4c 4f 43 4b 20 25 64 20 28 25 73 29 20 72  ("LOCK %d (%s) r
7510: 63 3d 25 64 5c 6e 22 2c 20 65 4c 6f 63 6b 2c 20  c=%d\n", eLock, 
7520: 70 2d 3e 7a 4e 61 6d 65 2c 20 72 63 29 29 3b 0a  p->zName, rc));.
7530: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73    return rc;.}.s
7540: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 55  tatic int asyncU
7550: 6e 6c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69  nlock(sqlite3_fi
7560: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 65  le *pFile, int e
7570: 4c 6f 63 6b 29 7b 0a 20 20 69 6e 74 20 72 63 20  Lock){.  int rc 
7580: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 41  = SQLITE_OK;.  A
7590: 73 79 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 20  syncFileData *p 
75a0: 3d 20 28 28 41 73 79 6e 63 46 69 6c 65 20 2a 29  = ((AsyncFile *)
75b0: 70 46 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a 20  pFile)->pData;. 
75c0: 20 69 66 28 20 70 2d 3e 7a 4e 61 6d 65 20 29 7b   if( p->zName ){
75d0: 0a 20 20 20 20 41 73 79 6e 63 46 69 6c 65 4c 6f  .    AsyncFileLo
75e0: 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 26 70 2d 3e  ck *pLock = &p->
75f0: 6c 6f 63 6b 3b 0a 20 20 20 20 61 73 79 6e 63 5f  lock;.    async_
7600: 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e  mutex_enter(ASYN
7610: 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b 0a  C_MUTEX_QUEUE);.
7620: 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f      async_mutex_
7630: 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54 45  enter(ASYNC_MUTE
7640: 58 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 70 4c 6f  X_LOCK);.    pLo
7650: 63 6b 2d 3e 65 4c 6f 63 6b 20 3d 20 4d 49 4e 28  ck->eLock = MIN(
7660: 70 4c 6f 63 6b 2d 3e 65 4c 6f 63 6b 2c 20 65 4c  pLock->eLock, eL
7670: 6f 63 6b 29 3b 0a 20 20 20 20 72 63 20 3d 20 61  ock);.    rc = a
7680: 64 64 4e 65 77 41 73 79 6e 63 57 72 69 74 65 28  ddNewAsyncWrite(
7690: 70 2c 20 41 53 59 4e 43 5f 55 4e 4c 4f 43 4b 2c  p, ASYNC_UNLOCK,
76a0: 20 30 2c 20 65 4c 6f 63 6b 2c 20 30 29 3b 0a 20   0, eLock, 0);. 
76b0: 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c     async_mutex_l
76c0: 65 61 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58  eave(ASYNC_MUTEX
76d0: 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 61 73 79 6e  _LOCK);.    asyn
76e0: 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53  c_mutex_leave(AS
76f0: 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29  YNC_MUTEX_QUEUE)
7700: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
7710: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
7720: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
7730: 6c 65 64 20 77 68 65 6e 20 74 68 65 20 70 61 67  led when the pag
7740: 65 72 20 6c 61 79 65 72 20 66 69 72 73 74 20 6f  er layer first o
7750: 70 65 6e 73 20 61 20 64 61 74 61 62 61 73 65 20  pens a database 
7760: 66 69 6c 65 0a 2a 2a 20 61 6e 64 20 69 73 20 63  file.** and is c
7770: 68 65 63 6b 69 6e 67 20 66 6f 72 20 61 20 68 6f  hecking for a ho
7780: 74 2d 6a 6f 75 72 6e 61 6c 2e 0a 2a 2f 0a 73 74  t-journal..*/.st
7790: 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 43 68  atic int asyncCh
77a0: 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28  eckReservedLock(
77b0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
77c0: 69 6c 65 2c 20 69 6e 74 20 2a 70 52 65 73 4f 75  ile, int *pResOu
77d0: 74 29 7b 0a 20 20 69 6e 74 20 72 65 74 20 3d 20  t){.  int ret = 
77e0: 30 3b 0a 20 20 41 73 79 6e 63 46 69 6c 65 4c 6f  0;.  AsyncFileLo
77f0: 63 6b 20 2a 70 49 74 65 72 3b 0a 20 20 41 73 79  ck *pIter;.  Asy
7800: 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 20 3d 20  ncFileData *p = 
7810: 28 28 41 73 79 6e 63 46 69 6c 65 20 2a 29 70 46  ((AsyncFile *)pF
7820: 69 6c 65 29 2d 3e 70 44 61 74 61 3b 0a 0a 20 20  ile)->pData;..  
7830: 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65  async_mutex_ente
7840: 72 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f  r(ASYNC_MUTEX_LO
7850: 43 4b 29 3b 0a 20 20 66 6f 72 28 70 49 74 65 72  CK);.  for(pIter
7860: 3d 70 2d 3e 70 4c 6f 63 6b 2d 3e 70 4c 69 73 74  =p->pLock->pList
7870: 3b 20 70 49 74 65 72 3b 20 70 49 74 65 72 3d 70  ; pIter; pIter=p
7880: 49 74 65 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  Iter->pNext){.  
7890: 20 20 69 66 28 20 70 49 74 65 72 2d 3e 65 4c 6f    if( pIter->eLo
78a0: 63 6b 3e 3d 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f  ck>=SQLITE_LOCK_
78b0: 52 45 53 45 52 56 45 44 20 29 7b 0a 20 20 20 20  RESERVED ){.    
78c0: 20 20 72 65 74 20 3d 20 31 3b 0a 20 20 20 20 20    ret = 1;.     
78d0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
78e0: 7d 0a 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f  }.  async_mutex_
78f0: 6c 65 61 76 65 28 41 53 59 4e 43 5f 4d 55 54 45  leave(ASYNC_MUTE
7900: 58 5f 4c 4f 43 4b 29 3b 0a 0a 20 20 41 53 59 4e  X_LOCK);..  ASYN
7910: 43 5f 54 52 41 43 45 28 28 22 43 48 45 43 4b 2d  C_TRACE(("CHECK-
7920: 4c 4f 43 4b 20 25 64 20 28 25 73 29 5c 6e 22 2c  LOCK %d (%s)\n",
7930: 20 72 65 74 2c 20 70 2d 3e 7a 4e 61 6d 65 29 29   ret, p->zName))
7940: 3b 0a 20 20 2a 70 52 65 73 4f 75 74 20 3d 20 72  ;.  *pResOut = r
7950: 65 74 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  et;.  return SQL
7960: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  ITE_OK;.}../* .*
7970: 2a 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 5f 63  * sqlite3_file_c
7980: 6f 6e 74 72 6f 6c 28 29 20 69 6d 70 6c 65 6d 65  ontrol() impleme
7990: 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  ntation..*/.stat
79a0: 69 63 20 69 6e 74 20 61 73 79 6e 63 46 69 6c 65  ic int asyncFile
79b0: 43 6f 6e 74 72 6f 6c 28 73 71 6c 69 74 65 33 5f  Control(sqlite3_
79c0: 66 69 6c 65 20 2a 69 64 2c 20 69 6e 74 20 6f 70  file *id, int op
79d0: 2c 20 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a 20  , void *pArg){. 
79e0: 20 73 77 69 74 63 68 28 20 6f 70 20 29 7b 0a 20   switch( op ){. 
79f0: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 46     case SQLITE_F
7a00: 43 4e 54 4c 5f 4c 4f 43 4b 53 54 41 54 45 3a 20  CNTL_LOCKSTATE: 
7a10: 7b 0a 20 20 20 20 20 20 61 73 79 6e 63 5f 6d 75  {.      async_mu
7a20: 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f  tex_enter(ASYNC_
7a30: 4d 55 54 45 58 5f 4c 4f 43 4b 29 3b 0a 20 20 20  MUTEX_LOCK);.   
7a40: 20 20 20 2a 28 69 6e 74 2a 29 70 41 72 67 20 3d     *(int*)pArg =
7a50: 20 28 28 41 73 79 6e 63 46 69 6c 65 2a 29 69 64   ((AsyncFile*)id
7a60: 29 2d 3e 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e 65  )->pData->lock.e
7a70: 4c 6f 63 6b 3b 0a 20 20 20 20 20 20 61 73 79 6e  Lock;.      asyn
7a80: 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53  c_mutex_leave(AS
7a90: 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b 29 3b  YNC_MUTEX_LOCK);
7aa0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
7ab0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20  LITE_OK;.    }. 
7ac0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
7ad0: 54 45 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a 20  TE_ERROR;.}../* 
7ae0: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 64  .** Return the d
7af0: 65 76 69 63 65 20 63 68 61 72 61 63 74 65 72 69  evice characteri
7b00: 73 74 69 63 73 20 61 6e 64 20 73 65 63 74 6f 72  stics and sector
7b10: 2d 73 69 7a 65 20 6f 66 20 74 68 65 20 64 65 76  -size of the dev
7b20: 69 63 65 2e 20 49 74 0a 2a 2a 20 69 73 20 74 72  ice. It.** is tr
7b30: 69 63 6b 79 20 74 6f 20 69 6d 70 6c 65 6d 65 6e  icky to implemen
7b40: 74 20 74 68 65 73 65 20 63 6f 72 72 65 63 74 6c  t these correctl
7b50: 79 2c 20 61 73 20 74 68 69 73 20 62 61 63 6b 65  y, as this backe
7b60: 6e 64 20 6d 69 67 68 74 20 0a 2a 2a 20 6e 6f 74  nd might .** not
7b70: 20 68 61 76 65 20 61 6e 20 6f 70 65 6e 20 66 69   have an open fi
7b80: 6c 65 20 68 61 6e 64 6c 65 20 61 74 20 74 68 69  le handle at thi
7b90: 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 73 74 61 74  s point..*/.stat
7ba0: 69 63 20 69 6e 74 20 61 73 79 6e 63 53 65 63 74  ic int asyncSect
7bb0: 6f 72 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66  orSize(sqlite3_f
7bc0: 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 55  ile *pFile){.  U
7bd0: 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28  NUSED_PARAMETER(
7be0: 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e  pFile);.  return
7bf0: 20 35 31 32 3b 0a 7d 0a 73 74 61 74 69 63 20 69   512;.}.static i
7c00: 6e 74 20 61 73 79 6e 63 44 65 76 69 63 65 43 68  nt asyncDeviceCh
7c10: 61 72 61 63 74 65 72 69 73 74 69 63 73 28 73 71  aracteristics(sq
7c20: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
7c30: 65 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52  e){.  UNUSED_PAR
7c40: 41 4d 45 54 45 52 28 70 46 69 6c 65 29 3b 0a 20  AMETER(pFile);. 
7c50: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 73 74   return 0;.}..st
7c60: 61 74 69 63 20 69 6e 74 20 75 6e 6c 69 6e 6b 41  atic int unlinkA
7c70: 73 79 6e 63 46 69 6c 65 28 41 73 79 6e 63 46 69  syncFile(AsyncFi
7c80: 6c 65 44 61 74 61 20 2a 70 44 61 74 61 29 7b 0a  leData *pData){.
7c90: 20 20 41 73 79 6e 63 46 69 6c 65 4c 6f 63 6b 20    AsyncFileLock 
7ca0: 2a 2a 70 70 49 74 65 72 3b 0a 20 20 69 6e 74 20  **ppIter;.  int 
7cb0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
7cc0: 0a 20 20 69 66 28 20 70 44 61 74 61 2d 3e 7a 4e  .  if( pData->zN
7cd0: 61 6d 65 20 29 7b 0a 20 20 20 20 41 73 79 6e 63  ame ){.    Async
7ce0: 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 70 44  Lock *pLock = pD
7cf0: 61 74 61 2d 3e 70 4c 6f 63 6b 3b 0a 20 20 20 20  ata->pLock;.    
7d00: 66 6f 72 28 70 70 49 74 65 72 3d 26 70 4c 6f 63  for(ppIter=&pLoc
7d10: 6b 2d 3e 70 4c 69 73 74 3b 20 2a 70 70 49 74 65  k->pList; *ppIte
7d20: 72 3b 20 70 70 49 74 65 72 3d 26 28 28 2a 70 70  r; ppIter=&((*pp
7d30: 49 74 65 72 29 2d 3e 70 4e 65 78 74 29 29 7b 0a  Iter)->pNext)){.
7d40: 20 20 20 20 20 20 69 66 28 20 28 2a 70 70 49 74        if( (*ppIt
7d50: 65 72 29 3d 3d 26 70 44 61 74 61 2d 3e 6c 6f 63  er)==&pData->loc
7d60: 6b 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 70 70  k ){.        *pp
7d70: 49 74 65 72 20 3d 20 70 44 61 74 61 2d 3e 6c 6f  Iter = pData->lo
7d80: 63 6b 2e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  ck.pNext;.      
7d90: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
7da0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 21  .    }.    if( !
7db0: 70 4c 6f 63 6b 2d 3e 70 4c 69 73 74 20 29 7b 0a  pLock->pList ){.
7dc0: 20 20 20 20 20 20 41 73 79 6e 63 4c 6f 63 6b 20        AsyncLock 
7dd0: 2a 2a 70 70 3b 0a 20 20 20 20 20 20 69 66 28 20  **pp;.      if( 
7de0: 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65 20 29 7b 0a  pLock->pFile ){.
7df0: 20 20 20 20 20 20 20 20 70 4c 6f 63 6b 2d 3e 70          pLock->p
7e00: 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  File->pMethods->
7e10: 78 43 6c 6f 73 65 28 70 4c 6f 63 6b 2d 3e 70 46  xClose(pLock->pF
7e20: 69 6c 65 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ile);.      }.  
7e30: 20 20 20 20 66 6f 72 28 70 70 3d 26 61 73 79 6e      for(pp=&asyn
7e40: 63 2e 70 4c 6f 63 6b 3b 20 2a 70 70 21 3d 70 4c  c.pLock; *pp!=pL
7e50: 6f 63 6b 3b 20 70 70 3d 26 28 28 2a 70 70 29 2d  ock; pp=&((*pp)-
7e60: 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20 20 20  >pNext));.      
7e70: 2a 70 70 20 3d 20 70 4c 6f 63 6b 2d 3e 70 4e 65  *pp = pLock->pNe
7e80: 78 74 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  xt;.      sqlite
7e90: 33 5f 66 72 65 65 28 70 4c 6f 63 6b 29 3b 0a 20  3_free(pLock);. 
7ea0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
7eb0: 72 63 20 3d 20 67 65 74 46 69 6c 65 4c 6f 63 6b  rc = getFileLock
7ec0: 28 70 4c 6f 63 6b 29 3b 0a 20 20 20 20 7d 0a 20  (pLock);.    }. 
7ed0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
7ee0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 70 61  .}../*.** The pa
7ef0: 72 61 6d 65 74 65 72 20 70 61 73 73 65 64 20 74  rameter passed t
7f00: 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  o this function 
7f10: 69 73 20 61 20 63 6f 70 79 20 6f 66 20 61 20 27  is a copy of a '
7f20: 66 6c 61 67 73 27 20 70 61 72 61 6d 65 74 65 72  flags' parameter
7f30: 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f 20 74 68  .** passed to th
7f40: 69 73 20 6d 6f 64 75 6c 65 73 20 78 4f 70 65 6e  is modules xOpen
7f50: 28 29 20 6d 65 74 68 6f 64 2e 20 54 68 69 73 20  () method. This 
7f60: 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
7f70: 20 74 72 75 65 0a 2a 2a 20 69 66 20 74 68 65 20   true.** if the 
7f80: 66 69 6c 65 20 73 68 6f 75 6c 64 20 62 65 20 6f  file should be o
7f90: 70 65 6e 65 64 20 61 73 79 6e 63 68 72 6f 6e 6f  pened asynchrono
7fa0: 75 73 6c 79 2c 20 6f 72 20 66 61 6c 73 65 20 69  usly, or false i
7fb0: 66 20 69 74 20 73 68 6f 75 6c 64 0a 2a 2a 20 62  f it should.** b
7fc0: 65 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64 69 61  e opened immedia
7fd0: 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  tely..**.** If t
7fe0: 68 65 20 66 69 6c 65 20 69 73 20 74 6f 20 62 65  he file is to be
7ff0: 20 6f 70 65 6e 65 64 20 61 73 79 6e 63 68 72 6f   opened asynchro
8000: 6e 6f 75 73 6c 79 2c 20 74 68 65 6e 20 61 73 79  nously, then asy
8010: 6e 63 4f 70 65 6e 28 29 20 77 69 6c 6c 20 61 64  ncOpen() will ad
8020: 64 0a 2a 2a 20 61 6e 20 65 6e 74 72 79 20 74 6f  d.** an entry to
8030: 20 74 68 65 20 65 76 65 6e 74 20 71 75 65 75 65   the event queue
8040: 20 61 6e 64 20 74 68 65 20 66 69 6c 65 20 77 69   and the file wi
8050: 6c 6c 20 6e 6f 74 20 61 63 74 75 61 6c 6c 79 20  ll not actually 
8060: 62 65 20 6f 70 65 6e 65 64 0a 2a 2a 20 75 6e 74  be opened.** unt
8070: 69 6c 20 74 68 65 20 65 76 65 6e 74 20 69 73 20  il the event is 
8080: 70 72 6f 63 65 73 73 65 64 2e 20 4f 74 68 65 72  processed. Other
8090: 77 69 73 65 2c 20 74 68 65 20 66 69 6c 65 20 69  wise, the file i
80a0: 73 20 6f 70 65 6e 65 64 20 64 69 72 65 63 74 6c  s opened directl
80b0: 79 0a 2a 2a 20 62 79 20 74 68 65 20 63 61 6c 6c  y.** by the call
80c0: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  er..*/.static in
80d0: 74 20 64 6f 41 73 79 6e 63 68 72 6f 6e 6f 75 73  t doAsynchronous
80e0: 4f 70 65 6e 28 69 6e 74 20 66 6c 61 67 73 29 7b  Open(int flags){
80f0: 0a 20 20 72 65 74 75 72 6e 20 28 66 6c 61 67 73  .  return (flags
8100: 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45  &SQLITE_OPEN_CRE
8110: 41 54 45 29 20 26 26 20 28 0a 20 20 20 20 20 20  ATE) && (.      
8120: 28 66 6c 61 67 73 26 53 51 4c 49 54 45 5f 4f 50  (flags&SQLITE_OP
8130: 45 4e 5f 4d 41 49 4e 5f 4a 4f 55 52 4e 41 4c 29  EN_MAIN_JOURNAL)
8140: 20 7c 7c 0a 20 20 20 20 20 20 28 66 6c 61 67 73   ||.      (flags
8150: 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 54 45 4d  &SQLITE_OPEN_TEM
8160: 50 5f 4a 4f 55 52 4e 41 4c 29 20 7c 7c 0a 20 20  P_JOURNAL) ||.  
8170: 20 20 20 20 28 66 6c 61 67 73 26 53 51 4c 49 54      (flags&SQLIT
8180: 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45 4f 4e 43  E_OPEN_DELETEONC
8190: 4c 4f 53 45 29 0a 20 20 29 3b 0a 7d 0a 0a 2f 2a  LOSE).  );.}../*
81a0: 0a 2a 2a 20 4f 70 65 6e 20 61 20 66 69 6c 65 2e  .** Open a file.
81b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .*/.static int a
81c0: 73 79 6e 63 4f 70 65 6e 28 0a 20 20 73 71 6c 69  syncOpen(.  sqli
81d0: 74 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56  te3_vfs *pAsyncV
81e0: 66 73 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  fs,.  const char
81f0: 20 2a 7a 4e 61 6d 65 2c 0a 20 20 73 71 6c 69 74   *zName,.  sqlit
8200: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a  e3_file *pFile,.
8210: 20 20 69 6e 74 20 66 6c 61 67 73 2c 0a 20 20 69    int flags,.  i
8220: 6e 74 20 2a 70 4f 75 74 46 6c 61 67 73 0a 29 7b  nt *pOutFlags.){
8230: 0a 20 20 73 74 61 74 69 63 20 73 71 6c 69 74 65  .  static sqlite
8240: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 61 73 79  3_io_methods asy
8250: 6e 63 5f 6d 65 74 68 6f 64 73 20 3d 20 7b 0a 20  nc_methods = {. 
8260: 20 20 20 31 2c 20 20 20 20 20 20 20 20 20 20 20     1,           
8270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8280: 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20      /* iVersion 
8290: 2a 2f 0a 20 20 20 20 61 73 79 6e 63 43 6c 6f 73  */.    asyncClos
82a0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
82b0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73          /* xClos
82c0: 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 52 65  e */.    asyncRe
82d0: 61 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ad,             
82e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65            /* xRe
82f0: 61 64 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 57  ad */.    asyncW
8300: 72 69 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  rite,           
8310: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 57             /* xW
8320: 72 69 74 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e  rite */.    asyn
8330: 63 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20  cTruncate,      
8340: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8350: 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20  xTruncate */.   
8360: 20 61 73 79 6e 63 53 79 6e 63 2c 20 20 20 20 20   asyncSync,     
8370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8380: 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20    /* xSync */.  
8390: 20 20 61 73 79 6e 63 46 69 6c 65 53 69 7a 65 2c    asyncFileSize,
83a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
83b0: 20 20 20 2f 2a 20 78 46 69 6c 65 53 69 7a 65 20     /* xFileSize 
83c0: 2a 2f 0a 20 20 20 20 61 73 79 6e 63 4c 6f 63 6b  */.    asyncLock
83d0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
83e0: 20 20 20 20 20 20 20 20 2f 2a 20 78 4c 6f 63 6b          /* xLock
83f0: 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 55 6e 6c   */.    asyncUnl
8400: 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ock,            
8410: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e 6c           /* xUnl
8420: 6f 63 6b 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63  ock */.    async
8430: 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63  CheckReservedLoc
8440: 6b 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  k,          /* x
8450: 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63  CheckReservedLoc
8460: 6b 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 46 69  k */.    asyncFi
8470: 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20 20 20  leControl,      
8480: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69            /* xFi
8490: 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20 20 20  leControl */.   
84a0: 20 61 73 79 6e 63 53 65 63 74 6f 72 53 69 7a 65   asyncSectorSize
84b0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
84c0: 20 20 2f 2a 20 78 53 65 63 74 6f 72 53 69 7a 65    /* xSectorSize
84d0: 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 44 65 76   */.    asyncDev
84e0: 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69  iceCharacteristi
84f0: 63 73 20 20 20 20 20 20 20 2f 2a 20 78 44 65 76  cs       /* xDev
8500: 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69  iceCharacteristi
8510: 63 73 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 73 71  cs */.  };..  sq
8520: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20  lite3_vfs *pVfs 
8530: 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  = (sqlite3_vfs *
8540: 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70  )pAsyncVfs->pApp
8550: 44 61 74 61 3b 0a 20 20 41 73 79 6e 63 46 69 6c  Data;.  AsyncFil
8560: 65 20 2a 70 20 3d 20 28 41 73 79 6e 63 46 69 6c  e *p = (AsyncFil
8570: 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 69 6e 74  e *)pFile;.  int
8580: 20 6e 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 69 6e   nName = 0;.  in
8590: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
85a0: 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20  ;.  int nByte;. 
85b0: 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 20 2a   AsyncFileData *
85c0: 70 44 61 74 61 3b 0a 20 20 41 73 79 6e 63 4c 6f  pData;.  AsyncLo
85d0: 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 30 3b 0a 20  ck *pLock = 0;. 
85e0: 20 63 68 61 72 20 2a 7a 3b 0a 20 20 69 6e 74 20   char *z;.  int 
85f0: 69 73 41 73 79 6e 63 4f 70 65 6e 20 3d 20 64 6f  isAsyncOpen = do
8600: 41 73 79 6e 63 68 72 6f 6e 6f 75 73 4f 70 65 6e  AsynchronousOpen
8610: 28 66 6c 61 67 73 29 3b 0a 0a 20 20 2f 2a 20 49  (flags);..  /* I
8620: 66 20 7a 4e 61 6d 65 20 69 73 20 4e 55 4c 4c 2c  f zName is NULL,
8630: 20 74 68 65 6e 20 74 68 65 20 75 70 70 65 72 20   then the upper 
8640: 6c 61 79 65 72 20 69 73 20 72 65 71 75 65 73 74  layer is request
8650: 69 6e 67 20 61 6e 20 61 6e 6f 6e 79 6d 6f 75 73  ing an anonymous
8660: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 66 28 20 7a   file */.  if( z
8670: 4e 61 6d 65 20 29 7b 0a 20 20 20 20 6e 4e 61 6d  Name ){.    nNam
8680: 65 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  e = (int)strlen(
8690: 7a 4e 61 6d 65 29 2b 31 3b 0a 20 20 7d 0a 0a 20  zName)+1;.  }.. 
86a0: 20 6e 42 79 74 65 20 3d 20 28 0a 20 20 20 20 73   nByte = (.    s
86b0: 69 7a 65 6f 66 28 41 73 79 6e 63 46 69 6c 65 44  izeof(AsyncFileD
86c0: 61 74 61 29 20 2b 20 20 20 20 20 20 20 20 2f 2a  ata) +        /*
86d0: 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 20 73   AsyncFileData s
86e0: 74 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 20 20  tructure */.    
86f0: 32 20 2a 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69  2 * pVfs->szOsFi
8700: 6c 65 20 2b 20 20 20 20 20 20 20 20 20 20 20 2f  le +           /
8710: 2a 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 2e  * AsyncFileData.
8720: 70 42 61 73 65 52 65 61 64 20 61 6e 64 20 70 42  pBaseRead and pB
8730: 61 73 65 57 72 69 74 65 20 2a 2f 0a 20 20 20 20  aseWrite */.    
8740: 6e 4e 61 6d 65 20 20 20 20 20 20 20 20 20 20 20  nName           
8750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8760: 2a 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 2e  * AsyncFileData.
8770: 7a 4e 61 6d 65 20 2a 2f 0a 20 20 29 3b 20 0a 20  zName */.  ); . 
8780: 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c   z = sqlite3_mal
8790: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66  loc(nByte);.  if
87a0: 28 20 21 7a 20 29 7b 0a 20 20 20 20 72 65 74 75  ( !z ){.    retu
87b0: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
87c0: 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74 28 7a 2c  .  }.  memset(z,
87d0: 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70 44   0, nByte);.  pD
87e0: 61 74 61 20 3d 20 28 41 73 79 6e 63 46 69 6c 65  ata = (AsyncFile
87f0: 44 61 74 61 2a 29 7a 3b 0a 20 20 7a 20 2b 3d 20  Data*)z;.  z += 
8800: 73 69 7a 65 6f 66 28 70 44 61 74 61 5b 30 5d 29  sizeof(pData[0])
8810: 3b 0a 20 20 70 44 61 74 61 2d 3e 70 42 61 73 65  ;.  pData->pBase
8820: 52 65 61 64 20 3d 20 28 73 71 6c 69 74 65 33 5f  Read = (sqlite3_
8830: 66 69 6c 65 2a 29 7a 3b 0a 20 20 7a 20 2b 3d 20  file*)z;.  z += 
8840: 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 3b 0a  pVfs->szOsFile;.
8850: 20 20 70 44 61 74 61 2d 3e 70 42 61 73 65 57 72    pData->pBaseWr
8860: 69 74 65 20 3d 20 28 73 71 6c 69 74 65 33 5f 66  ite = (sqlite3_f
8870: 69 6c 65 2a 29 7a 3b 0a 20 20 70 44 61 74 61 2d  ile*)z;.  pData-
8880: 3e 63 6c 6f 73 65 4f 70 2e 70 46 69 6c 65 44 61  >closeOp.pFileDa
8890: 74 61 20 3d 20 70 44 61 74 61 3b 0a 20 20 70 44  ta = pData;.  pD
88a0: 61 74 61 2d 3e 63 6c 6f 73 65 4f 70 2e 6f 70 20  ata->closeOp.op 
88b0: 3d 20 41 53 59 4e 43 5f 43 4c 4f 53 45 3b 0a 0a  = ASYNC_CLOSE;..
88c0: 20 20 69 66 28 20 7a 4e 61 6d 65 20 29 7b 0a 20    if( zName ){. 
88d0: 20 20 20 7a 20 2b 3d 20 70 56 66 73 2d 3e 73 7a     z += pVfs->sz
88e0: 4f 73 46 69 6c 65 3b 0a 20 20 20 20 70 44 61 74  OsFile;.    pDat
88f0: 61 2d 3e 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20  a->zName = z;.  
8900: 20 20 70 44 61 74 61 2d 3e 6e 4e 61 6d 65 20 3d    pData->nName =
8910: 20 6e 4e 61 6d 65 3b 0a 20 20 20 20 6d 65 6d 63   nName;.    memc
8920: 70 79 28 70 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c  py(pData->zName,
8930: 20 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 29 3b 0a   zName, nName);.
8940: 20 20 7d 0a 0a 20 20 69 66 28 20 21 69 73 41 73    }..  if( !isAs
8950: 79 6e 63 4f 70 65 6e 20 29 7b 0a 20 20 20 20 69  yncOpen ){.    i
8960: 6e 74 20 66 6c 61 67 73 6f 75 74 3b 0a 20 20 20  nt flagsout;.   
8970: 20 72 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65   rc = pVfs->xOpe
8980: 6e 28 70 56 66 73 2c 20 70 44 61 74 61 2d 3e 7a  n(pVfs, pData->z
8990: 4e 61 6d 65 2c 20 70 44 61 74 61 2d 3e 70 42 61  Name, pData->pBa
89a0: 73 65 52 65 61 64 2c 20 66 6c 61 67 73 2c 20 26  seRead, flags, &
89b0: 66 6c 61 67 73 6f 75 74 29 3b 0a 20 20 20 20 69  flagsout);.    i
89c0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
89d0: 20 0a 20 20 20 20 20 26 26 20 28 66 6c 61 67 73   .     && (flags
89e0: 6f 75 74 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  out&SQLITE_OPEN_
89f0: 52 45 41 44 57 52 49 54 45 29 20 0a 20 20 20 20  READWRITE) .    
8a00: 20 26 26 20 28 66 6c 61 67 73 26 53 51 4c 49 54   && (flags&SQLIT
8a10: 45 5f 4f 50 45 4e 5f 45 58 43 4c 55 53 49 56 45  E_OPEN_EXCLUSIVE
8a20: 29 3d 3d 30 0a 20 20 20 20 29 7b 0a 20 20 20 20  )==0.    ){.    
8a30: 20 20 72 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70    rc = pVfs->xOp
8a40: 65 6e 28 70 56 66 73 2c 20 70 44 61 74 61 2d 3e  en(pVfs, pData->
8a50: 7a 4e 61 6d 65 2c 20 70 44 61 74 61 2d 3e 70 42  zName, pData->pB
8a60: 61 73 65 57 72 69 74 65 2c 20 66 6c 61 67 73 2c  aseWrite, flags,
8a70: 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69   0);.    }.    i
8a80: 66 28 20 70 4f 75 74 46 6c 61 67 73 20 29 7b 0a  f( pOutFlags ){.
8a90: 20 20 20 20 20 20 2a 70 4f 75 74 46 6c 61 67 73        *pOutFlags
8aa0: 20 3d 20 66 6c 61 67 73 6f 75 74 3b 0a 20 20 20   = flagsout;.   
8ab0: 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63 5f   }.  }..  async_
8ac0: 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e  mutex_enter(ASYN
8ad0: 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b 29 3b 0a 0a  C_MUTEX_LOCK);..
8ae0: 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 72    if( zName && r
8af0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
8b00: 20 20 20 20 70 4c 6f 63 6b 20 3d 20 66 69 6e 64      pLock = find
8b10: 4c 6f 63 6b 28 70 44 61 74 61 2d 3e 7a 4e 61 6d  Lock(pData->zNam
8b20: 65 2c 20 70 44 61 74 61 2d 3e 6e 4e 61 6d 65 29  e, pData->nName)
8b30: 3b 0a 20 20 20 20 69 66 28 20 21 70 4c 6f 63 6b  ;.    if( !pLock
8b40: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 42   ){.      int nB
8b50: 79 74 65 20 3d 20 70 56 66 73 2d 3e 73 7a 4f 73  yte = pVfs->szOs
8b60: 46 69 6c 65 20 2b 20 73 69 7a 65 6f 66 28 41 73  File + sizeof(As
8b70: 79 6e 63 4c 6f 63 6b 29 20 2b 20 70 44 61 74 61  yncLock) + pData
8b80: 2d 3e 6e 4e 61 6d 65 20 2b 20 31 3b 20 0a 20 20  ->nName + 1; .  
8b90: 20 20 20 20 70 4c 6f 63 6b 20 3d 20 28 41 73 79      pLock = (Asy
8ba0: 6e 63 4c 6f 63 6b 20 2a 29 73 71 6c 69 74 65 33  ncLock *)sqlite3
8bb0: 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a  _malloc(nByte);.
8bc0: 20 20 20 20 20 20 69 66 28 20 70 4c 6f 63 6b 20        if( pLock 
8bd0: 29 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65  ){.        memse
8be0: 74 28 70 4c 6f 63 6b 2c 20 30 2c 20 6e 42 79 74  t(pLock, 0, nByt
8bf0: 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  e);.        if( 
8c00: 61 73 79 6e 63 2e 62 4c 6f 63 6b 46 69 6c 65 73  async.bLockFiles
8c10: 20 26 26 20 28 66 6c 61 67 73 26 53 51 4c 49 54   && (flags&SQLIT
8c20: 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 29 20  E_OPEN_MAIN_DB) 
8c30: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 4c 6f  ){.          pLo
8c40: 63 6b 2d 3e 70 46 69 6c 65 20 3d 20 28 73 71 6c  ck->pFile = (sql
8c50: 69 74 65 33 5f 66 69 6c 65 20 2a 29 26 70 4c 6f  ite3_file *)&pLo
8c60: 63 6b 5b 31 5d 3b 0a 20 20 20 20 20 20 20 20 20  ck[1];.         
8c70: 20 72 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65   rc = pVfs->xOpe
8c80: 6e 28 70 56 66 73 2c 20 70 44 61 74 61 2d 3e 7a  n(pVfs, pData->z
8c90: 4e 61 6d 65 2c 20 70 4c 6f 63 6b 2d 3e 70 46 69  Name, pLock->pFi
8ca0: 6c 65 2c 20 66 6c 61 67 73 2c 20 30 29 3b 0a 20  le, flags, 0);. 
8cb0: 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63 21           if( rc!
8cc0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
8cd0: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
8ce0: 33 5f 66 72 65 65 28 70 4c 6f 63 6b 29 3b 0a 20  3_free(pLock);. 
8cf0: 20 20 20 20 20 20 20 20 20 20 20 70 4c 6f 63 6b             pLock
8d00: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20   = 0;.          
8d10: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
8d20: 20 20 20 20 69 66 28 20 70 4c 6f 63 6b 20 29 7b      if( pLock ){
8d30: 0a 20 20 20 20 20 20 20 20 20 20 70 4c 6f 63 6b  .          pLock
8d40: 2d 3e 6e 46 69 6c 65 20 3d 20 70 44 61 74 61 2d  ->nFile = pData-
8d50: 3e 6e 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20 20  >nName;.        
8d60: 20 20 70 4c 6f 63 6b 2d 3e 7a 46 69 6c 65 20 3d    pLock->zFile =
8d70: 20 26 28 28 63 68 61 72 20 2a 29 28 26 70 4c 6f   &((char *)(&pLo
8d80: 63 6b 5b 31 5d 29 29 5b 70 56 66 73 2d 3e 73 7a  ck[1]))[pVfs->sz
8d90: 4f 73 46 69 6c 65 5d 3b 0a 20 20 20 20 20 20 20  OsFile];.       
8da0: 20 20 20 6d 65 6d 63 70 79 28 70 4c 6f 63 6b 2d     memcpy(pLock-
8db0: 3e 7a 46 69 6c 65 2c 20 70 44 61 74 61 2d 3e 7a  >zFile, pData->z
8dc0: 4e 61 6d 65 2c 20 70 4c 6f 63 6b 2d 3e 6e 46 69  Name, pLock->nFi
8dd0: 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70  le);.          p
8de0: 4c 6f 63 6b 2d 3e 70 4e 65 78 74 20 3d 20 61 73  Lock->pNext = as
8df0: 79 6e 63 2e 70 4c 6f 63 6b 3b 0a 20 20 20 20 20  ync.pLock;.     
8e00: 20 20 20 20 20 61 73 79 6e 63 2e 70 4c 6f 63 6b       async.pLock
8e10: 20 3d 20 70 4c 6f 63 6b 3b 0a 20 20 20 20 20 20   = pLock;.      
8e20: 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b    }.      }else{
8e30: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
8e40: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
8e50: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
8e60: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
8e70: 4f 4b 20 29 7b 0a 20 20 20 20 70 2d 3e 70 4d 65  OK ){.    p->pMe
8e80: 74 68 6f 64 20 3d 20 26 61 73 79 6e 63 5f 6d 65  thod = &async_me
8e90: 74 68 6f 64 73 3b 0a 20 20 20 20 70 2d 3e 70 44  thods;.    p->pD
8ea0: 61 74 61 20 3d 20 70 44 61 74 61 3b 0a 0a 20 20  ata = pData;..  
8eb0: 20 20 2f 2a 20 4c 69 6e 6b 20 41 73 79 6e 63 46    /* Link AsyncF
8ec0: 69 6c 65 44 61 74 61 2e 6c 6f 63 6b 20 69 6e 74  ileData.lock int
8ed0: 6f 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73  o the linked lis
8ee0: 74 20 6f 66 20 0a 20 20 20 20 2a 2a 20 41 73 79  t of .    ** Asy
8ef0: 6e 63 46 69 6c 65 4c 6f 63 6b 20 73 74 72 75 63  ncFileLock struc
8f00: 74 75 72 65 73 20 66 6f 72 20 74 68 69 73 20 66  tures for this f
8f10: 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ile..    */.    
8f20: 69 66 28 20 7a 4e 61 6d 65 20 29 7b 0a 20 20 20  if( zName ){.   
8f30: 20 20 20 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e 70     pData->lock.p
8f40: 4e 65 78 74 20 3d 20 70 4c 6f 63 6b 2d 3e 70 4c  Next = pLock->pL
8f50: 69 73 74 3b 0a 20 20 20 20 20 20 70 4c 6f 63 6b  ist;.      pLock
8f60: 2d 3e 70 4c 69 73 74 20 3d 20 26 70 44 61 74 61  ->pList = &pData
8f70: 2d 3e 6c 6f 63 6b 3b 0a 20 20 20 20 20 20 70 44  ->lock;.      pD
8f80: 61 74 61 2d 3e 7a 4e 61 6d 65 20 3d 20 70 4c 6f  ata->zName = pLo
8f90: 63 6b 2d 3e 7a 46 69 6c 65 3b 0a 20 20 20 20 7d  ck->zFile;.    }
8fa0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66  .  }else{.    if
8fb0: 28 20 70 44 61 74 61 2d 3e 70 42 61 73 65 52 65  ( pData->pBaseRe
8fc0: 61 64 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b 0a  ad->pMethods ){.
8fd0: 20 20 20 20 20 20 70 44 61 74 61 2d 3e 70 42 61        pData->pBa
8fe0: 73 65 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73  seRead->pMethods
8ff0: 2d 3e 78 43 6c 6f 73 65 28 70 44 61 74 61 2d 3e  ->xClose(pData->
9000: 70 42 61 73 65 52 65 61 64 29 3b 0a 20 20 20 20  pBaseRead);.    
9010: 7d 0a 20 20 20 20 69 66 28 20 70 44 61 74 61 2d  }.    if( pData-
9020: 3e 70 42 61 73 65 57 72 69 74 65 2d 3e 70 4d 65  >pBaseWrite->pMe
9030: 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 20 20 70  thods ){.      p
9040: 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74 65  Data->pBaseWrite
9050: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f  ->pMethods->xClo
9060: 73 65 28 70 44 61 74 61 2d 3e 70 42 61 73 65 57  se(pData->pBaseW
9070: 72 69 74 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20  rite);.    }.   
9080: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 44   sqlite3_free(pD
9090: 61 74 61 29 3b 0a 20 20 7d 0a 0a 20 20 61 73 79  ata);.  }..  asy
90a0: 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41  nc_mutex_leave(A
90b0: 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b 29  SYNC_MUTEX_LOCK)
90c0: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
90d0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 44  ITE_OK ){.    pD
90e0: 61 74 61 2d 3e 70 4c 6f 63 6b 20 3d 20 70 4c 6f  ata->pLock = pLo
90f0: 63 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  ck;.  }..  if( r
9100: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
9110: 69 73 41 73 79 6e 63 4f 70 65 6e 20 29 7b 0a 20  isAsyncOpen ){. 
9120: 20 20 20 72 63 20 3d 20 61 64 64 4e 65 77 41 73     rc = addNewAs
9130: 79 6e 63 57 72 69 74 65 28 70 44 61 74 61 2c 20  yncWrite(pData, 
9140: 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53  ASYNC_OPENEXCLUS
9150: 49 56 45 2c 20 28 73 71 6c 69 74 65 33 5f 69 6e  IVE, (sqlite3_in
9160: 74 36 34 29 66 6c 61 67 73 2c 30 2c 30 29 3b 0a  t64)flags,0,0);.
9170: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
9180: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69  TE_OK ){.      i
9190: 66 28 20 70 4f 75 74 46 6c 61 67 73 20 29 20 2a  f( pOutFlags ) *
91a0: 70 4f 75 74 46 6c 61 67 73 20 3d 20 66 6c 61 67  pOutFlags = flag
91b0: 73 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  s;.    }else{.  
91c0: 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f      async_mutex_
91d0: 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54 45  enter(ASYNC_MUTE
91e0: 58 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20 75  X_LOCK);.      u
91f0: 6e 6c 69 6e 6b 41 73 79 6e 63 46 69 6c 65 28 70  nlinkAsyncFile(p
9200: 44 61 74 61 29 3b 0a 20 20 20 20 20 20 61 73 79  Data);.      asy
9210: 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41  nc_mutex_leave(A
9220: 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b 29  SYNC_MUTEX_LOCK)
9230: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
9240: 66 72 65 65 28 70 44 61 74 61 29 3b 0a 20 20 20  free(pData);.   
9250: 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21   }.  }.  if( rc!
9260: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
9270: 20 20 70 2d 3e 70 4d 65 74 68 6f 64 20 3d 20 30    p->pMethod = 0
9280: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
9290: 6e 63 72 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74  ncrOpenFileCount
92a0: 28 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  ();.  }..  retur
92b0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  n rc;.}../*.** I
92c0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
92d0: 20 73 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65   sqlite3OsDelete
92e0: 2e 20 41 64 64 20 61 6e 20 65 6e 74 72 79 20 74  . Add an entry t
92f0: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  o the end of the
9300: 20 0a 2a 2a 20 77 72 69 74 65 2d 6f 70 20 71 75   .** write-op qu
9310: 65 75 65 20 74 6f 20 70 65 72 66 6f 72 6d 20 74  eue to perform t
9320: 68 65 20 64 65 6c 65 74 65 2e 0a 2a 2f 0a 73 74  he delete..*/.st
9330: 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 44 65  atic int asyncDe
9340: 6c 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73  lete(sqlite3_vfs
9350: 20 2a 70 41 73 79 6e 63 56 66 73 2c 20 63 6f 6e   *pAsyncVfs, con
9360: 73 74 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20  st char *z, int 
9370: 73 79 6e 63 44 69 72 29 7b 0a 20 20 55 4e 55 53  syncDir){.  UNUS
9380: 45 44 5f 50 41 52 41 4d 45 54 45 52 28 70 41 73  ED_PARAMETER(pAs
9390: 79 6e 63 56 66 73 29 3b 0a 20 20 72 65 74 75 72  yncVfs);.  retur
93a0: 6e 20 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69  n addNewAsyncWri
93b0: 74 65 28 30 2c 20 41 53 59 4e 43 5f 44 45 4c 45  te(0, ASYNC_DELE
93c0: 54 45 2c 20 73 79 6e 63 44 69 72 2c 20 28 69 6e  TE, syncDir, (in
93d0: 74 29 73 74 72 6c 65 6e 28 7a 29 2b 31 2c 20 7a  t)strlen(z)+1, z
93e0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
93f0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 71  ementation of sq
9400: 6c 69 74 65 33 4f 73 41 63 63 65 73 73 2e 20 54  lite3OsAccess. T
9410: 68 69 73 20 6d 65 74 68 6f 64 20 68 6f 6c 64 73  his method holds
9420: 20 74 68 65 20 6d 75 74 65 78 20 66 72 6f 6d 0a   the mutex from.
9430: 2a 2a 20 73 74 61 72 74 20 74 6f 20 66 69 6e 69  ** start to fini
9440: 73 68 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  sh..*/.static in
9450: 74 20 61 73 79 6e 63 41 63 63 65 73 73 28 0a 20  t asyncAccess(. 
9460: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 41   sqlite3_vfs *pA
9470: 73 79 6e 63 56 66 73 2c 20 0a 20 20 63 6f 6e 73  syncVfs, .  cons
9480: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 0a  t char *zName, .
9490: 20 20 69 6e 74 20 66 6c 61 67 73 2c 0a 20 20 69    int flags,.  i
94a0: 6e 74 20 2a 70 52 65 73 4f 75 74 0a 29 7b 0a 20  nt *pResOut.){. 
94b0: 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 72   int rc;.  int r
94c0: 65 74 3b 0a 20 20 41 73 79 6e 63 57 72 69 74 65  et;.  AsyncWrite
94d0: 20 2a 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76   *p;.  sqlite3_v
94e0: 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71 6c 69  fs *pVfs = (sqli
94f0: 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79 6e 63  te3_vfs *)pAsync
9500: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a  Vfs->pAppData;..
9510: 20 20 61 73 73 65 72 74 28 66 6c 61 67 73 3d 3d    assert(flags==
9520: 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f 52 45  SQLITE_ACCESS_RE
9530: 41 44 57 52 49 54 45 20 0a 20 20 20 20 20 20 7c  ADWRITE .      |
9540: 7c 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f  | flags==SQLITE_
9550: 41 43 43 45 53 53 5f 52 45 41 44 20 0a 20 20 20  ACCESS_READ .   
9560: 20 20 20 7c 7c 20 66 6c 61 67 73 3d 3d 53 51 4c     || flags==SQL
9570: 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53 54  ITE_ACCESS_EXIST
9580: 53 20 0a 20 20 29 3b 0a 0a 20 20 61 73 79 6e 63  S .  );..  async
9590: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59  _mutex_enter(ASY
95a0: 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b  NC_MUTEX_QUEUE);
95b0: 0a 20 20 72 63 20 3d 20 70 56 66 73 2d 3e 78 41  .  rc = pVfs->xA
95c0: 63 63 65 73 73 28 70 56 66 73 2c 20 7a 4e 61 6d  ccess(pVfs, zNam
95d0: 65 2c 20 66 6c 61 67 73 2c 20 26 72 65 74 29 3b  e, flags, &ret);
95e0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
95f0: 45 5f 4f 4b 20 26 26 20 66 6c 61 67 73 3d 3d 53  E_OK && flags==S
9600: 51 4c 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49  QLITE_ACCESS_EXI
9610: 53 54 53 20 29 7b 0a 20 20 20 20 66 6f 72 28 70  STS ){.    for(p
9620: 3d 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72  =async.pQueueFir
9630: 73 74 3b 20 70 3b 20 70 20 3d 20 70 2d 3e 70 4e  st; p; p = p->pN
9640: 65 78 74 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ext){.      if( 
9650: 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f 44 45 4c  p->op==ASYNC_DEL
9660: 45 54 45 20 26 26 20 30 3d 3d 73 74 72 63 6d 70  ETE && 0==strcmp
9670: 28 70 2d 3e 7a 42 75 66 2c 20 7a 4e 61 6d 65 29  (p->zBuf, zName)
9680: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 20   ){.        ret 
9690: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  = 0;.      }else
96a0: 20 69 66 28 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e   if( p->op==ASYN
96b0: 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56 45 20  C_OPENEXCLUSIVE 
96c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 26 26  .             &&
96d0: 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a   p->pFileData->z
96e0: 4e 61 6d 65 0a 20 20 20 20 20 20 20 20 20 20 20  Name.           
96f0: 20 20 26 26 20 30 3d 3d 73 74 72 63 6d 70 28 70    && 0==strcmp(p
9700: 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61  ->pFileData->zNa
9710: 6d 65 2c 20 7a 4e 61 6d 65 29 20 0a 20 20 20 20  me, zName) .    
9720: 20 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74    ){.        ret
9730: 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 1;.      }.  
9740: 20 20 7d 0a 20 20 7d 0a 20 20 41 53 59 4e 43 5f    }.  }.  ASYNC_
9750: 54 52 41 43 45 28 28 22 41 43 43 45 53 53 28 25  TRACE(("ACCESS(%
9760: 73 29 3a 20 25 73 20 3d 20 25 64 5c 6e 22 2c 20  s): %s = %d\n", 
9770: 0a 20 20 20 20 66 6c 61 67 73 3d 3d 53 51 4c 49  .    flags==SQLI
9780: 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52  TE_ACCESS_READWR
9790: 49 54 45 3f 22 72 65 61 64 2d 77 72 69 74 65 22  ITE?"read-write"
97a0: 3a 0a 20 20 20 20 66 6c 61 67 73 3d 3d 53 51 4c  :.    flags==SQL
97b0: 49 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44 3f  ITE_ACCESS_READ?
97c0: 22 72 65 61 64 22 3a 22 65 78 69 73 74 73 22 0a  "read":"exists".
97d0: 20 20 20 20 2c 20 7a 4e 61 6d 65 2c 20 72 65 74      , zName, ret
97e0: 29 0a 20 20 29 3b 0a 20 20 61 73 79 6e 63 5f 6d  ).  );.  async_m
97f0: 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59 4e 43  utex_leave(ASYNC
9800: 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b 0a 20  _MUTEX_QUEUE);. 
9810: 20 2a 70 52 65 73 4f 75 74 20 3d 20 72 65 74 3b   *pResOut = ret;
9820: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
9830: 0a 2f 2a 0a 2a 2a 20 46 69 6c 6c 20 69 6e 20 7a  ./*.** Fill in z
9840: 50 61 74 68 4f 75 74 20 77 69 74 68 20 74 68 65  PathOut with the
9850: 20 66 75 6c 6c 20 70 61 74 68 20 74 6f 20 74 68   full path to th
9860: 65 20 66 69 6c 65 20 69 64 65 6e 74 69 66 69 65  e file identifie
9870: 64 20 62 79 20 7a 50 61 74 68 2e 0a 2a 2f 0a 73  d by zPath..*/.s
9880: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 46  tatic int asyncF
9890: 75 6c 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 73  ullPathname(.  s
98a0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 41 73 79  qlite3_vfs *pAsy
98b0: 6e 63 56 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20  ncVfs, .  const 
98c0: 63 68 61 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20  char *zPath, .  
98d0: 69 6e 74 20 6e 50 61 74 68 4f 75 74 2c 0a 20 20  int nPathOut,.  
98e0: 63 68 61 72 20 2a 7a 50 61 74 68 4f 75 74 0a 29  char *zPathOut.)
98f0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71  {.  int rc;.  sq
9900: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20  lite3_vfs *pVfs 
9910: 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  = (sqlite3_vfs *
9920: 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70  )pAsyncVfs->pApp
9930: 44 61 74 61 3b 0a 20 20 72 63 20 3d 20 70 56 66  Data;.  rc = pVf
9940: 73 2d 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65  s->xFullPathname
9950: 28 70 56 66 73 2c 20 7a 50 61 74 68 2c 20 6e 50  (pVfs, zPath, nP
9960: 61 74 68 4f 75 74 2c 20 7a 50 61 74 68 4f 75 74  athOut, zPathOut
9970: 29 3b 0a 0a 20 20 2f 2a 20 42 65 63 61 75 73 65  );..  /* Because
9980: 20 6f 66 20 74 68 65 20 77 61 79 20 69 6e 74 72   of the way intr
9990: 61 2d 70 72 6f 63 65 73 73 20 66 69 6c 65 20 6c  a-process file l
99a0: 6f 63 6b 69 6e 67 20 77 6f 72 6b 73 2c 20 74 68  ocking works, th
99b0: 69 73 20 62 61 63 6b 65 6e 64 0a 20 20 2a 2a 20  is backend.  ** 
99c0: 6e 65 65 64 73 20 74 6f 20 72 65 74 75 72 6e 20  needs to return 
99d0: 61 20 63 61 6e 6f 6e 69 63 61 6c 20 70 61 74 68  a canonical path
99e0: 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  . The following 
99f0: 62 6c 6f 63 6b 20 61 73 73 75 6d 65 73 20 74 68  block assumes th
9a00: 65 0a 20 20 2a 2a 20 66 69 6c 65 2d 73 79 73 74  e.  ** file-syst
9a10: 65 6d 20 75 73 65 73 20 75 6e 69 78 20 73 74 79  em uses unix sty
9a20: 6c 65 20 70 61 74 68 73 2e 20 0a 20 20 2a 2f 0a  le paths. .  */.
9a30: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
9a40: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  _OK ){.    int i
9a50: 2c 20 6a 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  , j;.    char *z
9a60: 20 3d 20 7a 50 61 74 68 4f 75 74 3b 0a 20 20 20   = zPathOut;.   
9a70: 20 69 6e 74 20 6e 20 3d 20 28 69 6e 74 29 73 74   int n = (int)st
9a80: 72 6c 65 6e 28 7a 29 3b 0a 20 20 20 20 77 68 69  rlen(z);.    whi
9a90: 6c 65 28 20 6e 3e 31 20 26 26 20 7a 5b 6e 2d 31  le( n>1 && z[n-1
9aa0: 5d 3d 3d 27 2f 27 20 29 7b 20 6e 2d 2d 3b 20 7d  ]=='/' ){ n--; }
9ab0: 0a 20 20 20 20 66 6f 72 28 69 3d 6a 3d 30 3b 20  .    for(i=j=0; 
9ac0: 69 3c 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  i<n; i++){.     
9ad0: 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 2f 27 20 29   if( z[i]=='/' )
9ae0: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b  {.        if( z[
9af0: 69 2b 31 5d 3d 3d 27 2f 27 20 29 20 63 6f 6e 74  i+1]=='/' ) cont
9b00: 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 69 66  inue;.        if
9b10: 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 26 26  ( z[i+1]=='.' &&
9b20: 20 69 2b 32 3c 6e 20 26 26 20 7a 5b 69 2b 32 5d   i+2<n && z[i+2]
9b30: 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 20  =='/' ){.       
9b40: 20 20 20 69 20 2b 3d 20 31 3b 0a 20 20 20 20 20     i += 1;.     
9b50: 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20       continue;. 
9b60: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
9b70: 20 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27   if( z[i+1]=='.'
9b80: 20 26 26 20 69 2b 33 3c 6e 20 26 26 20 7a 5b 69   && i+3<n && z[i
9b90: 2b 32 5d 3d 3d 27 2e 27 20 26 26 20 7a 5b 69 2b  +2]=='.' && z[i+
9ba0: 33 5d 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20  3]=='/' ){.     
9bb0: 20 20 20 20 20 77 68 69 6c 65 28 20 6a 3e 30 20       while( j>0 
9bc0: 26 26 20 7a 5b 6a 2d 31 5d 21 3d 27 2f 27 20 29  && z[j-1]!='/' )
9bd0: 7b 20 6a 2d 2d 3b 20 7d 0a 20 20 20 20 20 20 20  { j--; }.       
9be0: 20 20 20 69 66 28 20 6a 3e 30 20 29 7b 20 6a 2d     if( j>0 ){ j-
9bf0: 2d 3b 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69  -; }.          i
9c00: 20 2b 3d 20 32 3b 0a 20 20 20 20 20 20 20 20 20   += 2;.         
9c10: 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20   continue;.     
9c20: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
9c30: 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d     z[j++] = z[i]
9c40: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 5b 6a 5d  ;.    }.    z[j]
9c50: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74   = 0;.  }..  ret
9c60: 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63  urn rc;.}.static
9c70: 20 76 6f 69 64 20 2a 61 73 79 6e 63 44 6c 4f 70   void *asyncDlOp
9c80: 65 6e 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  en(sqlite3_vfs *
9c90: 70 41 73 79 6e 63 56 66 73 2c 20 63 6f 6e 73 74  pAsyncVfs, const
9ca0: 20 63 68 61 72 20 2a 7a 50 61 74 68 29 7b 0a 20   char *zPath){. 
9cb0: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
9cc0: 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66  fs = (sqlite3_vf
9cd0: 73 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70  s *)pAsyncVfs->p
9ce0: 41 70 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72  AppData;.  retur
9cf0: 6e 20 70 56 66 73 2d 3e 78 44 6c 4f 70 65 6e 28  n pVfs->xDlOpen(
9d00: 70 56 66 73 2c 20 7a 50 61 74 68 29 3b 0a 7d 0a  pVfs, zPath);.}.
9d10: 73 74 61 74 69 63 20 76 6f 69 64 20 61 73 79 6e  static void asyn
9d20: 63 44 6c 45 72 72 6f 72 28 73 71 6c 69 74 65 33  cDlError(sqlite3
9d30: 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66 73 2c  _vfs *pAsyncVfs,
9d40: 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72   int nByte, char
9d50: 20 2a 7a 45 72 72 4d 73 67 29 7b 0a 20 20 73 71   *zErrMsg){.  sq
9d60: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20  lite3_vfs *pVfs 
9d70: 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  = (sqlite3_vfs *
9d80: 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70  )pAsyncVfs->pApp
9d90: 44 61 74 61 3b 0a 20 20 70 56 66 73 2d 3e 78 44  Data;.  pVfs->xD
9da0: 6c 45 72 72 6f 72 28 70 56 66 73 2c 20 6e 42 79  lError(pVfs, nBy
9db0: 74 65 2c 20 7a 45 72 72 4d 73 67 29 3b 0a 7d 0a  te, zErrMsg);.}.
9dc0: 73 74 61 74 69 63 20 76 6f 69 64 20 28 2a 61 73  static void (*as
9dd0: 79 6e 63 44 6c 53 79 6d 28 0a 20 20 73 71 6c 69  yncDlSym(.  sqli
9de0: 74 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56  te3_vfs *pAsyncV
9df0: 66 73 2c 20 0a 20 20 76 6f 69 64 20 2a 70 48 61  fs, .  void *pHa
9e00: 6e 64 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20 63  ndle, .  const c
9e10: 68 61 72 20 2a 7a 53 79 6d 62 6f 6c 0a 29 29 28  har *zSymbol.))(
9e20: 76 6f 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33  void){.  sqlite3
9e30: 5f 76 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71  _vfs *pVfs = (sq
9e40: 6c 69 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79  lite3_vfs *)pAsy
9e50: 6e 63 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  ncVfs->pAppData;
9e60: 0a 20 20 72 65 74 75 72 6e 20 70 56 66 73 2d 3e  .  return pVfs->
9e70: 78 44 6c 53 79 6d 28 70 56 66 73 2c 20 70 48 61  xDlSym(pVfs, pHa
9e80: 6e 64 6c 65 2c 20 7a 53 79 6d 62 6f 6c 29 3b 0a  ndle, zSymbol);.
9e90: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 73  }.static void as
9ea0: 79 6e 63 44 6c 43 6c 6f 73 65 28 73 71 6c 69 74  yncDlClose(sqlit
9eb0: 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66  e3_vfs *pAsyncVf
9ec0: 73 2c 20 76 6f 69 64 20 2a 70 48 61 6e 64 6c 65  s, void *pHandle
9ed0: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  ){.  sqlite3_vfs
9ee0: 20 2a 70 56 66 73 20 3d 20 28 73 71 6c 69 74 65   *pVfs = (sqlite
9ef0: 33 5f 76 66 73 20 2a 29 70 41 73 79 6e 63 56 66  3_vfs *)pAsyncVf
9f00: 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 70  s->pAppData;.  p
9f10: 56 66 73 2d 3e 78 44 6c 43 6c 6f 73 65 28 70 56  Vfs->xDlClose(pV
9f20: 66 73 2c 20 70 48 61 6e 64 6c 65 29 3b 0a 7d 0a  fs, pHandle);.}.
9f30: 73 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63  static int async
9f40: 52 61 6e 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74  Randomness(sqlit
9f50: 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66  e3_vfs *pAsyncVf
9f60: 73 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68  s, int nByte, ch
9f70: 61 72 20 2a 7a 42 75 66 4f 75 74 29 7b 0a 20 20  ar *zBufOut){.  
9f80: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
9f90: 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73  s = (sqlite3_vfs
9fa0: 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41   *)pAsyncVfs->pA
9fb0: 70 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72 6e  ppData;.  return
9fc0: 20 70 56 66 73 2d 3e 78 52 61 6e 64 6f 6d 6e 65   pVfs->xRandomne
9fd0: 73 73 28 70 56 66 73 2c 20 6e 42 79 74 65 2c 20  ss(pVfs, nByte, 
9fe0: 7a 42 75 66 4f 75 74 29 3b 0a 7d 0a 73 74 61 74  zBufOut);.}.stat
9ff0: 69 63 20 69 6e 74 20 61 73 79 6e 63 53 6c 65 65  ic int asyncSlee
a000: 70 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  p(sqlite3_vfs *p
a010: 41 73 79 6e 63 56 66 73 2c 20 69 6e 74 20 6e 4d  AsyncVfs, int nM
a020: 69 63 72 6f 29 7b 0a 20 20 73 71 6c 69 74 65 33  icro){.  sqlite3
a030: 5f 76 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71  _vfs *pVfs = (sq
a040: 6c 69 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79  lite3_vfs *)pAsy
a050: 6e 63 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  ncVfs->pAppData;
a060: 0a 20 20 72 65 74 75 72 6e 20 70 56 66 73 2d 3e  .  return pVfs->
a070: 78 53 6c 65 65 70 28 70 56 66 73 2c 20 6e 4d 69  xSleep(pVfs, nMi
a080: 63 72 6f 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  cro);.}.static i
a090: 6e 74 20 61 73 79 6e 63 43 75 72 72 65 6e 74 54  nt asyncCurrentT
a0a0: 69 6d 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ime(sqlite3_vfs 
a0b0: 2a 70 41 73 79 6e 63 56 66 73 2c 20 64 6f 75 62  *pAsyncVfs, doub
a0c0: 6c 65 20 2a 70 54 69 6d 65 4f 75 74 29 7b 0a 20  le *pTimeOut){. 
a0d0: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
a0e0: 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66  fs = (sqlite3_vf
a0f0: 73 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70  s *)pAsyncVfs->p
a100: 41 70 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72  AppData;.  retur
a110: 6e 20 70 56 66 73 2d 3e 78 43 75 72 72 65 6e 74  n pVfs->xCurrent
a120: 54 69 6d 65 28 70 56 66 73 2c 20 70 54 69 6d 65  Time(pVfs, pTime
a130: 4f 75 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  Out);.}..static 
a140: 73 71 6c 69 74 65 33 5f 76 66 73 20 61 73 79 6e  sqlite3_vfs asyn
a150: 63 5f 76 66 73 20 3d 20 7b 0a 20 20 31 2c 20 20  c_vfs = {.  1,  
a160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a170: 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f    /* iVersion */
a180: 0a 20 20 73 69 7a 65 6f 66 28 41 73 79 6e 63 46  .  sizeof(AsyncF
a190: 69 6c 65 29 2c 20 20 20 20 2f 2a 20 73 7a 4f 73  ile),    /* szOs
a1a0: 46 69 6c 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20  File */.  0,    
a1b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a1c0: 2f 2a 20 6d 78 50 61 74 68 6e 61 6d 65 20 2a 2f  /* mxPathname */
a1d0: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
a1e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 70 4e 65 78           /* pNex
a1f0: 74 20 2a 2f 0a 20 20 53 51 4c 49 54 45 41 53 59  t */.  SQLITEASY
a200: 4e 43 5f 56 46 53 4e 41 4d 45 2c 20 20 2f 2a 20  NC_VFSNAME,  /* 
a210: 7a 4e 61 6d 65 20 2a 2f 0a 20 20 30 2c 20 20 20  zName */.  0,   
a220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a230: 20 2f 2a 20 70 41 70 70 44 61 74 61 20 2a 2f 0a   /* pAppData */.
a240: 20 20 61 73 79 6e 63 4f 70 65 6e 2c 20 20 20 20    asyncOpen,    
a250: 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e          /* xOpen
a260: 20 2a 2f 0a 20 20 61 73 79 6e 63 44 65 6c 65 74   */.  asyncDelet
a270: 65 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  e,          /* x
a280: 44 65 6c 65 74 65 20 2a 2f 0a 20 20 61 73 79 6e  Delete */.  asyn
a290: 63 41 63 63 65 73 73 2c 20 20 20 20 20 20 20 20  cAccess,        
a2a0: 20 20 2f 2a 20 78 41 63 63 65 73 73 20 2a 2f 0a    /* xAccess */.
a2b0: 20 20 61 73 79 6e 63 46 75 6c 6c 50 61 74 68 6e    asyncFullPathn
a2c0: 61 6d 65 2c 20 20 20 20 2f 2a 20 78 46 75 6c 6c  ame,    /* xFull
a2d0: 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 61 73  Pathname */.  as
a2e0: 79 6e 63 44 6c 4f 70 65 6e 2c 20 20 20 20 20 20  yncDlOpen,      
a2f0: 20 20 20 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a      /* xDlOpen *
a300: 2f 0a 20 20 61 73 79 6e 63 44 6c 45 72 72 6f 72  /.  asyncDlError
a310: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c  ,         /* xDl
a320: 45 72 72 6f 72 20 2a 2f 0a 20 20 61 73 79 6e 63  Error */.  async
a330: 44 6c 53 79 6d 2c 20 20 20 20 20 20 20 20 20 20  DlSym,          
a340: 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20 20   /* xDlSym */.  
a350: 61 73 79 6e 63 44 6c 43 6c 6f 73 65 2c 20 20 20  asyncDlClose,   
a360: 20 20 20 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73        /* xDlClos
a370: 65 20 2a 2f 0a 20 20 61 73 79 6e 63 52 61 6e 64  e */.  asyncRand
a380: 6f 6d 6e 65 73 73 2c 20 20 20 20 20 20 2f 2a 20  omness,      /* 
a390: 78 44 6c 45 72 72 6f 72 20 2a 2f 0a 20 20 61 73  xDlError */.  as
a3a0: 79 6e 63 53 6c 65 65 70 2c 20 20 20 20 20 20 20  yncSleep,       
a3b0: 20 20 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f      /* xDlSym */
a3c0: 0a 20 20 61 73 79 6e 63 43 75 72 72 65 6e 74 54  .  asyncCurrentT
a3d0: 69 6d 65 20 20 20 20 20 20 2f 2a 20 78 44 6c 43  ime      /* xDlC
a3e0: 6c 6f 73 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 0a  lose */.};../* .
a3f0: 2a 2a 20 54 68 69 73 20 70 72 6f 63 65 64 75 72  ** This procedur
a400: 65 20 72 75 6e 73 20 69 6e 20 61 20 73 65 70 61  e runs in a sepa
a410: 72 61 74 65 20 74 68 72 65 61 64 2c 20 72 65 61  rate thread, rea
a420: 64 69 6e 67 20 6d 65 73 73 61 67 65 73 20 6f 66  ding messages of
a430: 66 20 6f 66 20 74 68 65 0a 2a 2a 20 77 72 69 74  f of the.** writ
a440: 65 20 71 75 65 75 65 20 61 6e 64 20 70 72 6f 63  e queue and proc
a450: 65 73 73 69 6e 67 20 74 68 65 6d 20 6f 6e 65 20  essing them one 
a460: 62 79 20 6f 6e 65 2e 20 20 0a 2a 2a 0a 2a 2a 20  by one.  .**.** 
a470: 49 66 20 61 73 79 6e 63 2e 77 72 69 74 65 72 48  If async.writerH
a480: 61 6c 74 4e 6f 77 20 69 73 20 74 72 75 65 2c 20  altNow is true, 
a490: 74 68 65 6e 20 74 68 69 73 20 70 72 6f 63 65 64  then this proced
a4a0: 75 72 65 20 65 78 69 74 73 0a 2a 2a 20 61 66 74  ure exits.** aft
a4b0: 65 72 20 70 72 6f 63 65 73 73 69 6e 67 20 61 20  er processing a 
a4c0: 73 69 6e 67 6c 65 20 6d 65 73 73 61 67 65 2e 0a  single message..
a4d0: 2a 2a 0a 2a 2a 20 49 66 20 61 73 79 6e 63 2e 77  **.** If async.w
a4e0: 72 69 74 65 72 48 61 6c 74 57 68 65 6e 49 64 6c  riterHaltWhenIdl
a4f0: 65 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20  e is true, then 
a500: 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 65  this procedure e
a510: 78 69 74 73 20 77 68 65 6e 0a 2a 2a 20 74 68 65  xits when.** the
a520: 20 77 72 69 74 65 20 71 75 65 75 65 20 69 73 20   write queue is 
a530: 65 6d 70 74 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  empty..**.** If 
a540: 62 6f 74 68 20 6f 66 20 74 68 65 20 61 62 6f 76  both of the abov
a550: 65 20 76 61 72 69 61 62 6c 65 73 20 61 72 65 20  e variables are 
a560: 66 61 6c 73 65 2c 20 74 68 69 73 20 70 72 6f 63  false, this proc
a570: 65 64 75 72 65 20 72 75 6e 73 0a 2a 2a 20 69 6e  edure runs.** in
a580: 64 65 66 69 6e 61 74 65 6c 79 2c 20 77 61 69 74  definately, wait
a590: 69 6e 67 20 66 6f 72 20 6f 70 65 72 61 74 69 6f  ing for operatio
a5a0: 6e 73 20 74 6f 20 62 65 20 61 64 64 65 64 20 74  ns to be added t
a5b0: 6f 20 74 68 65 20 77 72 69 74 65 20 71 75 65 75  o the write queu
a5c0: 65 0a 2a 2a 20 61 6e 64 20 70 72 6f 63 65 73 73  e.** and process
a5d0: 69 6e 67 20 74 68 65 6d 20 69 6e 20 74 68 65 20  ing them in the 
a5e0: 6f 72 64 65 72 20 69 6e 20 77 68 69 63 68 20 74  order in which t
a5f0: 68 65 79 20 61 72 72 69 76 65 2e 0a 2a 2a 0a 2a  hey arrive..**.*
a600: 2a 20 41 6e 20 61 72 74 69 66 69 63 61 6c 20 64  * An artifical d
a610: 65 6c 61 79 20 6f 66 20 61 73 79 6e 63 2e 69 6f  elay of async.io
a620: 44 65 6c 61 79 20 6d 69 6c 6c 69 73 65 63 6f 6e  Delay millisecon
a630: 64 73 20 69 73 20 69 6e 73 65 72 74 65 64 20 62  ds is inserted b
a640: 65 66 6f 72 65 0a 2a 2a 20 65 61 63 68 20 77 72  efore.** each wr
a650: 69 74 65 20 6f 70 65 72 61 74 69 6f 6e 20 69 6e  ite operation in
a660: 20 6f 72 64 65 72 20 74 6f 20 73 69 6d 75 6c 61   order to simula
a670: 74 65 20 74 68 65 20 65 66 66 65 63 74 20 6f 66  te the effect of
a680: 20 61 20 73 6c 6f 77 20 64 69 73 6b 2e 0a 2a 2a   a slow disk..**
a690: 0a 2a 2a 20 4f 6e 6c 79 20 6f 6e 65 20 69 6e 73  .** Only one ins
a6a0: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 70 72  tance of this pr
a6b0: 6f 63 65 64 75 72 65 20 6d 61 79 20 62 65 20 72  ocedure may be r
a6c0: 75 6e 6e 69 6e 67 20 61 74 20 61 20 74 69 6d 65  unning at a time
a6d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
a6e0: 20 61 73 79 6e 63 57 72 69 74 65 72 54 68 72 65   asyncWriterThre
a6f0: 61 64 28 76 6f 69 64 29 7b 0a 20 20 73 71 6c 69  ad(void){.  sqli
a700: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20 3d 20  te3_vfs *pVfs = 
a710: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 29 28  (sqlite3_vfs *)(
a720: 61 73 79 6e 63 5f 76 66 73 2e 70 41 70 70 44 61  async_vfs.pAppDa
a730: 74 61 29 3b 0a 20 20 41 73 79 6e 63 57 72 69 74  ta);.  AsyncWrit
a740: 65 20 2a 70 20 3d 20 30 3b 0a 20 20 69 6e 74 20  e *p = 0;.  int 
a750: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
a760: 20 20 69 6e 74 20 68 6f 6c 64 69 6e 67 4d 75 74    int holdingMut
a770: 65 78 20 3d 20 30 3b 0a 0a 20 20 61 73 79 6e 63  ex = 0;..  async
a780: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59  _mutex_enter(ASY
a790: 4e 43 5f 4d 55 54 45 58 5f 57 52 49 54 45 52 29  NC_MUTEX_WRITER)
a7a0: 3b 0a 0a 20 20 77 68 69 6c 65 28 20 61 73 79 6e  ;..  while( asyn
a7b0: 63 2e 65 48 61 6c 74 21 3d 53 51 4c 49 54 45 41  c.eHalt!=SQLITEA
a7c0: 53 59 4e 43 5f 48 41 4c 54 5f 4e 4f 57 20 29 7b  SYNC_HALT_NOW ){
a7d0: 0a 20 20 20 20 69 6e 74 20 64 6f 4e 6f 74 46 72  .    int doNotFr
a7e0: 65 65 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69  ee = 0;.    sqli
a7f0: 74 65 33 5f 66 69 6c 65 20 2a 70 42 61 73 65 20  te3_file *pBase 
a800: 3d 20 30 3b 0a 0a 20 20 20 20 69 66 28 20 21 68  = 0;..    if( !h
a810: 6f 6c 64 69 6e 67 4d 75 74 65 78 20 29 7b 0a 20  oldingMutex ){. 
a820: 20 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78       async_mutex
a830: 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54  _enter(ASYNC_MUT
a840: 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 7d  EX_QUEUE);.    }
a850: 0a 20 20 20 20 77 68 69 6c 65 28 20 28 70 20 3d  .    while( (p =
a860: 20 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72   async.pQueueFir
a870: 73 74 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  st)==0 ){.      
a880: 69 66 28 20 61 73 79 6e 63 2e 65 48 61 6c 74 21  if( async.eHalt!
a890: 3d 53 51 4c 49 54 45 41 53 59 4e 43 5f 48 41 4c  =SQLITEASYNC_HAL
a8a0: 54 5f 4e 45 56 45 52 20 29 7b 0a 20 20 20 20 20  T_NEVER ){.     
a8b0: 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c     async_mutex_l
a8c0: 65 61 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58  eave(ASYNC_MUTEX
a8d0: 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20 20 20  _QUEUE);.       
a8e0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65   break;.      }e
a8f0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 41 53 59  lse{.        ASY
a900: 4e 43 5f 54 52 41 43 45 28 28 22 49 44 4c 45 5c  NC_TRACE(("IDLE\
a910: 6e 22 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73  n"));.        as
a920: 79 6e 63 5f 63 6f 6e 64 5f 77 61 69 74 28 41 53  ync_cond_wait(AS
a930: 59 4e 43 5f 43 4f 4e 44 5f 51 55 45 55 45 2c 20  YNC_COND_QUEUE, 
a940: 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55  ASYNC_MUTEX_QUEU
a950: 45 29 3b 0a 20 20 20 20 20 20 20 20 41 53 59 4e  E);.        ASYN
a960: 43 5f 54 52 41 43 45 28 28 22 57 41 4b 45 55 50  C_TRACE(("WAKEUP
a970: 5c 6e 22 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20  \n"));.      }. 
a980: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 3d 3d     }.    if( p==
a990: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 68  0 ) break;.    h
a9a0: 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20 31 3b  oldingMutex = 1;
a9b0: 0a 0a 20 20 20 20 2f 2a 20 52 69 67 68 74 20 6e  ..    /* Right n
a9c0: 6f 77 20 74 68 69 73 20 74 68 72 65 61 64 20 69  ow this thread i
a9d0: 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 6d 75  s holding the mu
a9e0: 74 65 78 20 6f 6e 20 74 68 65 20 77 72 69 74 65  tex on the write
a9f0: 2d 6f 70 20 71 75 65 75 65 2e 0a 20 20 20 20 2a  -op queue..    *
aa00: 2a 20 56 61 72 69 61 62 6c 65 20 27 70 27 20 70  * Variable 'p' p
aa10: 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 66 69 72  oints to the fir
aa20: 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20  st entry in the 
aa30: 77 72 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 20  write-op queue. 
aa40: 49 6e 0a 20 20 20 20 2a 2a 20 74 68 65 20 67 65  In.    ** the ge
aa50: 6e 65 72 61 6c 20 63 61 73 65 2c 20 77 65 20 68  neral case, we h
aa60: 6f 6c 64 20 6f 6e 20 74 6f 20 74 68 65 20 6d 75  old on to the mu
aa70: 74 65 78 20 66 6f 72 20 74 68 65 20 65 6e 74 69  tex for the enti
aa80: 72 65 20 62 6f 64 79 20 6f 66 0a 20 20 20 20 2a  re body of.    *
aa90: 2a 20 74 68 65 20 6c 6f 6f 70 2e 20 0a 20 20 20  * the loop. .   
aaa0: 20 2a 2a 0a 20 20 20 20 2a 2a 20 48 6f 77 65 76   **.    ** Howev
aab0: 65 72 20 69 6e 20 74 68 65 20 63 61 73 65 73 20  er in the cases 
aac0: 65 6e 75 6d 65 72 61 74 65 64 20 62 65 6c 6f 77  enumerated below
aad0: 2c 20 77 65 20 72 65 6c 69 6e 71 75 69 73 68 20  , we relinquish 
aae0: 74 68 65 20 6d 75 74 65 78 2c 0a 20 20 20 20 2a  the mutex,.    *
aaf0: 2a 20 70 65 72 66 6f 72 6d 20 74 68 65 20 49 4f  * perform the IO
ab00: 2c 20 61 6e 64 20 74 68 65 6e 20 72 65 2d 72 65  , and then re-re
ab10: 71 75 65 73 74 20 74 68 65 20 6d 75 74 65 78 20  quest the mutex 
ab20: 62 65 66 6f 72 65 20 72 65 6d 6f 76 69 6e 67 20  before removing 
ab30: 27 70 27 20 66 72 6f 6d 0a 20 20 20 20 2a 2a 20  'p' from.    ** 
ab40: 74 68 65 20 68 65 61 64 20 6f 66 20 74 68 65 20  the head of the 
ab50: 77 72 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 20  write-op queue. 
ab60: 54 68 65 20 69 64 65 61 20 69 73 20 74 6f 20 69  The idea is to i
ab70: 6e 63 72 65 61 73 65 20 63 6f 6e 63 75 72 72 65  ncrease concurre
ab80: 6e 63 79 20 77 69 74 68 0a 20 20 20 20 2a 2a 20  ncy with.    ** 
ab90: 73 71 6c 69 74 65 20 74 68 72 65 61 64 73 2e 0a  sqlite threads..
aba0: 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20 20      **.    **   
abb0: 20 20 2a 20 41 6e 20 41 53 59 4e 43 5f 43 4c 4f    * An ASYNC_CLO
abc0: 53 45 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 20 20  SE operation..  
abd0: 20 20 2a 2a 20 20 20 20 20 2a 20 41 6e 20 41 53    **     * An AS
abe0: 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56  YNC_OPENEXCLUSIV
abf0: 45 20 6f 70 65 72 61 74 69 6f 6e 2e 20 46 6f 72  E operation. For
ac00: 20 74 68 69 73 20 6f 6e 65 2c 20 77 65 20 72 65   this one, we re
ac10: 6c 69 6e 71 75 69 73 68 20 0a 20 20 20 20 2a 2a  linquish .    **
ac20: 20 20 20 20 20 20 20 74 68 65 20 6d 75 74 65 78         the mutex
ac30: 2c 20 63 61 6c 6c 20 74 68 65 20 75 6e 64 65 72  , call the under
ac40: 6c 79 69 6e 67 20 78 4f 70 65 6e 45 78 63 6c 75  lying xOpenExclu
ac50: 73 69 76 65 28 29 20 66 75 6e 63 74 69 6f 6e 2c  sive() function,
ac60: 20 74 68 65 6e 0a 20 20 20 20 2a 2a 20 20 20 20   then.    **    
ac70: 20 20 20 72 65 2d 61 71 75 69 72 65 20 74 68 65     re-aquire the
ac80: 20 6d 75 74 65 78 20 62 65 66 6f 72 65 20 73 65   mutex before se
ac90: 74 69 6e 67 20 74 68 65 20 41 73 79 6e 63 46 69  ting the AsyncFi
aca0: 6c 65 2e 70 42 61 73 65 52 65 61 64 20 0a 20 20  le.pBaseRead .  
acb0: 20 20 2a 2a 20 20 20 20 20 20 20 76 61 72 69 61    **       varia
acc0: 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 20 20 20 20  ble..    **     
acd0: 2a 20 41 53 59 4e 43 5f 53 59 4e 43 20 61 6e 64  * ASYNC_SYNC and
ace0: 20 41 53 59 4e 43 5f 57 52 49 54 45 20 6f 70 65   ASYNC_WRITE ope
acf0: 72 61 74 69 6f 6e 73 2c 20 69 66 20 0a 20 20 20  rations, if .   
ad00: 20 2a 2a 20 20 20 20 20 20 20 53 51 4c 49 54 45   **       SQLITE
ad10: 5f 41 53 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48  _ASYNC_TWO_FILEH
ad20: 41 4e 44 4c 45 53 20 77 61 73 20 73 65 74 20 61  ANDLES was set a
ad30: 74 20 63 6f 6d 70 69 6c 65 20 74 69 6d 65 20 61  t compile time a
ad40: 6e 64 20 74 77 6f 0a 20 20 20 20 2a 2a 20 20 20  nd two.    **   
ad50: 20 20 20 20 66 69 6c 65 2d 68 61 6e 64 6c 65 73      file-handles
ad60: 20 61 72 65 20 6f 70 65 6e 20 66 6f 72 20 74 68   are open for th
ad70: 65 20 70 61 72 74 69 63 75 6c 61 72 20 66 69 6c  e particular fil
ad80: 65 20 62 65 69 6e 67 20 22 73 79 6e 63 65 64 22  e being "synced"
ad90: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  ..    */.    if(
ada0: 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 21 3d   async.ioError!=
adb0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e  SQLITE_OK && p->
adc0: 6f 70 21 3d 41 53 59 4e 43 5f 43 4c 4f 53 45 20  op!=ASYNC_CLOSE 
add0: 29 7b 0a 20 20 20 20 20 20 70 2d 3e 6f 70 20 3d  ){.      p->op =
ade0: 20 41 53 59 4e 43 5f 4e 4f 4f 50 3b 0a 20 20 20   ASYNC_NOOP;.   
adf0: 20 7d 0a 20 20 20 20 69 66 28 20 70 2d 3e 70 46   }.    if( p->pF
ae00: 69 6c 65 44 61 74 61 20 29 7b 0a 20 20 20 20 20  ileData ){.     
ae10: 20 70 42 61 73 65 20 3d 20 70 2d 3e 70 46 69 6c   pBase = p->pFil
ae20: 65 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74  eData->pBaseWrit
ae30: 65 3b 0a 20 20 20 20 20 20 69 66 28 20 0a 20 20  e;.      if( .  
ae40: 20 20 20 20 20 20 70 2d 3e 6f 70 3d 3d 41 53 59        p->op==ASY
ae50: 4e 43 5f 43 4c 4f 53 45 20 7c 7c 20 0a 20 20 20  NC_CLOSE || .   
ae60: 20 20 20 20 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e       p->op==ASYN
ae70: 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56 45 20  C_OPENEXCLUSIVE 
ae80: 7c 7c 0a 20 20 20 20 20 20 20 20 28 70 42 61 73  ||.        (pBas
ae90: 65 2d 3e 70 4d 65 74 68 6f 64 73 20 26 26 20 28  e->pMethods && (
aea0: 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f 53 59 4e  p->op==ASYNC_SYN
aeb0: 43 20 7c 7c 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e  C || p->op==ASYN
aec0: 43 5f 57 52 49 54 45 29 20 29 20 0a 20 20 20 20  C_WRITE) ) .    
aed0: 20 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73 79    ){.        asy
aee0: 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41  nc_mutex_leave(A
aef0: 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45  SYNC_MUTEX_QUEUE
af00: 29 3b 0a 20 20 20 20 20 20 20 20 68 6f 6c 64 69  );.        holdi
af10: 6e 67 4d 75 74 65 78 20 3d 20 30 3b 0a 20 20 20  ngMutex = 0;.   
af20: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 21     }.      if( !
af30: 70 42 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73 20  pBase->pMethods 
af40: 29 7b 0a 20 20 20 20 20 20 20 20 70 42 61 73 65  ){.        pBase
af50: 20 3d 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 2d   = p->pFileData-
af60: 3e 70 42 61 73 65 52 65 61 64 3b 0a 20 20 20 20  >pBaseRead;.    
af70: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73    }.    }..    s
af80: 77 69 74 63 68 28 20 70 2d 3e 6f 70 20 29 7b 0a  witch( p->op ){.
af90: 20 20 20 20 20 20 63 61 73 65 20 41 53 59 4e 43        case ASYNC
afa0: 5f 4e 4f 4f 50 3a 0a 20 20 20 20 20 20 20 20 62  _NOOP:.        b
afb0: 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73  reak;..      cas
afc0: 65 20 41 53 59 4e 43 5f 57 52 49 54 45 3a 0a 20  e ASYNC_WRITE:. 
afd0: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
afe0: 42 61 73 65 20 29 3b 0a 20 20 20 20 20 20 20 20  Base );.        
aff0: 41 53 59 4e 43 5f 54 52 41 43 45 28 28 22 57 52  ASYNC_TRACE(("WR
b000: 49 54 45 20 25 73 20 25 64 20 62 79 74 65 73 20  ITE %s %d bytes 
b010: 61 74 20 25 64 5c 6e 22 2c 0a 20 20 20 20 20 20  at %d\n",.      
b020: 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70 46 69            p->pFi
b030: 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 70  leData->zName, p
b040: 2d 3e 6e 42 79 74 65 2c 20 70 2d 3e 69 4f 66 66  ->nByte, p->iOff
b050: 73 65 74 29 29 3b 0a 20 20 20 20 20 20 20 20 72  set));.        r
b060: 63 20 3d 20 70 42 61 73 65 2d 3e 70 4d 65 74 68  c = pBase->pMeth
b070: 6f 64 73 2d 3e 78 57 72 69 74 65 28 70 42 61 73  ods->xWrite(pBas
b080: 65 2c 20 28 76 6f 69 64 20 2a 29 28 70 2d 3e 7a  e, (void *)(p->z
b090: 42 75 66 29 2c 20 70 2d 3e 6e 42 79 74 65 2c 20  Buf), p->nByte, 
b0a0: 70 2d 3e 69 4f 66 66 73 65 74 29 3b 0a 20 20 20  p->iOffset);.   
b0b0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
b0c0: 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f 53 59     case ASYNC_SY
b0d0: 4e 43 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65  NC:.        asse
b0e0: 72 74 28 20 70 42 61 73 65 20 29 3b 0a 20 20 20  rt( pBase );.   
b0f0: 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41 43 45       ASYNC_TRACE
b100: 28 28 22 53 59 4e 43 20 25 73 5c 6e 22 2c 20 70  (("SYNC %s\n", p
b110: 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61  ->pFileData->zNa
b120: 6d 65 29 29 3b 0a 20 20 20 20 20 20 20 20 72 63  me));.        rc
b130: 20 3d 20 70 42 61 73 65 2d 3e 70 4d 65 74 68 6f   = pBase->pMetho
b140: 64 73 2d 3e 78 53 79 6e 63 28 70 42 61 73 65 2c  ds->xSync(pBase,
b150: 20 70 2d 3e 6e 42 79 74 65 29 3b 0a 20 20 20 20   p->nByte);.    
b160: 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
b170: 20 20 63 61 73 65 20 41 53 59 4e 43 5f 54 52 55    case ASYNC_TRU
b180: 4e 43 41 54 45 3a 0a 20 20 20 20 20 20 20 20 61  NCATE:.        a
b190: 73 73 65 72 74 28 20 70 42 61 73 65 20 29 3b 0a  ssert( pBase );.
b1a0: 20 20 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52          ASYNC_TR
b1b0: 41 43 45 28 28 22 54 52 55 4e 43 41 54 45 20 25  ACE(("TRUNCATE %
b1c0: 73 20 74 6f 20 25 64 20 62 79 74 65 73 5c 6e 22  s to %d bytes\n"
b1d0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  , .             
b1e0: 20 20 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 2d     p->pFileData-
b1f0: 3e 7a 4e 61 6d 65 2c 20 70 2d 3e 69 4f 66 66 73  >zName, p->iOffs
b200: 65 74 29 29 3b 0a 20 20 20 20 20 20 20 20 72 63  et));.        rc
b210: 20 3d 20 70 42 61 73 65 2d 3e 70 4d 65 74 68 6f   = pBase->pMetho
b220: 64 73 2d 3e 78 54 72 75 6e 63 61 74 65 28 70 42  ds->xTruncate(pB
b230: 61 73 65 2c 20 70 2d 3e 69 4f 66 66 73 65 74 29  ase, p->iOffset)
b240: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
b250: 0a 0a 20 20 20 20 20 20 63 61 73 65 20 41 53 59  ..      case ASY
b260: 4e 43 5f 43 4c 4f 53 45 3a 20 7b 0a 20 20 20 20  NC_CLOSE: {.    
b270: 20 20 20 20 41 73 79 6e 63 46 69 6c 65 44 61 74      AsyncFileDat
b280: 61 20 2a 70 44 61 74 61 20 3d 20 70 2d 3e 70 46  a *pData = p->pF
b290: 69 6c 65 44 61 74 61 3b 0a 20 20 20 20 20 20 20  ileData;.       
b2a0: 20 41 53 59 4e 43 5f 54 52 41 43 45 28 28 22 43   ASYNC_TRACE(("C
b2b0: 4c 4f 53 45 20 25 73 5c 6e 22 2c 20 70 2d 3e 70  LOSE %s\n", p->p
b2c0: 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65 29  FileData->zName)
b2d0: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  );.        if( p
b2e0: 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74 65  Data->pBaseWrite
b2f0: 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b 0a 20 20  ->pMethods ){.  
b300: 20 20 20 20 20 20 20 20 70 44 61 74 61 2d 3e 70          pData->p
b310: 42 61 73 65 57 72 69 74 65 2d 3e 70 4d 65 74 68  BaseWrite->pMeth
b320: 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70 44 61 74  ods->xClose(pDat
b330: 61 2d 3e 70 42 61 73 65 57 72 69 74 65 29 3b 0a  a->pBaseWrite);.
b340: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
b350: 20 20 69 66 28 20 70 44 61 74 61 2d 3e 70 42 61    if( pData->pBa
b360: 73 65 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73  seRead->pMethods
b370: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 44   ){.          pD
b380: 61 74 61 2d 3e 70 42 61 73 65 52 65 61 64 2d 3e  ata->pBaseRead->
b390: 70 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73 65  pMethods->xClose
b3a0: 28 70 44 61 74 61 2d 3e 70 42 61 73 65 52 65 61  (pData->pBaseRea
b3b0: 64 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  d);.        }.. 
b3c0: 20 20 20 20 20 20 20 2f 2a 20 55 6e 6c 69 6e 6b         /* Unlink
b3d0: 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 2e 6c   AsyncFileData.l
b3e0: 6f 63 6b 20 66 72 6f 6d 20 74 68 65 20 6c 69 6e  ock from the lin
b3f0: 6b 65 64 20 6c 69 73 74 20 6f 66 20 41 73 79 6e  ked list of Asyn
b400: 63 46 69 6c 65 4c 6f 63 6b 20 0a 20 20 20 20 20  cFileLock .     
b410: 20 20 20 2a 2a 20 73 74 72 75 63 74 75 72 65 73     ** structures
b420: 20 66 6f 72 20 74 68 69 73 20 66 69 6c 65 2e 20   for this file. 
b430: 4f 62 74 61 69 6e 20 74 68 65 20 61 73 79 6e 63  Obtain the async
b440: 2e 6c 6f 63 6b 4d 75 74 65 78 20 6d 75 74 65 78  .lockMutex mutex
b450: 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 62 65 66   .        ** bef
b460: 6f 72 65 20 64 6f 69 6e 67 20 73 6f 2e 0a 20 20  ore doing so..  
b470: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20        */.       
b480: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74   async_mutex_ent
b490: 65 72 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c  er(ASYNC_MUTEX_L
b4a0: 4f 43 4b 29 3b 0a 20 20 20 20 20 20 20 20 72 63  OCK);.        rc
b4b0: 20 3d 20 75 6e 6c 69 6e 6b 41 73 79 6e 63 46 69   = unlinkAsyncFi
b4c0: 6c 65 28 70 44 61 74 61 29 3b 0a 20 20 20 20 20  le(pData);.     
b4d0: 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c     async_mutex_l
b4e0: 65 61 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58  eave(ASYNC_MUTEX
b4f0: 5f 4c 4f 43 4b 29 3b 0a 0a 20 20 20 20 20 20 20  _LOCK);..       
b500: 20 69 66 28 20 21 68 6f 6c 64 69 6e 67 4d 75 74   if( !holdingMut
b510: 65 78 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ex ){.          
b520: 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65  async_mutex_ente
b530: 72 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55  r(ASYNC_MUTEX_QU
b540: 45 55 45 29 3b 0a 20 20 20 20 20 20 20 20 20 20  EUE);.          
b550: 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20 31  holdingMutex = 1
b560: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
b570: 20 20 20 20 61 73 73 65 72 74 5f 6d 75 74 65 78      assert_mutex
b580: 5f 69 73 5f 68 65 6c 64 28 41 53 59 4e 43 5f 4d  _is_held(ASYNC_M
b590: 55 54 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 20  UTEX_QUEUE);.   
b5a0: 20 20 20 20 20 61 73 79 6e 63 2e 70 51 75 65 75       async.pQueu
b5b0: 65 46 69 72 73 74 20 3d 20 70 2d 3e 70 4e 65 78  eFirst = p->pNex
b5c0: 74 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  t;.        sqlit
b5d0: 65 33 5f 66 72 65 65 28 70 44 61 74 61 29 3b 0a  e3_free(pData);.
b5e0: 20 20 20 20 20 20 20 20 64 6f 4e 6f 74 46 72 65          doNotFre
b5f0: 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 62  e = 1;.        b
b600: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  reak;.      }.. 
b610: 20 20 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f       case ASYNC_
b620: 55 4e 4c 4f 43 4b 3a 20 7b 0a 20 20 20 20 20 20  UNLOCK: {.      
b630: 20 20 41 73 79 6e 63 57 72 69 74 65 20 2a 70 49    AsyncWrite *pI
b640: 74 65 72 3b 0a 20 20 20 20 20 20 20 20 41 73 79  ter;.        Asy
b650: 6e 63 46 69 6c 65 44 61 74 61 20 2a 70 44 61 74  ncFileData *pDat
b660: 61 20 3d 20 70 2d 3e 70 46 69 6c 65 44 61 74 61  a = p->pFileData
b670: 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 65 4c  ;.        int eL
b680: 6f 63 6b 20 3d 20 70 2d 3e 6e 42 79 74 65 3b 0a  ock = p->nByte;.
b690: 0a 20 20 20 20 20 20 20 20 2f 2a 20 57 68 65 6e  .        /* When
b6a0: 20 61 20 66 69 6c 65 20 69 73 20 6c 6f 63 6b 65   a file is locke
b6b0: 64 20 62 79 20 53 51 4c 69 74 65 20 75 73 69 6e  d by SQLite usin
b6c0: 67 20 74 68 65 20 61 73 79 6e 63 20 62 61 63 6b  g the async back
b6d0: 65 6e 64 2c 20 69 74 20 69 73 20 0a 20 20 20 20  end, it is .    
b6e0: 20 20 20 20 2a 2a 20 6c 6f 63 6b 65 64 20 77 69      ** locked wi
b6f0: 74 68 69 6e 20 74 68 65 20 27 72 65 61 6c 27 20  thin the 'real' 
b700: 66 69 6c 65 2d 73 79 73 74 65 6d 20 73 79 6e 63  file-system sync
b710: 68 72 6f 6e 6f 75 73 6c 79 2e 20 57 68 65 6e 20  hronously. When 
b720: 69 74 20 69 73 0a 20 20 20 20 20 20 20 20 2a 2a  it is.        **
b730: 20 75 6e 6c 6f 63 6b 65 64 2c 20 61 6e 20 41 53   unlocked, an AS
b740: 59 4e 43 5f 55 4e 4c 4f 43 4b 20 65 76 65 6e 74  YNC_UNLOCK event
b750: 20 69 73 20 61 64 64 65 64 20 74 6f 20 74 68 65   is added to the
b760: 20 77 72 69 74 65 2d 71 75 65 75 65 20 74 6f 0a   write-queue to.
b770: 20 20 20 20 20 20 20 20 2a 2a 20 75 6e 6c 6f 63          ** unloc
b780: 6b 20 74 68 65 20 66 69 6c 65 20 61 73 79 6e 63  k the file async
b790: 68 72 6f 6e 6f 75 73 6c 79 2e 20 54 68 65 20 64  hronously. The d
b7a0: 65 73 69 67 6e 20 6f 66 20 74 68 65 20 61 73 79  esign of the asy
b7b0: 6e 63 20 62 61 63 6b 65 6e 64 0a 20 20 20 20 20  nc backend.     
b7c0: 20 20 20 2a 2a 20 72 65 71 75 69 72 65 73 20 74     ** requires t
b7d0: 68 61 74 20 74 68 65 20 27 72 65 61 6c 27 20 66  hat the 'real' f
b7e0: 69 6c 65 2d 73 79 73 74 65 6d 20 66 69 6c 65 20  ile-system file 
b7f0: 62 65 20 6c 6f 63 6b 65 64 20 66 72 6f 6d 20 74  be locked from t
b800: 68 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 69  he.        ** ti
b810: 6d 65 20 74 68 61 74 20 53 51 4c 69 74 65 20 66  me that SQLite f
b820: 69 72 73 74 20 6c 6f 63 6b 73 20 69 74 20 28 61  irst locks it (a
b830: 6e 64 20 70 72 6f 62 61 62 6c 79 20 72 65 61 64  nd probably read
b840: 73 20 66 72 6f 6d 20 69 74 29 0a 20 20 20 20 20  s from it).     
b850: 20 20 20 2a 2a 20 75 6e 74 69 6c 20 61 6c 6c 20     ** until all 
b860: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 77 72 69  asynchronous wri
b870: 74 65 20 65 76 65 6e 74 73 20 74 68 61 74 20 77  te events that w
b880: 65 72 65 20 73 63 68 65 64 75 6c 65 64 20 62 65  ere scheduled be
b890: 66 6f 72 65 0a 20 20 20 20 20 20 20 20 2a 2a 20  fore.        ** 
b8a0: 53 51 4c 69 74 65 20 75 6e 6c 6f 63 6b 65 64 20  SQLite unlocked 
b8b0: 74 68 65 20 66 69 6c 65 20 68 61 76 65 20 62 65  the file have be
b8c0: 65 6e 20 70 72 6f 63 65 73 73 65 64 2e 0a 20 20  en processed..  
b8d0: 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20        **.       
b8e0: 20 2a 2a 20 54 68 69 73 20 69 73 20 6d 6f 72 65   ** This is more
b8f0: 20 63 6f 6d 70 6c 65 78 20 69 66 20 53 51 4c 69   complex if SQLi
b900: 74 65 20 6c 6f 63 6b 73 20 61 6e 64 20 75 6e 6c  te locks and unl
b910: 6f 63 6b 73 20 74 68 65 20 66 69 6c 65 20 6d 75  ocks the file mu
b920: 6c 74 69 70 6c 65 0a 20 20 20 20 20 20 20 20 2a  ltiple.        *
b930: 2a 20 74 69 6d 65 73 20 69 6e 20 71 75 69 63 6b  * times in quick
b940: 20 73 75 63 63 65 73 73 69 6f 6e 2e 20 46 6f 72   succession. For
b950: 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 53 51 4c   example, if SQL
b960: 69 74 65 20 64 6f 65 73 3a 20 0a 20 20 20 20 20  ite does: .     
b970: 20 20 20 2a 2a 20 0a 20 20 20 20 20 20 20 20 2a     ** .        *
b980: 2a 20 20 20 6c 6f 63 6b 2c 20 77 72 69 74 65 2c  *   lock, write,
b990: 20 75 6e 6c 6f 63 6b 2c 20 6c 6f 63 6b 2c 20 77   unlock, lock, w
b9a0: 72 69 74 65 2c 20 75 6e 6c 6f 63 6b 0a 20 20 20  rite, unlock.   
b9b0: 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20       **.        
b9c0: 2a 2a 20 45 61 63 68 20 22 6c 6f 63 6b 22 20 6f  ** Each "lock" o
b9d0: 70 65 72 61 74 69 6f 6e 20 6c 6f 63 6b 73 20 74  peration locks t
b9e0: 68 65 20 66 69 6c 65 20 69 6d 6d 65 64 69 61 74  he file immediat
b9f0: 65 6c 79 2e 20 45 61 63 68 20 22 77 72 69 74 65  ely. Each "write
ba00: 22 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 6e  " .        ** an
ba10: 64 20 22 75 6e 6c 6f 63 6b 22 20 6f 70 65 72 61  d "unlock" opera
ba20: 74 69 6f 6e 20 61 64 64 73 20 61 6e 20 65 76 65  tion adds an eve
ba30: 6e 74 20 74 6f 20 74 68 65 20 65 76 65 6e 74 20  nt to the event 
ba40: 71 75 65 75 65 2e 20 49 66 20 74 68 65 0a 20 20  queue. If the.  
ba50: 20 20 20 20 20 20 2a 2a 20 73 65 63 6f 6e 64 20        ** second 
ba60: 22 6c 6f 63 6b 22 20 6f 70 65 72 61 74 69 6f 6e  "lock" operation
ba70: 20 69 73 20 70 65 72 66 6f 72 6d 65 64 20 62 65   is performed be
ba80: 66 6f 72 65 20 74 68 65 20 66 69 72 73 74 20 22  fore the first "
ba90: 75 6e 6c 6f 63 6b 22 0a 20 20 20 20 20 20 20 20  unlock".        
baa0: 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 20 68 61 73  ** operation has
bab0: 20 62 65 65 6e 20 70 72 6f 63 65 73 73 65 64 20   been processed 
bac0: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 6c 79 2c 20  asynchronously, 
bad0: 74 68 65 6e 20 74 68 65 20 66 69 72 73 74 0a 20  then the first. 
bae0: 20 20 20 20 20 20 20 2a 2a 20 22 75 6e 6c 6f 63         ** "unloc
baf0: 6b 22 20 63 61 6e 6e 6f 74 20 62 65 20 73 61 66  k" cannot be saf
bb00: 65 6c 79 20 70 72 6f 63 65 73 73 65 64 20 61 73  ely processed as
bb10: 20 69 73 2c 20 73 69 6e 63 65 20 74 68 69 73 20   is, since this 
bb20: 77 6f 75 6c 64 20 6d 65 61 6e 0a 20 20 20 20 20  would mean.     
bb30: 20 20 20 2a 2a 20 74 68 65 20 66 69 6c 65 20 77     ** the file w
bb40: 61 73 20 75 6e 6c 6f 63 6b 65 64 20 77 68 65 6e  as unlocked when
bb50: 20 74 68 65 20 73 65 63 6f 6e 64 20 22 77 72 69   the second "wri
bb60: 74 65 22 20 6f 70 65 72 61 74 69 6f 6e 20 69 73  te" operation is
bb70: 0a 20 20 20 20 20 20 20 20 2a 2a 20 70 72 6f 63  .        ** proc
bb80: 65 73 73 65 64 2e 20 54 6f 20 77 6f 72 6b 20 61  essed. To work a
bb90: 72 6f 75 6e 64 20 74 68 69 73 2c 20 77 68 65 6e  round this, when
bba0: 20 70 72 6f 63 65 73 73 69 6e 67 20 61 6e 20 41   processing an A
bbb0: 53 59 4e 43 5f 55 4e 4c 4f 43 4b 0a 20 20 20 20  SYNC_UNLOCK.    
bbc0: 20 20 20 20 2a 2a 20 6f 70 65 72 61 74 69 6f 6e      ** operation
bbd0: 2c 20 53 51 4c 69 74 65 3a 0a 20 20 20 20 20 20  , SQLite:.      
bbe0: 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20    **.        ** 
bbf0: 20 20 31 29 20 55 6e 6c 6f 63 6b 73 20 74 68 65    1) Unlocks the
bc00: 20 66 69 6c 65 20 74 6f 20 74 68 65 20 6d 69 6e   file to the min
bc10: 69 6d 75 6d 20 6f 66 20 74 68 65 20 61 72 67 75  imum of the argu
bc20: 6d 65 6e 74 20 70 61 73 73 65 64 20 74 6f 0a 20  ment passed to. 
bc30: 20 20 20 20 20 20 20 2a 2a 20 20 20 20 20 20 74         **      t
bc40: 68 65 20 78 55 6e 6c 6f 63 6b 28 29 20 63 61 6c  he xUnlock() cal
bc50: 6c 20 61 6e 64 20 74 68 65 20 63 75 72 72 65 6e  l and the curren
bc60: 74 20 6c 6f 63 6b 20 66 72 6f 6d 20 53 51 4c 69  t lock from SQLi
bc70: 74 65 27 73 20 70 6f 69 6e 74 0a 20 20 20 20 20  te's point.     
bc80: 20 20 20 2a 2a 20 20 20 20 20 20 6f 66 20 76 69     **      of vi
bc90: 65 77 2c 20 61 6e 64 0a 20 20 20 20 20 20 20 20  ew, and.        
bca0: 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 20 20  **.        **   
bcb0: 32 29 20 4f 6e 6c 79 20 75 6e 6c 6f 63 6b 73 20  2) Only unlocks 
bcc0: 74 68 65 20 66 69 6c 65 20 61 74 20 61 6c 6c 20  the file at all 
bcd0: 69 66 20 74 68 69 73 20 65 76 65 6e 74 20 69 73  if this event is
bce0: 20 74 68 65 20 6c 61 73 74 0a 20 20 20 20 20 20   the last.      
bcf0: 20 20 2a 2a 20 20 20 20 20 20 41 53 59 4e 43 5f    **      ASYNC_
bd00: 55 4e 4c 4f 43 4b 20 65 76 65 6e 74 20 6f 6e 20  UNLOCK event on 
bd10: 74 68 69 73 20 66 69 6c 65 20 69 6e 20 74 68 65  this file in the
bd20: 20 77 72 69 74 65 2d 71 75 65 75 65 2e 0a 20 20   write-queue..  
bd30: 20 20 20 20 20 20 2a 2f 20 0a 20 20 20 20 20 20        */ .      
bd40: 20 20 61 73 73 65 72 74 28 20 68 6f 6c 64 69 6e    assert( holdin
bd50: 67 4d 75 74 65 78 3d 3d 31 20 29 3b 0a 20 20 20  gMutex==1 );.   
bd60: 20 20 20 20 20 61 73 73 65 72 74 28 20 61 73 79       assert( asy
bd70: 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74 3d 3d  nc.pQueueFirst==
bd80: 70 20 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72  p );.        for
bd90: 28 70 49 74 65 72 3d 61 73 79 6e 63 2e 70 51 75  (pIter=async.pQu
bda0: 65 75 65 46 69 72 73 74 2d 3e 70 4e 65 78 74 3b  eueFirst->pNext;
bdb0: 20 70 49 74 65 72 3b 20 70 49 74 65 72 3d 70 49   pIter; pIter=pI
bdc0: 74 65 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  ter->pNext){.   
bdd0: 20 20 20 20 20 20 20 69 66 28 20 70 49 74 65 72         if( pIter
bde0: 2d 3e 70 46 69 6c 65 44 61 74 61 3d 3d 70 44 61  ->pFileData==pDa
bdf0: 74 61 20 26 26 20 70 49 74 65 72 2d 3e 6f 70 3d  ta && pIter->op=
be00: 3d 41 53 59 4e 43 5f 55 4e 4c 4f 43 4b 20 29 20  =ASYNC_UNLOCK ) 
be10: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
be20: 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 70 49  .        if( !pI
be30: 74 65 72 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ter ){.         
be40: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74   async_mutex_ent
be50: 65 72 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c  er(ASYNC_MUTEX_L
be60: 4f 43 4b 29 3b 0a 20 20 20 20 20 20 20 20 20 20  OCK);.          
be70: 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e 65 41 73 79  pData->lock.eAsy
be80: 6e 63 4c 6f 63 6b 20 3d 20 4d 49 4e 28 0a 20 20  ncLock = MIN(.  
be90: 20 20 20 20 20 20 20 20 20 20 20 20 70 44 61 74              pDat
bea0: 61 2d 3e 6c 6f 63 6b 2e 65 41 73 79 6e 63 4c 6f  a->lock.eAsyncLo
beb0: 63 6b 2c 20 4d 41 58 28 70 44 61 74 61 2d 3e 6c  ck, MAX(pData->l
bec0: 6f 63 6b 2e 65 4c 6f 63 6b 2c 20 65 4c 6f 63 6b  ock.eLock, eLock
bed0: 29 0a 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20  ).          );. 
bee0: 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
bef0: 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e 65 41 73 79  pData->lock.eAsy
bf00: 6e 63 4c 6f 63 6b 3e 3d 70 44 61 74 61 2d 3e 6c  ncLock>=pData->l
bf10: 6f 63 6b 2e 65 4c 6f 63 6b 29 3b 0a 20 20 20 20  ock.eLock);.    
bf20: 20 20 20 20 20 20 72 63 20 3d 20 67 65 74 46 69        rc = getFi
bf30: 6c 65 4c 6f 63 6b 28 70 44 61 74 61 2d 3e 70 4c  leLock(pData->pL
bf40: 6f 63 6b 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ock);.          
bf50: 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76  async_mutex_leav
bf60: 65 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f  e(ASYNC_MUTEX_LO
bf70: 43 4b 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  CK);.        }. 
bf80: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
bf90: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 63 61 73      }..      cas
bfa0: 65 20 41 53 59 4e 43 5f 44 45 4c 45 54 45 3a 0a  e ASYNC_DELETE:.
bfb0: 20 20 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52          ASYNC_TR
bfc0: 41 43 45 28 28 22 44 45 4c 45 54 45 20 25 73 5c  ACE(("DELETE %s\
bfd0: 6e 22 2c 20 70 2d 3e 7a 42 75 66 29 29 3b 0a 20  n", p->zBuf));. 
bfe0: 20 20 20 20 20 20 20 72 63 20 3d 20 70 56 66 73         rc = pVfs
bff0: 2d 3e 78 44 65 6c 65 74 65 28 70 56 66 73 2c 20  ->xDelete(pVfs, 
c000: 70 2d 3e 7a 42 75 66 2c 20 28 69 6e 74 29 70 2d  p->zBuf, (int)p-
c010: 3e 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20  >iOffset);.     
c020: 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20     break;..     
c030: 20 63 61 73 65 20 41 53 59 4e 43 5f 4f 50 45 4e   case ASYNC_OPEN
c040: 45 58 43 4c 55 53 49 56 45 3a 20 7b 0a 20 20 20  EXCLUSIVE: {.   
c050: 20 20 20 20 20 69 6e 74 20 66 6c 61 67 73 20 3d       int flags =
c060: 20 28 69 6e 74 29 70 2d 3e 69 4f 66 66 73 65 74   (int)p->iOffset
c070: 3b 0a 20 20 20 20 20 20 20 20 41 73 79 6e 63 46  ;.        AsyncF
c080: 69 6c 65 44 61 74 61 20 2a 70 44 61 74 61 20 3d  ileData *pData =
c090: 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 3b 0a 20   p->pFileData;. 
c0a0: 20 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41         ASYNC_TRA
c0b0: 43 45 28 28 22 4f 50 45 4e 20 25 73 20 66 6c 61  CE(("OPEN %s fla
c0c0: 67 73 3d 25 64 5c 6e 22 2c 20 70 2d 3e 7a 42 75  gs=%d\n", p->zBu
c0d0: 66 2c 20 28 69 6e 74 29 70 2d 3e 69 4f 66 66 73  f, (int)p->iOffs
c0e0: 65 74 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73  et));.        as
c0f0: 73 65 72 74 28 70 44 61 74 61 2d 3e 70 42 61 73  sert(pData->pBas
c100: 65 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73 3d  eRead->pMethods=
c110: 3d 30 20 26 26 20 70 44 61 74 61 2d 3e 70 42 61  =0 && pData->pBa
c120: 73 65 57 72 69 74 65 2d 3e 70 4d 65 74 68 6f 64  seWrite->pMethod
c130: 73 3d 3d 30 29 3b 0a 20 20 20 20 20 20 20 20 72  s==0);.        r
c140: 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65 6e 28  c = pVfs->xOpen(
c150: 70 56 66 73 2c 20 70 44 61 74 61 2d 3e 7a 4e 61  pVfs, pData->zNa
c160: 6d 65 2c 20 70 44 61 74 61 2d 3e 70 42 61 73 65  me, pData->pBase
c170: 52 65 61 64 2c 20 66 6c 61 67 73 2c 20 30 29 3b  Read, flags, 0);
c180: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
c190: 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78 3d 3d 30   holdingMutex==0
c1a0: 20 29 3b 0a 20 20 20 20 20 20 20 20 61 73 79 6e   );.        asyn
c1b0: 63 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53  c_mutex_enter(AS
c1c0: 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29  YNC_MUTEX_QUEUE)
c1d0: 3b 0a 20 20 20 20 20 20 20 20 68 6f 6c 64 69 6e  ;.        holdin
c1e0: 67 4d 75 74 65 78 20 3d 20 31 3b 0a 20 20 20 20  gMutex = 1;.    
c1f0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
c200: 20 7d 0a 0a 20 20 20 20 20 20 64 65 66 61 75 6c   }..      defaul
c210: 74 3a 20 61 73 73 65 72 74 28 21 22 49 6c 6c 65  t: assert(!"Ille
c220: 67 61 6c 20 76 61 6c 75 65 20 66 6f 72 20 41 73  gal value for As
c230: 79 6e 63 57 72 69 74 65 2e 6f 70 22 29 3b 0a 20  yncWrite.op");. 
c240: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20     }..    /* If 
c250: 77 65 20 64 69 64 6e 27 74 20 68 61 6e 67 20 6f  we didn't hang o
c260: 6e 20 74 6f 20 74 68 65 20 6d 75 74 65 78 20 64  n to the mutex d
c270: 75 72 69 6e 67 20 74 68 65 20 49 4f 20 6f 70 2c  uring the IO op,
c280: 20 6f 62 74 61 69 6e 20 69 74 20 6e 6f 77 0a 20   obtain it now. 
c290: 20 20 20 2a 2a 20 73 6f 20 74 68 61 74 20 74 68     ** so that th
c2a0: 65 20 41 73 79 6e 63 57 72 69 74 65 20 73 74 72  e AsyncWrite str
c2b0: 75 63 74 75 72 65 20 63 61 6e 20 62 65 20 73 61  ucture can be sa
c2c0: 66 65 6c 79 20 72 65 6d 6f 76 65 64 20 66 72 6f  fely removed fro
c2d0: 6d 20 74 68 65 20 0a 20 20 20 20 2a 2a 20 67 6c  m the .    ** gl
c2e0: 6f 62 61 6c 20 77 72 69 74 65 2d 6f 70 20 71 75  obal write-op qu
c2f0: 65 75 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  eue..    */.    
c300: 69 66 28 20 21 68 6f 6c 64 69 6e 67 4d 75 74 65  if( !holdingMute
c310: 78 20 29 7b 0a 20 20 20 20 20 20 61 73 79 6e 63  x ){.      async
c320: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59  _mutex_enter(ASY
c330: 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b  NC_MUTEX_QUEUE);
c340: 0a 20 20 20 20 20 20 68 6f 6c 64 69 6e 67 4d 75  .      holdingMu
c350: 74 65 78 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20  tex = 1;.    }. 
c360: 20 20 20 2f 2a 20 41 53 59 4e 43 5f 54 52 41 43     /* ASYNC_TRAC
c370: 45 28 28 22 55 4e 4c 49 4e 4b 20 25 70 5c 6e 22  E(("UNLINK %p\n"
c380: 2c 20 70 29 29 3b 20 2a 2f 0a 20 20 20 20 69 66  , p)); */.    if
c390: 28 20 70 3d 3d 61 73 79 6e 63 2e 70 51 75 65 75  ( p==async.pQueu
c3a0: 65 4c 61 73 74 20 29 7b 0a 20 20 20 20 20 20 61  eLast ){.      a
c3b0: 73 79 6e 63 2e 70 51 75 65 75 65 4c 61 73 74 20  sync.pQueueLast 
c3c0: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  = 0;.    }.    i
c3d0: 66 28 20 21 64 6f 4e 6f 74 46 72 65 65 20 29 7b  f( !doNotFree ){
c3e0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 5f 6d 75  .      assert_mu
c3f0: 74 65 78 5f 69 73 5f 68 65 6c 64 28 41 53 59 4e  tex_is_held(ASYN
c400: 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b 0a  C_MUTEX_QUEUE);.
c410: 20 20 20 20 20 20 61 73 79 6e 63 2e 70 51 75 65        async.pQue
c420: 75 65 46 69 72 73 74 20 3d 20 70 2d 3e 70 4e 65  ueFirst = p->pNe
c430: 78 74 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  xt;.      sqlite
c440: 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 7d  3_free(p);.    }
c450: 0a 20 20 20 20 61 73 73 65 72 74 28 20 68 6f 6c  .    assert( hol
c460: 64 69 6e 67 4d 75 74 65 78 20 29 3b 0a 0a 20 20  dingMutex );..  
c470: 20 20 2f 2a 20 41 6e 20 49 4f 20 65 72 72 6f 72    /* An IO error
c480: 20 68 61 73 20 6f 63 63 75 72 72 65 64 2e 20 57   has occurred. W
c490: 65 20 63 61 6e 6e 6f 74 20 72 65 70 6f 72 74 20  e cannot report 
c4a0: 74 68 65 20 65 72 72 6f 72 20 62 61 63 6b 20 74  the error back t
c4b0: 6f 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e  o the.    ** con
c4c0: 6e 65 63 74 69 6f 6e 20 74 68 61 74 20 72 65 71  nection that req
c4d0: 75 65 73 74 65 64 20 74 68 65 20 49 2f 4f 20 73  uested the I/O s
c4e0: 69 6e 63 65 20 74 68 65 20 65 72 72 6f 72 20 68  ince the error h
c4f0: 61 70 70 65 6e 65 64 20 0a 20 20 20 20 2a 2a 20  appened .    ** 
c500: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 6c 79 2e 20  asynchronously. 
c510: 20 54 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20   The connection 
c520: 68 61 73 20 61 6c 72 65 61 64 79 20 6d 6f 76 65  has already move
c530: 64 20 6f 6e 2e 20 20 54 68 65 72 65 20 0a 20 20  d on.  There .  
c540: 20 20 2a 2a 20 72 65 61 6c 6c 79 20 69 73 20 6e    ** really is n
c550: 6f 62 6f 64 79 20 74 6f 20 72 65 70 6f 72 74 20  obody to report 
c560: 74 68 65 20 65 72 72 6f 72 20 74 6f 2e 0a 20 20  the error to..  
c570: 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20    **.    ** The 
c580: 66 69 6c 65 20 66 6f 72 20 77 68 69 63 68 20 74  file for which t
c590: 68 65 20 65 72 72 6f 72 20 6f 63 63 75 72 72 65  he error occurre
c5a0: 64 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20  d may have been 
c5b0: 61 20 64 61 74 61 62 61 73 65 20 6f 72 0a 20 20  a database or.  
c5c0: 20 20 2a 2a 20 6a 6f 75 72 6e 61 6c 20 66 69 6c    ** journal fil
c5d0: 65 2e 20 52 65 67 61 72 64 6c 65 73 73 2c 20 6e  e. Regardless, n
c5e0: 6f 6e 65 20 6f 66 20 74 68 65 20 63 75 72 72 65  one of the curre
c5f0: 6e 74 6c 79 20 71 75 65 75 65 64 20 6f 70 65 72  ntly queued oper
c600: 61 74 69 6f 6e 73 0a 20 20 20 20 2a 2a 20 61 73  ations.    ** as
c610: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
c620: 65 20 73 61 6d 65 20 64 61 74 61 62 61 73 65 20  e same database 
c630: 73 68 6f 75 6c 64 20 6e 6f 77 20 62 65 20 70 65  should now be pe
c640: 72 66 6f 72 6d 65 64 2e 20 4e 6f 72 20 73 68 6f  rformed. Nor sho
c650: 75 6c 64 0a 20 20 20 20 2a 2a 20 61 6e 79 20 73  uld.    ** any s
c660: 75 62 73 65 71 75 65 6e 74 6c 79 20 72 65 71 75  ubsequently requ
c670: 65 73 74 65 64 20 49 4f 20 6f 6e 20 65 69 74 68  ested IO on eith
c680: 65 72 20 61 20 64 61 74 61 62 61 73 65 20 6f 72  er a database or
c690: 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20 0a 20   journal file . 
c6a0: 20 20 20 2a 2a 20 68 61 6e 64 6c 65 20 66 6f 72     ** handle for
c6b0: 20 74 68 65 20 73 61 6d 65 20 64 61 74 61 62 61   the same databa
c6c0: 73 65 20 62 65 20 61 63 63 65 70 74 65 64 20 75  se be accepted u
c6d0: 6e 74 69 6c 20 74 68 65 20 6d 61 69 6e 20 64 61  ntil the main da
c6e0: 74 61 62 61 73 65 0a 20 20 20 20 2a 2a 20 66 69  tabase.    ** fi
c6f0: 6c 65 20 68 61 6e 64 6c 65 20 68 61 73 20 62 65  le handle has be
c700: 65 6e 20 63 6c 6f 73 65 64 20 61 6e 64 20 72 65  en closed and re
c710: 6f 70 65 6e 65 64 2e 0a 20 20 20 20 2a 2a 0a 20  opened..    **. 
c720: 20 20 20 2a 2a 20 46 75 72 74 68 65 72 6d 6f 72     ** Furthermor
c730: 65 2c 20 6e 6f 20 66 75 72 74 68 65 72 20 49 4f  e, no further IO
c740: 20 73 68 6f 75 6c 64 20 62 65 20 71 75 65 75 65   should be queue
c750: 64 20 6f 72 20 70 65 72 66 6f 72 6d 65 64 20 6f  d or performed o
c760: 6e 20 61 6e 79 20 66 69 6c 65 0a 20 20 20 20 2a  n any file.    *
c770: 2a 20 68 61 6e 64 6c 65 20 61 73 73 6f 63 69 61  * handle associa
c780: 74 65 64 20 77 69 74 68 20 61 20 64 61 74 61 62  ted with a datab
c790: 61 73 65 20 74 68 61 74 20 6d 61 79 20 68 61 76  ase that may hav
c7a0: 65 20 62 65 65 6e 20 70 61 72 74 20 6f 66 20 61  e been part of a
c7b0: 20 0a 20 20 20 20 2a 2a 20 6d 75 6c 74 69 2d 66   .    ** multi-f
c7c0: 69 6c 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ile transaction 
c7d0: 74 68 61 74 20 69 6e 63 6c 75 64 65 64 20 74 68  that included th
c7e0: 65 20 64 61 74 61 62 61 73 65 20 61 73 73 6f 63  e database assoc
c7f0: 69 61 74 65 64 20 77 69 74 68 20 0a 20 20 20 20  iated with .    
c800: 2a 2a 20 74 68 65 20 49 4f 20 65 72 72 6f 72 20  ** the IO error 
c810: 28 69 2e 65 2e 20 61 20 64 61 74 61 62 61 73 65  (i.e. a database
c820: 20 41 54 54 41 43 48 65 64 20 74 6f 20 74 68 65   ATTACHed to the
c830: 20 73 61 6d 65 20 68 61 6e 64 6c 65 20 61 74 20   same handle at 
c840: 73 6f 6d 65 20 0a 20 20 20 20 2a 2a 20 70 6f 69  some .    ** poi
c850: 6e 74 20 69 6e 20 74 69 6d 65 29 2e 0a 20 20 20  nt in time)..   
c860: 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 21 3d   */.    if( rc!=
c870: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
c880: 20 20 20 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72     async.ioError
c890: 20 3d 20 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20   = rc;.    }..  
c8a0: 20 20 69 66 28 20 61 73 79 6e 63 2e 69 6f 45 72    if( async.ioEr
c8b0: 72 6f 72 20 26 26 20 21 61 73 79 6e 63 2e 70 51  ror && !async.pQ
c8c0: 75 65 75 65 46 69 72 73 74 20 29 7b 0a 20 20 20  ueueFirst ){.   
c8d0: 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65     async_mutex_e
c8e0: 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54 45 58  nter(ASYNC_MUTEX
c8f0: 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20 69 66  _LOCK);.      if
c900: 28 20 30 3d 3d 61 73 79 6e 63 2e 70 4c 6f 63 6b  ( 0==async.pLock
c910: 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73 79 6e   ){.        asyn
c920: 63 2e 69 6f 45 72 72 6f 72 20 3d 20 53 51 4c 49  c.ioError = SQLI
c930: 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20  TE_OK;.      }. 
c940: 20 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78       async_mutex
c950: 5f 6c 65 61 76 65 28 41 53 59 4e 43 5f 4d 55 54  _leave(ASYNC_MUT
c960: 45 58 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 7d 0a  EX_LOCK);.    }.
c970: 0a 20 20 20 20 2f 2a 20 44 72 6f 70 20 74 68 65  .    /* Drop the
c980: 20 71 75 65 75 65 20 6d 75 74 65 78 20 62 65 66   queue mutex bef
c990: 6f 72 65 20 63 6f 6e 74 69 6e 75 69 6e 67 20 74  ore continuing t
c9a0: 6f 20 74 68 65 20 6e 65 78 74 20 77 72 69 74 65  o the next write
c9b0: 20 6f 70 65 72 61 74 69 6f 6e 0a 20 20 20 20 2a   operation.    *
c9c0: 2a 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 67 69  * in order to gi
c9d0: 76 65 20 6f 74 68 65 72 20 74 68 72 65 61 64 73  ve other threads
c9e0: 20 61 20 63 68 61 6e 63 65 20 74 6f 20 77 6f 72   a chance to wor
c9f0: 6b 20 77 69 74 68 20 74 68 65 20 77 72 69 74 65  k with the write
ca00: 20 71 75 65 75 65 2e 0a 20 20 20 20 2a 2f 0a 20   queue..    */. 
ca10: 20 20 20 69 66 28 20 21 61 73 79 6e 63 2e 70 51     if( !async.pQ
ca20: 75 65 75 65 46 69 72 73 74 20 7c 7c 20 21 61 73  ueueFirst || !as
ca30: 79 6e 63 2e 69 6f 45 72 72 6f 72 20 29 7b 0a 20  ync.ioError ){. 
ca40: 20 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78       async_mutex
ca50: 5f 6c 65 61 76 65 28 41 53 59 4e 43 5f 4d 55 54  _leave(ASYNC_MUT
ca60: 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20  EX_QUEUE);.     
ca70: 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20   holdingMutex = 
ca80: 30 3b 0a 20 20 20 20 20 20 69 66 28 20 61 73 79  0;.      if( asy
ca90: 6e 63 2e 69 6f 44 65 6c 61 79 3e 30 20 29 7b 0a  nc.ioDelay>0 ){.
caa0: 20 20 20 20 20 20 20 20 70 56 66 73 2d 3e 78 53          pVfs->xS
cab0: 6c 65 65 70 28 70 56 66 73 2c 20 61 73 79 6e 63  leep(pVfs, async
cac0: 2e 69 6f 44 65 6c 61 79 2a 31 30 30 30 29 3b 0a  .ioDelay*1000);.
cad0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
cae0: 20 20 20 20 20 61 73 79 6e 63 5f 73 63 68 65 64       async_sched
caf0: 5f 79 69 65 6c 64 28 29 3b 0a 20 20 20 20 20 20  _yield();.      
cb00: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20  }.    }.  }.  . 
cb10: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61   async_mutex_lea
cb20: 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 57  ve(ASYNC_MUTEX_W
cb30: 52 49 54 45 52 29 3b 0a 20 20 72 65 74 75 72 6e  RITER);.  return
cb40: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 73 74 61  ;.}../*.** Insta
cb50: 6c 6c 20 74 68 65 20 61 73 79 6e 63 68 72 6f 6e  ll the asynchron
cb60: 6f 75 73 20 56 46 53 2e 0a 2a 2f 20 0a 69 6e 74  ous VFS..*/ .int
cb70: 20 73 71 6c 69 74 65 33 61 73 79 6e 63 5f 69 6e   sqlite3async_in
cb80: 69 74 69 61 6c 69 7a 65 28 63 6f 6e 73 74 20 63  itialize(const c
cb90: 68 61 72 20 2a 7a 50 61 72 65 6e 74 2c 20 69 6e  har *zParent, in
cba0: 74 20 69 73 44 65 66 61 75 6c 74 29 7b 0a 20 20  t isDefault){.  
cbb0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
cbc0: 4f 4b 3b 0a 20 20 69 66 28 20 61 73 79 6e 63 5f  OK;.  if( async_
cbd0: 76 66 73 2e 70 41 70 70 44 61 74 61 3d 3d 30 20  vfs.pAppData==0 
cbe0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 76  ){.    sqlite3_v
cbf0: 66 73 20 2a 70 50 61 72 65 6e 74 20 3d 20 73 71  fs *pParent = sq
cc00: 6c 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 7a  lite3_vfs_find(z
cc10: 50 61 72 65 6e 74 29 3b 0a 20 20 20 20 69 66 28  Parent);.    if(
cc20: 20 21 70 50 61 72 65 6e 74 20 7c 7c 20 61 73 79   !pParent || asy
cc30: 6e 63 5f 6f 73 5f 69 6e 69 74 69 61 6c 69 7a 65  nc_os_initialize
cc40: 28 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  () ){.      rc =
cc50: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
cc60: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 53 51 4c     }else if( SQL
cc70: 49 54 45 5f 4f 4b 21 3d 28 72 63 20 3d 20 73 71  ITE_OK!=(rc = sq
cc80: 6c 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74  lite3_vfs_regist
cc90: 65 72 28 26 61 73 79 6e 63 5f 76 66 73 2c 20 69  er(&async_vfs, i
cca0: 73 44 65 66 61 75 6c 74 29 29 20 29 7b 0a 20 20  sDefault)) ){.  
ccb0: 20 20 20 20 61 73 79 6e 63 5f 6f 73 5f 73 68 75      async_os_shu
ccc0: 74 64 6f 77 6e 28 29 3b 0a 20 20 20 20 7d 65 6c  tdown();.    }el
ccd0: 73 65 7b 0a 20 20 20 20 20 20 61 73 79 6e 63 5f  se{.      async_
cce0: 76 66 73 2e 70 41 70 70 44 61 74 61 20 3d 20 28  vfs.pAppData = (
ccf0: 76 6f 69 64 20 2a 29 70 50 61 72 65 6e 74 3b 0a  void *)pParent;.
cd00: 20 20 20 20 20 20 61 73 79 6e 63 5f 76 66 73 2e        async_vfs.
cd10: 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20 28 28 73  mxPathname = ((s
cd20: 71 6c 69 74 65 33 5f 76 66 73 20 2a 29 61 73 79  qlite3_vfs *)asy
cd30: 6e 63 5f 76 66 73 2e 70 41 70 70 44 61 74 61 29  nc_vfs.pAppData)
cd40: 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 3b 0a 20 20  ->mxPathname;.  
cd50: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
cd60: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 6e   rc;.}../*.** Un
cd70: 69 6e 73 74 61 6c 6c 20 74 68 65 20 61 73 79 6e  install the asyn
cd80: 63 68 72 6f 6e 6f 75 73 20 56 46 53 2e 0a 2a 2f  chronous VFS..*/
cd90: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 61 73 79  .void sqlite3asy
cda0: 6e 63 5f 73 68 75 74 64 6f 77 6e 28 76 6f 69 64  nc_shutdown(void
cdb0: 29 7b 0a 20 20 69 66 28 20 61 73 79 6e 63 5f 76  ){.  if( async_v
cdc0: 66 73 2e 70 41 70 70 44 61 74 61 20 29 7b 0a 20  fs.pAppData ){. 
cdd0: 20 20 20 61 73 79 6e 63 5f 6f 73 5f 73 68 75 74     async_os_shut
cde0: 64 6f 77 6e 28 29 3b 0a 20 20 20 20 73 71 6c 69  down();.    sqli
cdf0: 74 65 33 5f 76 66 73 5f 75 6e 72 65 67 69 73 74  te3_vfs_unregist
ce00: 65 72 28 28 73 71 6c 69 74 65 33 5f 76 66 73 20  er((sqlite3_vfs 
ce10: 2a 29 26 61 73 79 6e 63 5f 76 66 73 29 3b 0a 20  *)&async_vfs);. 
ce20: 20 20 20 61 73 79 6e 63 5f 76 66 73 2e 70 41 70     async_vfs.pAp
ce30: 70 44 61 74 61 20 3d 20 30 3b 0a 20 20 7d 0a 7d  pData = 0;.  }.}
ce40: 0a 0a 2f 2a 0a 2a 2a 20 50 72 6f 63 65 73 73 20  ../*.** Process 
ce50: 65 76 65 6e 74 73 20 6f 6e 20 74 68 65 20 77 72  events on the wr
ce60: 69 74 65 2d 71 75 65 75 65 2e 0a 2a 2f 0a 76 6f  ite-queue..*/.vo
ce70: 69 64 20 73 71 6c 69 74 65 33 61 73 79 6e 63 5f  id sqlite3async_
ce80: 72 75 6e 28 76 6f 69 64 29 7b 0a 20 20 61 73 79  run(void){.  asy
ce90: 6e 63 57 72 69 74 65 72 54 68 72 65 61 64 28 29  ncWriterThread()
cea0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 74 72  ;.}../*.** Contr
ceb0: 6f 6c 2f 63 6f 6e 66 69 67 75 72 65 20 74 68 65  ol/configure the
cec0: 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 49 4f   asynchronous IO
ced0: 20 73 79 73 74 65 6d 2e 0a 2a 2f 0a 69 6e 74 20   system..*/.int 
cee0: 73 71 6c 69 74 65 33 61 73 79 6e 63 5f 63 6f 6e  sqlite3async_con
cef0: 74 72 6f 6c 28 69 6e 74 20 6f 70 2c 20 2e 2e 2e  trol(int op, ...
cf00: 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b  ){.  va_list ap;
cf10: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20  .  va_start(ap, 
cf20: 6f 70 29 3b 0a 20 20 73 77 69 74 63 68 28 20 6f  op);.  switch( o
cf30: 70 20 29 7b 0a 20 20 20 20 63 61 73 65 20 53 51  p ){.    case SQ
cf40: 4c 49 54 45 41 53 59 4e 43 5f 48 41 4c 54 3a 20  LITEASYNC_HALT: 
cf50: 7b 0a 20 20 20 20 20 20 69 6e 74 20 65 57 68 65  {.      int eWhe
cf60: 6e 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 69  n = va_arg(ap, i
cf70: 6e 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 65  nt);.      if( e
cf80: 57 68 65 6e 21 3d 53 51 4c 49 54 45 41 53 59 4e  When!=SQLITEASYN
cf90: 43 5f 48 41 4c 54 5f 4e 45 56 45 52 0a 20 20 20  C_HALT_NEVER.   
cfa0: 20 20 20 20 26 26 20 65 57 68 65 6e 21 3d 53 51      && eWhen!=SQ
cfb0: 4c 49 54 45 41 53 59 4e 43 5f 48 41 4c 54 5f 4e  LITEASYNC_HALT_N
cfc0: 4f 57 0a 20 20 20 20 20 20 20 26 26 20 65 57 68  OW.       && eWh
cfd0: 65 6e 21 3d 53 51 4c 49 54 45 41 53 59 4e 43 5f  en!=SQLITEASYNC_
cfe0: 48 41 4c 54 5f 49 44 4c 45 0a 20 20 20 20 20 20  HALT_IDLE.      
cff0: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
d000: 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b  n SQLITE_MISUSE;
d010: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
d020: 73 79 6e 63 2e 65 48 61 6c 74 20 3d 20 65 57 68  sync.eHalt = eWh
d030: 65 6e 3b 0a 20 20 20 20 20 20 61 73 79 6e 63 5f  en;.      async_
d040: 6d 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e  mutex_enter(ASYN
d050: 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b 0a  C_MUTEX_QUEUE);.
d060: 20 20 20 20 20 20 61 73 79 6e 63 5f 63 6f 6e 64        async_cond
d070: 5f 73 69 67 6e 61 6c 28 41 53 59 4e 43 5f 43 4f  _signal(ASYNC_CO
d080: 4e 44 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20  ND_QUEUE);.     
d090: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61   async_mutex_lea
d0a0: 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51  ve(ASYNC_MUTEX_Q
d0b0: 55 45 55 45 29 3b 0a 20 20 20 20 20 20 62 72 65  UEUE);.      bre
d0c0: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
d0d0: 61 73 65 20 53 51 4c 49 54 45 41 53 59 4e 43 5f  ase SQLITEASYNC_
d0e0: 44 45 4c 41 59 3a 20 7b 0a 20 20 20 20 20 20 69  DELAY: {.      i
d0f0: 6e 74 20 69 44 65 6c 61 79 20 3d 20 76 61 5f 61  nt iDelay = va_a
d100: 72 67 28 61 70 2c 20 69 6e 74 29 3b 0a 20 20 20  rg(ap, int);.   
d110: 20 20 20 69 66 28 20 69 44 65 6c 61 79 3c 30 20     if( iDelay<0 
d120: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
d130: 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b  n SQLITE_MISUSE;
d140: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
d150: 73 79 6e 63 2e 69 6f 44 65 6c 61 79 20 3d 20 69  sync.ioDelay = i
d160: 44 65 6c 61 79 3b 0a 20 20 20 20 20 20 62 72 65  Delay;.      bre
d170: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
d180: 61 73 65 20 53 51 4c 49 54 45 41 53 59 4e 43 5f  ase SQLITEASYNC_
d190: 4c 4f 43 4b 46 49 4c 45 53 3a 20 7b 0a 20 20 20  LOCKFILES: {.   
d1a0: 20 20 20 69 6e 74 20 62 4c 6f 63 6b 20 3d 20 76     int bLock = v
d1b0: 61 5f 61 72 67 28 61 70 2c 20 69 6e 74 29 3b 0a  a_arg(ap, int);.
d1c0: 20 20 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65        async_mute
d1d0: 78 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55  x_enter(ASYNC_MU
d1e0: 54 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20  TEX_QUEUE);.    
d1f0: 20 20 69 66 28 20 61 73 79 6e 63 2e 6e 46 69 6c    if( async.nFil
d200: 65 20 7c 7c 20 61 73 79 6e 63 2e 70 51 75 65 75  e || async.pQueu
d210: 65 46 69 72 73 74 20 29 7b 0a 20 20 20 20 20 20  eFirst ){.      
d220: 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65    async_mutex_le
d230: 61 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f  ave(ASYNC_MUTEX_
d240: 51 55 45 55 45 29 3b 0a 20 20 20 20 20 20 20 20  QUEUE);.        
d250: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49  return SQLITE_MI
d260: 53 55 53 45 3b 0a 20 20 20 20 20 20 7d 0a 20 20  SUSE;.      }.  
d270: 20 20 20 20 61 73 79 6e 63 2e 62 4c 6f 63 6b 46      async.bLockF
d280: 69 6c 65 73 20 3d 20 62 4c 6f 63 6b 3b 0a 20 20  iles = bLock;.  
d290: 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f      async_mutex_
d2a0: 6c 65 61 76 65 28 41 53 59 4e 43 5f 4d 55 54 45  leave(ASYNC_MUTE
d2b0: 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20 20  X_QUEUE);.      
d2c0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20  break;.    }.   
d2d0: 20 20 20 0a 20 20 20 20 63 61 73 65 20 53 51 4c     .    case SQL
d2e0: 49 54 45 41 53 59 4e 43 5f 47 45 54 5f 48 41 4c  ITEASYNC_GET_HAL
d2f0: 54 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 2a  T: {.      int *
d300: 70 65 57 68 65 6e 20 3d 20 76 61 5f 61 72 67 28  peWhen = va_arg(
d310: 61 70 2c 20 69 6e 74 20 2a 29 3b 0a 20 20 20 20  ap, int *);.    
d320: 20 20 2a 70 65 57 68 65 6e 20 3d 20 61 73 79 6e    *peWhen = asyn
d330: 63 2e 65 48 61 6c 74 3b 0a 20 20 20 20 20 20 62  c.eHalt;.      b
d340: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20  reak;.    }.    
d350: 63 61 73 65 20 53 51 4c 49 54 45 41 53 59 4e 43  case SQLITEASYNC
d360: 5f 47 45 54 5f 44 45 4c 41 59 3a 20 7b 0a 20 20  _GET_DELAY: {.  
d370: 20 20 20 20 69 6e 74 20 2a 70 69 44 65 6c 61 79      int *piDelay
d380: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 69 6e   = va_arg(ap, in
d390: 74 20 2a 29 3b 0a 20 20 20 20 20 20 2a 70 69 44  t *);.      *piD
d3a0: 65 6c 61 79 20 3d 20 61 73 79 6e 63 2e 69 6f 44  elay = async.ioD
d3b0: 65 6c 61 79 3b 0a 20 20 20 20 20 20 62 72 65 61  elay;.      brea
d3c0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73  k;.    }.    cas
d3d0: 65 20 53 51 4c 49 54 45 41 53 59 4e 43 5f 47 45  e SQLITEASYNC_GE
d3e0: 54 5f 4c 4f 43 4b 46 49 4c 45 53 3a 20 7b 0a 20  T_LOCKFILES: {. 
d3f0: 20 20 20 20 20 69 6e 74 20 2a 70 69 44 65 6c 61       int *piDela
d400: 79 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 69  y = va_arg(ap, i
d410: 6e 74 20 2a 29 3b 0a 20 20 20 20 20 20 2a 70 69  nt *);.      *pi
d420: 44 65 6c 61 79 20 3d 20 61 73 79 6e 63 2e 62 4c  Delay = async.bL
d430: 6f 63 6b 46 69 6c 65 73 3b 0a 20 20 20 20 20 20  ockFiles;.      
d440: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
d450: 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20    default:.     
d460: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
d470: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75  RROR;.  }.  retu
d480: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
d490: 0a 23 65 6e 64 69 66 20 2f 2a 20 21 64 65 66 69  .#endif /* !defi
d4a0: 6e 65 64 28 53 51 4c 49 54 45 5f 43 4f 52 45 29  ned(SQLITE_CORE)
d4b0: 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49   || defined(SQLI
d4c0: 54 45 5f 45 4e 41 42 4c 45 5f 41 53 59 4e 43 49  TE_ENABLE_ASYNCI
d4d0: 4f 29 20 2a 2f 0a 0a                             O) */..