/ Hex Artifact Content
Login

Artifact b5a3e30f538a9ffe81538b3063b4d5963f9bb422:


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 4e 4f 54 46 4f 55 4e 44 3b 0a 7d 0a 0a  TE_NOTFOUND;.}..
7ae0: 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  /* .** Return th
7af0: 65 20 64 65 76 69 63 65 20 63 68 61 72 61 63 74  e device charact
7b00: 65 72 69 73 74 69 63 73 20 61 6e 64 20 73 65 63  eristics and sec
7b10: 74 6f 72 2d 73 69 7a 65 20 6f 66 20 74 68 65 20  tor-size of the 
7b20: 64 65 76 69 63 65 2e 20 49 74 0a 2a 2a 20 69 73  device. It.** is
7b30: 20 74 72 69 63 6b 79 20 74 6f 20 69 6d 70 6c 65   tricky to imple
7b40: 6d 65 6e 74 20 74 68 65 73 65 20 63 6f 72 72 65  ment these corre
7b50: 63 74 6c 79 2c 20 61 73 20 74 68 69 73 20 62 61  ctly, as this ba
7b60: 63 6b 65 6e 64 20 6d 69 67 68 74 20 0a 2a 2a 20  ckend might .** 
7b70: 6e 6f 74 20 68 61 76 65 20 61 6e 20 6f 70 65 6e  not have an open
7b80: 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 61 74 20   file handle at 
7b90: 74 68 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 73  this point..*/.s
7ba0: 74 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 53  tatic int asyncS
7bb0: 65 63 74 6f 72 53 69 7a 65 28 73 71 6c 69 74 65  ectorSize(sqlite
7bc0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a  3_file *pFile){.
7bd0: 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54    UNUSED_PARAMET
7be0: 45 52 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  ER(pFile);.  ret
7bf0: 75 72 6e 20 35 31 32 3b 0a 7d 0a 73 74 61 74 69  urn 512;.}.stati
7c00: 63 20 69 6e 74 20 61 73 79 6e 63 44 65 76 69 63  c int asyncDevic
7c10: 65 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73  eCharacteristics
7c20: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
7c30: 46 69 6c 65 29 7b 0a 20 20 55 4e 55 53 45 44 5f  File){.  UNUSED_
7c40: 50 41 52 41 4d 45 54 45 52 28 70 46 69 6c 65 29  PARAMETER(pFile)
7c50: 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  ;.  return 0;.}.
7c60: 0a 73 74 61 74 69 63 20 69 6e 74 20 75 6e 6c 69  .static int unli
7c70: 6e 6b 41 73 79 6e 63 46 69 6c 65 28 41 73 79 6e  nkAsyncFile(Asyn
7c80: 63 46 69 6c 65 44 61 74 61 20 2a 70 44 61 74 61  cFileData *pData
7c90: 29 7b 0a 20 20 41 73 79 6e 63 46 69 6c 65 4c 6f  ){.  AsyncFileLo
7ca0: 63 6b 20 2a 2a 70 70 49 74 65 72 3b 0a 20 20 69  ck **ppIter;.  i
7cb0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
7cc0: 4b 3b 0a 0a 20 20 69 66 28 20 70 44 61 74 61 2d  K;..  if( pData-
7cd0: 3e 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 41 73  >zName ){.    As
7ce0: 79 6e 63 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 20 3d  yncLock *pLock =
7cf0: 20 70 44 61 74 61 2d 3e 70 4c 6f 63 6b 3b 0a 20   pData->pLock;. 
7d00: 20 20 20 66 6f 72 28 70 70 49 74 65 72 3d 26 70     for(ppIter=&p
7d10: 4c 6f 63 6b 2d 3e 70 4c 69 73 74 3b 20 2a 70 70  Lock->pList; *pp
7d20: 49 74 65 72 3b 20 70 70 49 74 65 72 3d 26 28 28  Iter; ppIter=&((
7d30: 2a 70 70 49 74 65 72 29 2d 3e 70 4e 65 78 74 29  *ppIter)->pNext)
7d40: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 28 2a 70  ){.      if( (*p
7d50: 70 49 74 65 72 29 3d 3d 26 70 44 61 74 61 2d 3e  pIter)==&pData->
7d60: 6c 6f 63 6b 20 29 7b 0a 20 20 20 20 20 20 20 20  lock ){.        
7d70: 2a 70 70 49 74 65 72 20 3d 20 70 44 61 74 61 2d  *ppIter = pData-
7d80: 3e 6c 6f 63 6b 2e 70 4e 65 78 74 3b 0a 20 20 20  >lock.pNext;.   
7d90: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
7da0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
7db0: 28 20 21 70 4c 6f 63 6b 2d 3e 70 4c 69 73 74 20  ( !pLock->pList 
7dc0: 29 7b 0a 20 20 20 20 20 20 41 73 79 6e 63 4c 6f  ){.      AsyncLo
7dd0: 63 6b 20 2a 2a 70 70 3b 0a 20 20 20 20 20 20 69  ck **pp;.      i
7de0: 66 28 20 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65 20  f( pLock->pFile 
7df0: 29 7b 0a 20 20 20 20 20 20 20 20 70 4c 6f 63 6b  ){.        pLock
7e00: 2d 3e 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64  ->pFile->pMethod
7e10: 73 2d 3e 78 43 6c 6f 73 65 28 70 4c 6f 63 6b 2d  s->xClose(pLock-
7e20: 3e 70 46 69 6c 65 29 3b 0a 20 20 20 20 20 20 7d  >pFile);.      }
7e30: 0a 20 20 20 20 20 20 66 6f 72 28 70 70 3d 26 61  .      for(pp=&a
7e40: 73 79 6e 63 2e 70 4c 6f 63 6b 3b 20 2a 70 70 21  sync.pLock; *pp!
7e50: 3d 70 4c 6f 63 6b 3b 20 70 70 3d 26 28 28 2a 70  =pLock; pp=&((*p
7e60: 70 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20  p)->pNext));.   
7e70: 20 20 20 2a 70 70 20 3d 20 70 4c 6f 63 6b 2d 3e     *pp = pLock->
7e80: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 73 71 6c  pNext;.      sql
7e90: 69 74 65 33 5f 66 72 65 65 28 70 4c 6f 63 6b 29  ite3_free(pLock)
7ea0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
7eb0: 20 20 20 72 63 20 3d 20 67 65 74 46 69 6c 65 4c     rc = getFileL
7ec0: 6f 63 6b 28 70 4c 6f 63 6b 29 3b 0a 20 20 20 20  ock(pLock);.    
7ed0: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  }.  }..  return 
7ee0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  rc;.}../*.** The
7ef0: 20 70 61 72 61 6d 65 74 65 72 20 70 61 73 73 65   parameter passe
7f00: 64 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69  d to this functi
7f10: 6f 6e 20 69 73 20 61 20 63 6f 70 79 20 6f 66 20  on is a copy of 
7f20: 61 20 27 66 6c 61 67 73 27 20 70 61 72 61 6d 65  a 'flags' parame
7f30: 74 65 72 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f  ter.** passed to
7f40: 20 74 68 69 73 20 6d 6f 64 75 6c 65 73 20 78 4f   this modules xO
7f50: 70 65 6e 28 29 20 6d 65 74 68 6f 64 2e 20 54 68  pen() method. Th
7f60: 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75  is function retu
7f70: 72 6e 73 20 74 72 75 65 0a 2a 2a 20 69 66 20 74  rns true.** if t
7f80: 68 65 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 62  he file should b
7f90: 65 20 6f 70 65 6e 65 64 20 61 73 79 6e 63 68 72  e opened asynchr
7fa0: 6f 6e 6f 75 73 6c 79 2c 20 6f 72 20 66 61 6c 73  onously, or fals
7fb0: 65 20 69 66 20 69 74 20 73 68 6f 75 6c 64 0a 2a  e if it should.*
7fc0: 2a 20 62 65 20 6f 70 65 6e 65 64 20 69 6d 6d 65  * be opened imme
7fd0: 64 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 49  diately..**.** I
7fe0: 66 20 74 68 65 20 66 69 6c 65 20 69 73 20 74 6f  f the file is to
7ff0: 20 62 65 20 6f 70 65 6e 65 64 20 61 73 79 6e 63   be opened async
8000: 68 72 6f 6e 6f 75 73 6c 79 2c 20 74 68 65 6e 20  hronously, then 
8010: 61 73 79 6e 63 4f 70 65 6e 28 29 20 77 69 6c 6c  asyncOpen() will
8020: 20 61 64 64 0a 2a 2a 20 61 6e 20 65 6e 74 72 79   add.** an entry
8030: 20 74 6f 20 74 68 65 20 65 76 65 6e 74 20 71 75   to the event qu
8040: 65 75 65 20 61 6e 64 20 74 68 65 20 66 69 6c 65  eue and the file
8050: 20 77 69 6c 6c 20 6e 6f 74 20 61 63 74 75 61 6c   will not actual
8060: 6c 79 20 62 65 20 6f 70 65 6e 65 64 0a 2a 2a 20  ly be opened.** 
8070: 75 6e 74 69 6c 20 74 68 65 20 65 76 65 6e 74 20  until the event 
8080: 69 73 20 70 72 6f 63 65 73 73 65 64 2e 20 4f 74  is processed. Ot
8090: 68 65 72 77 69 73 65 2c 20 74 68 65 20 66 69 6c  herwise, the fil
80a0: 65 20 69 73 20 6f 70 65 6e 65 64 20 64 69 72 65  e is opened dire
80b0: 63 74 6c 79 0a 2a 2a 20 62 79 20 74 68 65 20 63  ctly.** by the c
80c0: 61 6c 6c 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  aller..*/.static
80d0: 20 69 6e 74 20 64 6f 41 73 79 6e 63 68 72 6f 6e   int doAsynchron
80e0: 6f 75 73 4f 70 65 6e 28 69 6e 74 20 66 6c 61 67  ousOpen(int flag
80f0: 73 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 66 6c  s){.  return (fl
8100: 61 67 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  ags&SQLITE_OPEN_
8110: 43 52 45 41 54 45 29 20 26 26 20 28 0a 20 20 20  CREATE) && (.   
8120: 20 20 20 28 66 6c 61 67 73 26 53 51 4c 49 54 45     (flags&SQLITE
8130: 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 4a 4f 55 52 4e  _OPEN_MAIN_JOURN
8140: 41 4c 29 20 7c 7c 0a 20 20 20 20 20 20 28 66 6c  AL) ||.      (fl
8150: 61 67 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  ags&SQLITE_OPEN_
8160: 54 45 4d 50 5f 4a 4f 55 52 4e 41 4c 29 20 7c 7c  TEMP_JOURNAL) ||
8170: 0a 20 20 20 20 20 20 28 66 6c 61 67 73 26 53 51  .      (flags&SQ
8180: 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45  LITE_OPEN_DELETE
8190: 4f 4e 43 4c 4f 53 45 29 0a 20 20 29 3b 0a 7d 0a  ONCLOSE).  );.}.
81a0: 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20 66 69  ./*.** Open a fi
81b0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
81c0: 74 20 61 73 79 6e 63 4f 70 65 6e 28 0a 20 20 73  t asyncOpen(.  s
81d0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 41 73 79  qlite3_vfs *pAsy
81e0: 6e 63 56 66 73 2c 0a 20 20 63 6f 6e 73 74 20 63  ncVfs,.  const c
81f0: 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 73 71  har *zName,.  sq
8200: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
8210: 65 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73 2c 0a  e,.  int flags,.
8220: 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61 67 73    int *pOutFlags
8230: 0a 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c  .){.  static sql
8240: 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20  ite3_io_methods 
8250: 61 73 79 6e 63 5f 6d 65 74 68 6f 64 73 20 3d 20  async_methods = 
8260: 7b 0a 20 20 20 20 31 2c 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 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
8290: 6f 6e 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 43  on */.    asyncC
82a0: 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20 20  lose,           
82b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
82c0: 6c 6f 73 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e  lose */.    asyn
82d0: 63 52 65 61 64 2c 20 20 20 20 20 20 20 20 20 20  cRead,          
82e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
82f0: 78 52 65 61 64 20 2a 2f 0a 20 20 20 20 61 73 79  xRead */.    asy
8300: 6e 63 57 72 69 74 65 2c 20 20 20 20 20 20 20 20  ncWrite,        
8310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8320: 20 78 57 72 69 74 65 20 2a 2f 0a 20 20 20 20 61   xWrite */.    a
8330: 73 79 6e 63 54 72 75 6e 63 61 74 65 2c 20 20 20  syncTruncate,   
8340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8350: 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a  /* xTruncate */.
8360: 20 20 20 20 61 73 79 6e 63 53 79 6e 63 2c 20 20      asyncSync,  
8370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8380: 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f       /* xSync */
8390: 0a 20 20 20 20 61 73 79 6e 63 46 69 6c 65 53 69  .    asyncFileSi
83a0: 7a 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ze,             
83b0: 20 20 20 20 20 20 2f 2a 20 78 46 69 6c 65 53 69        /* xFileSi
83c0: 7a 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63 4c  ze */.    asyncL
83d0: 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ock,            
83e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4c             /* xL
83f0: 6f 63 6b 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63  ock */.    async
8400: 55 6e 6c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20  Unlock,         
8410: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8420: 55 6e 6c 6f 63 6b 20 2a 2f 0a 20 20 20 20 61 73  Unlock */.    as
8430: 79 6e 63 43 68 65 63 6b 52 65 73 65 72 76 65 64  yncCheckReserved
8440: 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20 2f  Lock,          /
8450: 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76 65 64  * xCheckReserved
8460: 4c 6f 63 6b 20 2a 2f 0a 20 20 20 20 61 73 79 6e  Lock */.    asyn
8470: 63 46 69 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20  cFileControl,   
8480: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8490: 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a  xFileControl */.
84a0: 20 20 20 20 61 73 79 6e 63 53 65 63 74 6f 72 53      asyncSectorS
84b0: 69 7a 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ize,            
84c0: 20 20 20 20 20 2f 2a 20 78 53 65 63 74 6f 72 53       /* xSectorS
84d0: 69 7a 65 20 2a 2f 0a 20 20 20 20 61 73 79 6e 63  ize */.    async
84e0: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
84f0: 73 74 69 63 73 20 20 20 20 20 20 20 2f 2a 20 78  stics       /* x
8500: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
8510: 73 74 69 63 73 20 2a 2f 0a 20 20 7d 3b 0a 0a 20  stics */.  };.. 
8520: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
8530: 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66  fs = (sqlite3_vf
8540: 73 20 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70  s *)pAsyncVfs->p
8550: 41 70 70 44 61 74 61 3b 0a 20 20 41 73 79 6e 63  AppData;.  Async
8560: 46 69 6c 65 20 2a 70 20 3d 20 28 41 73 79 6e 63  File *p = (Async
8570: 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20  File *)pFile;.  
8580: 69 6e 74 20 6e 4e 61 6d 65 20 3d 20 30 3b 0a 20  int nName = 0;. 
8590: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
85a0: 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65  _OK;.  int nByte
85b0: 3b 0a 20 20 41 73 79 6e 63 46 69 6c 65 44 61 74  ;.  AsyncFileDat
85c0: 61 20 2a 70 44 61 74 61 3b 0a 20 20 41 73 79 6e  a *pData;.  Asyn
85d0: 63 4c 6f 63 6b 20 2a 70 4c 6f 63 6b 20 3d 20 30  cLock *pLock = 0
85e0: 3b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 69  ;.  char *z;.  i
85f0: 6e 74 20 69 73 41 73 79 6e 63 4f 70 65 6e 20 3d  nt isAsyncOpen =
8600: 20 64 6f 41 73 79 6e 63 68 72 6f 6e 6f 75 73 4f   doAsynchronousO
8610: 70 65 6e 28 66 6c 61 67 73 29 3b 0a 0a 20 20 2f  pen(flags);..  /
8620: 2a 20 49 66 20 7a 4e 61 6d 65 20 69 73 20 4e 55  * If zName is NU
8630: 4c 4c 2c 20 74 68 65 6e 20 74 68 65 20 75 70 70  LL, then the upp
8640: 65 72 20 6c 61 79 65 72 20 69 73 20 72 65 71 75  er layer is requ
8650: 65 73 74 69 6e 67 20 61 6e 20 61 6e 6f 6e 79 6d  esting an anonym
8660: 6f 75 73 20 66 69 6c 65 2e 0a 20 20 2a 2a 20 4f  ous file..  ** O
8670: 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f 63 61  therwise, alloca
8680: 74 65 20 65 6e 6f 75 67 68 20 73 70 61 63 65 20  te enough space 
8690: 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f  to make a copy o
86a0: 66 20 74 68 65 20 66 69 6c 65 20 6e 61 6d 65 20  f the file name 
86b0: 28 61 6c 6f 6e 67 0a 20 20 2a 2a 20 77 69 74 68  (along.  ** with
86c0: 20 74 68 65 20 73 65 63 6f 6e 64 20 6e 75 6c 2d   the second nul-
86d0: 74 65 72 6d 69 6e 61 74 6f 72 20 62 79 74 65 20  terminator byte 
86e0: 72 65 71 75 69 72 65 64 20 62 79 20 78 4f 70 65  required by xOpe
86f0: 6e 29 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 7a  n)..  */.  if( z
8700: 4e 61 6d 65 20 29 7b 0a 20 20 20 20 6e 4e 61 6d  Name ){.    nNam
8710: 65 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  e = (int)strlen(
8720: 7a 4e 61 6d 65 29 3b 0a 20 20 7d 0a 0a 20 20 6e  zName);.  }..  n
8730: 42 79 74 65 20 3d 20 28 0a 20 20 20 20 73 69 7a  Byte = (.    siz
8740: 65 6f 66 28 41 73 79 6e 63 46 69 6c 65 44 61 74  eof(AsyncFileDat
8750: 61 29 20 2b 20 20 20 20 20 20 20 20 2f 2a 20 41  a) +        /* A
8760: 73 79 6e 63 46 69 6c 65 44 61 74 61 20 73 74 72  syncFileData str
8770: 75 63 74 75 72 65 20 2a 2f 0a 20 20 20 20 32 20  ucture */.    2 
8780: 2a 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65  * pVfs->szOsFile
8790: 20 2b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20   +           /* 
87a0: 41 73 79 6e 63 46 69 6c 65 44 61 74 61 2e 70 42  AsyncFileData.pB
87b0: 61 73 65 52 65 61 64 20 61 6e 64 20 70 42 61 73  aseRead and pBas
87c0: 65 57 72 69 74 65 20 2a 2f 0a 20 20 20 20 6e 4e  eWrite */.    nN
87d0: 61 6d 65 20 2b 20 32 20 20 20 20 20 20 20 20 20  ame + 2         
87e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
87f0: 41 73 79 6e 63 46 69 6c 65 44 61 74 61 2e 7a 4e  AsyncFileData.zN
8800: 61 6d 65 20 2a 2f 0a 20 20 29 3b 20 0a 20 20 7a  ame */.  ); .  z
8810: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
8820: 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20  c(nByte);.  if( 
8830: 21 7a 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  !z ){.    return
8840: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
8850: 20 7d 0a 20 20 6d 65 6d 73 65 74 28 7a 2c 20 30   }.  memset(z, 0
8860: 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70 44 61 74  , nByte);.  pDat
8870: 61 20 3d 20 28 41 73 79 6e 63 46 69 6c 65 44 61  a = (AsyncFileDa
8880: 74 61 2a 29 7a 3b 0a 20 20 7a 20 2b 3d 20 73 69  ta*)z;.  z += si
8890: 7a 65 6f 66 28 70 44 61 74 61 5b 30 5d 29 3b 0a  zeof(pData[0]);.
88a0: 20 20 70 44 61 74 61 2d 3e 70 42 61 73 65 52 65    pData->pBaseRe
88b0: 61 64 20 3d 20 28 73 71 6c 69 74 65 33 5f 66 69  ad = (sqlite3_fi
88c0: 6c 65 2a 29 7a 3b 0a 20 20 7a 20 2b 3d 20 70 56  le*)z;.  z += pV
88d0: 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 3b 0a 20 20  fs->szOsFile;.  
88e0: 70 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74  pData->pBaseWrit
88f0: 65 20 3d 20 28 73 71 6c 69 74 65 33 5f 66 69 6c  e = (sqlite3_fil
8900: 65 2a 29 7a 3b 0a 20 20 70 44 61 74 61 2d 3e 63  e*)z;.  pData->c
8910: 6c 6f 73 65 4f 70 2e 70 46 69 6c 65 44 61 74 61  loseOp.pFileData
8920: 20 3d 20 70 44 61 74 61 3b 0a 20 20 70 44 61 74   = pData;.  pDat
8930: 61 2d 3e 63 6c 6f 73 65 4f 70 2e 6f 70 20 3d 20  a->closeOp.op = 
8940: 41 53 59 4e 43 5f 43 4c 4f 53 45 3b 0a 0a 20 20  ASYNC_CLOSE;..  
8950: 69 66 28 20 7a 4e 61 6d 65 20 29 7b 0a 20 20 20  if( zName ){.   
8960: 20 7a 20 2b 3d 20 70 56 66 73 2d 3e 73 7a 4f 73   z += pVfs->szOs
8970: 46 69 6c 65 3b 0a 20 20 20 20 70 44 61 74 61 2d  File;.    pData-
8980: 3e 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 20  >zName = z;.    
8990: 70 44 61 74 61 2d 3e 6e 4e 61 6d 65 20 3d 20 6e  pData->nName = n
89a0: 4e 61 6d 65 3b 0a 20 20 20 20 6d 65 6d 63 70 79  Name;.    memcpy
89b0: 28 70 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 7a  (pData->zName, z
89c0: 4e 61 6d 65 2c 20 6e 4e 61 6d 65 29 3b 0a 20 20  Name, nName);.  
89d0: 7d 0a 0a 20 20 69 66 28 20 21 69 73 41 73 79 6e  }..  if( !isAsyn
89e0: 63 4f 70 65 6e 20 29 7b 0a 20 20 20 20 69 6e 74  cOpen ){.    int
89f0: 20 66 6c 61 67 73 6f 75 74 3b 0a 20 20 20 20 72   flagsout;.    r
8a00: 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65 6e 28  c = pVfs->xOpen(
8a10: 70 56 66 73 2c 20 70 44 61 74 61 2d 3e 7a 4e 61  pVfs, pData->zNa
8a20: 6d 65 2c 20 70 44 61 74 61 2d 3e 70 42 61 73 65  me, pData->pBase
8a30: 52 65 61 64 2c 20 66 6c 61 67 73 2c 20 26 66 6c  Read, flags, &fl
8a40: 61 67 73 6f 75 74 29 3b 0a 20 20 20 20 69 66 28  agsout);.    if(
8a50: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 0a   rc==SQLITE_OK .
8a60: 20 20 20 20 20 26 26 20 28 66 6c 61 67 73 6f 75       && (flagsou
8a70: 74 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45  t&SQLITE_OPEN_RE
8a80: 41 44 57 52 49 54 45 29 20 0a 20 20 20 20 20 26  ADWRITE) .     &
8a90: 26 20 28 66 6c 61 67 73 26 53 51 4c 49 54 45 5f  & (flags&SQLITE_
8aa0: 4f 50 45 4e 5f 45 58 43 4c 55 53 49 56 45 29 3d  OPEN_EXCLUSIVE)=
8ab0: 3d 30 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  =0.    ){.      
8ac0: 72 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65 6e  rc = pVfs->xOpen
8ad0: 28 70 56 66 73 2c 20 70 44 61 74 61 2d 3e 7a 4e  (pVfs, pData->zN
8ae0: 61 6d 65 2c 20 70 44 61 74 61 2d 3e 70 42 61 73  ame, pData->pBas
8af0: 65 57 72 69 74 65 2c 20 66 6c 61 67 73 2c 20 30  eWrite, flags, 0
8b00: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
8b10: 20 70 4f 75 74 46 6c 61 67 73 20 29 7b 0a 20 20   pOutFlags ){.  
8b20: 20 20 20 20 2a 70 4f 75 74 46 6c 61 67 73 20 3d      *pOutFlags =
8b30: 20 66 6c 61 67 73 6f 75 74 3b 0a 20 20 20 20 7d   flagsout;.    }
8b40: 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63 5f 6d 75  .  }..  async_mu
8b50: 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f  tex_enter(ASYNC_
8b60: 4d 55 54 45 58 5f 4c 4f 43 4b 29 3b 0a 0a 20 20  MUTEX_LOCK);..  
8b70: 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 72 63 3d  if( zName && rc=
8b80: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
8b90: 20 20 70 4c 6f 63 6b 20 3d 20 66 69 6e 64 4c 6f    pLock = findLo
8ba0: 63 6b 28 70 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c  ck(pData->zName,
8bb0: 20 70 44 61 74 61 2d 3e 6e 4e 61 6d 65 29 3b 0a   pData->nName);.
8bc0: 20 20 20 20 69 66 28 20 21 70 4c 6f 63 6b 20 29      if( !pLock )
8bd0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74  {.      int nByt
8be0: 65 20 3d 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69  e = pVfs->szOsFi
8bf0: 6c 65 20 2b 20 73 69 7a 65 6f 66 28 41 73 79 6e  le + sizeof(Asyn
8c00: 63 4c 6f 63 6b 29 20 2b 20 70 44 61 74 61 2d 3e  cLock) + pData->
8c10: 6e 4e 61 6d 65 20 2b 20 31 3b 20 0a 20 20 20 20  nName + 1; .    
8c20: 20 20 70 4c 6f 63 6b 20 3d 20 28 41 73 79 6e 63    pLock = (Async
8c30: 4c 6f 63 6b 20 2a 29 73 71 6c 69 74 65 33 5f 6d  Lock *)sqlite3_m
8c40: 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20  alloc(nByte);.  
8c50: 20 20 20 20 69 66 28 20 70 4c 6f 63 6b 20 29 7b      if( pLock ){
8c60: 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28  .        memset(
8c70: 70 4c 6f 63 6b 2c 20 30 2c 20 6e 42 79 74 65 29  pLock, 0, nByte)
8c80: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 73  ;.        if( as
8c90: 79 6e 63 2e 62 4c 6f 63 6b 46 69 6c 65 73 20 26  ync.bLockFiles &
8ca0: 26 20 28 66 6c 61 67 73 26 53 51 4c 49 54 45 5f  & (flags&SQLITE_
8cb0: 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 29 20 29 7b  OPEN_MAIN_DB) ){
8cc0: 0a 20 20 20 20 20 20 20 20 20 20 70 4c 6f 63 6b  .          pLock
8cd0: 2d 3e 70 46 69 6c 65 20 3d 20 28 73 71 6c 69 74  ->pFile = (sqlit
8ce0: 65 33 5f 66 69 6c 65 20 2a 29 26 70 4c 6f 63 6b  e3_file *)&pLock
8cf0: 5b 31 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 72  [1];.          r
8d00: 63 20 3d 20 70 56 66 73 2d 3e 78 4f 70 65 6e 28  c = pVfs->xOpen(
8d10: 70 56 66 73 2c 20 70 44 61 74 61 2d 3e 7a 4e 61  pVfs, pData->zNa
8d20: 6d 65 2c 20 70 4c 6f 63 6b 2d 3e 70 46 69 6c 65  me, pLock->pFile
8d30: 2c 20 66 6c 61 67 73 2c 20 30 29 3b 0a 20 20 20  , flags, 0);.   
8d40: 20 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53         if( rc!=S
8d50: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
8d60: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
8d70: 66 72 65 65 28 70 4c 6f 63 6b 29 3b 0a 20 20 20  free(pLock);.   
8d80: 20 20 20 20 20 20 20 20 20 70 4c 6f 63 6b 20 3d           pLock =
8d90: 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a   0;.          }.
8da0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
8db0: 20 20 69 66 28 20 70 4c 6f 63 6b 20 29 7b 0a 20    if( pLock ){. 
8dc0: 20 20 20 20 20 20 20 20 20 70 4c 6f 63 6b 2d 3e           pLock->
8dd0: 6e 46 69 6c 65 20 3d 20 70 44 61 74 61 2d 3e 6e  nFile = pData->n
8de0: 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 20 20  Name;.          
8df0: 70 4c 6f 63 6b 2d 3e 7a 46 69 6c 65 20 3d 20 26  pLock->zFile = &
8e00: 28 28 63 68 61 72 20 2a 29 28 26 70 4c 6f 63 6b  ((char *)(&pLock
8e10: 5b 31 5d 29 29 5b 70 56 66 73 2d 3e 73 7a 4f 73  [1]))[pVfs->szOs
8e20: 46 69 6c 65 5d 3b 0a 20 20 20 20 20 20 20 20 20  File];.         
8e30: 20 6d 65 6d 63 70 79 28 70 4c 6f 63 6b 2d 3e 7a   memcpy(pLock->z
8e40: 46 69 6c 65 2c 20 70 44 61 74 61 2d 3e 7a 4e 61  File, pData->zNa
8e50: 6d 65 2c 20 70 4c 6f 63 6b 2d 3e 6e 46 69 6c 65  me, pLock->nFile
8e60: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70 4c 6f  );.          pLo
8e70: 63 6b 2d 3e 70 4e 65 78 74 20 3d 20 61 73 79 6e  ck->pNext = asyn
8e80: 63 2e 70 4c 6f 63 6b 3b 0a 20 20 20 20 20 20 20  c.pLock;.       
8e90: 20 20 20 61 73 79 6e 63 2e 70 4c 6f 63 6b 20 3d     async.pLock =
8ea0: 20 70 4c 6f 63 6b 3b 0a 20 20 20 20 20 20 20 20   pLock;.        
8eb0: 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  }.      }else{. 
8ec0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
8ed0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
8ee0: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  }.    }.  }..  i
8ef0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
8f00: 20 29 7b 0a 20 20 20 20 70 2d 3e 70 4d 65 74 68   ){.    p->pMeth
8f10: 6f 64 20 3d 20 26 61 73 79 6e 63 5f 6d 65 74 68  od = &async_meth
8f20: 6f 64 73 3b 0a 20 20 20 20 70 2d 3e 70 44 61 74  ods;.    p->pDat
8f30: 61 20 3d 20 70 44 61 74 61 3b 0a 0a 20 20 20 20  a = pData;..    
8f40: 2f 2a 20 4c 69 6e 6b 20 41 73 79 6e 63 46 69 6c  /* Link AsyncFil
8f50: 65 44 61 74 61 2e 6c 6f 63 6b 20 69 6e 74 6f 20  eData.lock into 
8f60: 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20  the linked list 
8f70: 6f 66 20 0a 20 20 20 20 2a 2a 20 41 73 79 6e 63  of .    ** Async
8f80: 46 69 6c 65 4c 6f 63 6b 20 73 74 72 75 63 74 75  FileLock structu
8f90: 72 65 73 20 66 6f 72 20 74 68 69 73 20 66 69 6c  res for this fil
8fa0: 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  e..    */.    if
8fb0: 28 20 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 20  ( zName ){.     
8fc0: 20 70 44 61 74 61 2d 3e 6c 6f 63 6b 2e 70 4e 65   pData->lock.pNe
8fd0: 78 74 20 3d 20 70 4c 6f 63 6b 2d 3e 70 4c 69 73  xt = pLock->pLis
8fe0: 74 3b 0a 20 20 20 20 20 20 70 4c 6f 63 6b 2d 3e  t;.      pLock->
8ff0: 70 4c 69 73 74 20 3d 20 26 70 44 61 74 61 2d 3e  pList = &pData->
9000: 6c 6f 63 6b 3b 0a 20 20 20 20 20 20 70 44 61 74  lock;.      pDat
9010: 61 2d 3e 7a 4e 61 6d 65 20 3d 20 70 4c 6f 63 6b  a->zName = pLock
9020: 2d 3e 7a 46 69 6c 65 3b 0a 20 20 20 20 7d 0a 20  ->zFile;.    }. 
9030: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20   }else{.    if( 
9040: 70 44 61 74 61 2d 3e 70 42 61 73 65 52 65 61 64  pData->pBaseRead
9050: 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b 0a 20 20  ->pMethods ){.  
9060: 20 20 20 20 70 44 61 74 61 2d 3e 70 42 61 73 65      pData->pBase
9070: 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  Read->pMethods->
9080: 78 43 6c 6f 73 65 28 70 44 61 74 61 2d 3e 70 42  xClose(pData->pB
9090: 61 73 65 52 65 61 64 29 3b 0a 20 20 20 20 7d 0a  aseRead);.    }.
90a0: 20 20 20 20 69 66 28 20 70 44 61 74 61 2d 3e 70      if( pData->p
90b0: 42 61 73 65 57 72 69 74 65 2d 3e 70 4d 65 74 68  BaseWrite->pMeth
90c0: 6f 64 73 20 29 7b 0a 20 20 20 20 20 20 70 44 61  ods ){.      pDa
90d0: 74 61 2d 3e 70 42 61 73 65 57 72 69 74 65 2d 3e  ta->pBaseWrite->
90e0: 70 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73 65  pMethods->xClose
90f0: 28 70 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69  (pData->pBaseWri
9100: 74 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73  te);.    }.    s
9110: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 44 61 74  qlite3_free(pDat
9120: 61 29 3b 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63  a);.  }..  async
9130: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59  _mutex_leave(ASY
9140: 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b 29 3b 0a  NC_MUTEX_LOCK);.
9150: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
9160: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 44 61 74  E_OK ){.    pDat
9170: 61 2d 3e 70 4c 6f 63 6b 20 3d 20 70 4c 6f 63 6b  a->pLock = pLock
9180: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
9190: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 73  =SQLITE_OK && is
91a0: 41 73 79 6e 63 4f 70 65 6e 20 29 7b 0a 20 20 20  AsyncOpen ){.   
91b0: 20 72 63 20 3d 20 61 64 64 4e 65 77 41 73 79 6e   rc = addNewAsyn
91c0: 63 57 72 69 74 65 28 70 44 61 74 61 2c 20 41 53  cWrite(pData, AS
91d0: 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56  YNC_OPENEXCLUSIV
91e0: 45 2c 20 28 73 71 6c 69 74 65 33 5f 69 6e 74 36  E, (sqlite3_int6
91f0: 34 29 66 6c 61 67 73 2c 30 2c 30 29 3b 0a 20 20  4)flags,0,0);.  
9200: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
9210: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28  _OK ){.      if(
9220: 20 70 4f 75 74 46 6c 61 67 73 20 29 20 2a 70 4f   pOutFlags ) *pO
9230: 75 74 46 6c 61 67 73 20 3d 20 66 6c 61 67 73 3b  utFlags = flags;
9240: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
9250: 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e    async_mutex_en
9260: 74 65 72 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f  ter(ASYNC_MUTEX_
9270: 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20 75 6e 6c  LOCK);.      unl
9280: 69 6e 6b 41 73 79 6e 63 46 69 6c 65 28 70 44 61  inkAsyncFile(pDa
9290: 74 61 29 3b 0a 20 20 20 20 20 20 61 73 79 6e 63  ta);.      async
92a0: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59  _mutex_leave(ASY
92b0: 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b 29 3b 0a  NC_MUTEX_LOCK);.
92c0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
92d0: 65 65 28 70 44 61 74 61 29 3b 0a 20 20 20 20 7d  ee(pData);.    }
92e0: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 53  .  }.  if( rc!=S
92f0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
9300: 70 2d 3e 70 4d 65 74 68 6f 64 20 3d 20 30 3b 0a  p->pMethod = 0;.
9310: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 63    }else{.    inc
9320: 72 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74 28 29  rOpenFileCount()
9330: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
9340: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  rc;.}../*.** Imp
9350: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73  lementation of s
9360: 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 2e 20  qlite3OsDelete. 
9370: 41 64 64 20 61 6e 20 65 6e 74 72 79 20 74 6f 20  Add an entry to 
9380: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 0a  the end of the .
9390: 2a 2a 20 77 72 69 74 65 2d 6f 70 20 71 75 65 75  ** write-op queu
93a0: 65 20 74 6f 20 70 65 72 66 6f 72 6d 20 74 68 65  e to perform the
93b0: 20 64 65 6c 65 74 65 2e 0a 2a 2f 0a 73 74 61 74   delete..*/.stat
93c0: 69 63 20 69 6e 74 20 61 73 79 6e 63 44 65 6c 65  ic int asyncDele
93d0: 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  te(sqlite3_vfs *
93e0: 70 41 73 79 6e 63 56 66 73 2c 20 63 6f 6e 73 74  pAsyncVfs, const
93f0: 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 73 79   char *z, int sy
9400: 6e 63 44 69 72 29 7b 0a 20 20 55 4e 55 53 45 44  ncDir){.  UNUSED
9410: 5f 50 41 52 41 4d 45 54 45 52 28 70 41 73 79 6e  _PARAMETER(pAsyn
9420: 63 56 66 73 29 3b 0a 20 20 72 65 74 75 72 6e 20  cVfs);.  return 
9430: 61 64 64 4e 65 77 41 73 79 6e 63 57 72 69 74 65  addNewAsyncWrite
9440: 28 30 2c 20 41 53 59 4e 43 5f 44 45 4c 45 54 45  (0, ASYNC_DELETE
9450: 2c 20 73 79 6e 63 44 69 72 2c 20 28 69 6e 74 29  , syncDir, (int)
9460: 73 74 72 6c 65 6e 28 7a 29 2b 31 2c 20 7a 29 3b  strlen(z)+1, z);
9470: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
9480: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 73 71 6c 69  entation of sqli
9490: 74 65 33 4f 73 41 63 63 65 73 73 2e 20 54 68 69  te3OsAccess. Thi
94a0: 73 20 6d 65 74 68 6f 64 20 68 6f 6c 64 73 20 74  s method holds t
94b0: 68 65 20 6d 75 74 65 78 20 66 72 6f 6d 0a 2a 2a  he mutex from.**
94c0: 20 73 74 61 72 74 20 74 6f 20 66 69 6e 69 73 68   start to finish
94d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
94e0: 61 73 79 6e 63 41 63 63 65 73 73 28 0a 20 20 73  asyncAccess(.  s
94f0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 41 73 79  qlite3_vfs *pAsy
9500: 6e 63 56 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20  ncVfs, .  const 
9510: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 0a 20 20  char *zName, .  
9520: 69 6e 74 20 66 6c 61 67 73 2c 0a 20 20 69 6e 74  int flags,.  int
9530: 20 2a 70 52 65 73 4f 75 74 0a 29 7b 0a 20 20 69   *pResOut.){.  i
9540: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 72 65 74  nt rc;.  int ret
9550: 3b 0a 20 20 41 73 79 6e 63 57 72 69 74 65 20 2a  ;.  AsyncWrite *
9560: 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  p;.  sqlite3_vfs
9570: 20 2a 70 56 66 73 20 3d 20 28 73 71 6c 69 74 65   *pVfs = (sqlite
9580: 33 5f 76 66 73 20 2a 29 70 41 73 79 6e 63 56 66  3_vfs *)pAsyncVf
9590: 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20  s->pAppData;..  
95a0: 61 73 73 65 72 74 28 66 6c 61 67 73 3d 3d 53 51  assert(flags==SQ
95b0: 4c 49 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44  LITE_ACCESS_READ
95c0: 57 52 49 54 45 20 0a 20 20 20 20 20 20 7c 7c 20  WRITE .      || 
95d0: 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43  flags==SQLITE_AC
95e0: 43 45 53 53 5f 52 45 41 44 20 0a 20 20 20 20 20  CESS_READ .     
95f0: 20 7c 7c 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54   || flags==SQLIT
9600: 45 5f 41 43 43 45 53 53 5f 45 58 49 53 54 53 20  E_ACCESS_EXISTS 
9610: 0a 20 20 29 3b 0a 0a 20 20 61 73 79 6e 63 5f 6d  .  );..  async_m
9620: 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e 43  utex_enter(ASYNC
9630: 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b 0a 20  _MUTEX_QUEUE);. 
9640: 20 72 63 20 3d 20 70 56 66 73 2d 3e 78 41 63 63   rc = pVfs->xAcc
9650: 65 73 73 28 70 56 66 73 2c 20 7a 4e 61 6d 65 2c  ess(pVfs, zName,
9660: 20 66 6c 61 67 73 2c 20 26 72 65 74 29 3b 0a 20   flags, &ret);. 
9670: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
9680: 4f 4b 20 26 26 20 66 6c 61 67 73 3d 3d 53 51 4c  OK && flags==SQL
9690: 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53 54  ITE_ACCESS_EXIST
96a0: 53 20 29 7b 0a 20 20 20 20 66 6f 72 28 70 3d 61  S ){.    for(p=a
96b0: 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74  sync.pQueueFirst
96c0: 3b 20 70 3b 20 70 20 3d 20 70 2d 3e 70 4e 65 78  ; p; p = p->pNex
96d0: 74 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 2d  t){.      if( p-
96e0: 3e 6f 70 3d 3d 41 53 59 4e 43 5f 44 45 4c 45 54  >op==ASYNC_DELET
96f0: 45 20 26 26 20 30 3d 3d 73 74 72 63 6d 70 28 70  E && 0==strcmp(p
9700: 2d 3e 7a 42 75 66 2c 20 7a 4e 61 6d 65 29 20 29  ->zBuf, zName) )
9710: 7b 0a 20 20 20 20 20 20 20 20 72 65 74 20 3d 20  {.        ret = 
9720: 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  0;.      }else i
9730: 66 28 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f  f( p->op==ASYNC_
9740: 4f 50 45 4e 45 58 43 4c 55 53 49 56 45 20 0a 20  OPENEXCLUSIVE . 
9750: 20 20 20 20 20 20 20 20 20 20 20 20 26 26 20 70              && p
9760: 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61  ->pFileData->zNa
9770: 6d 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  me.             
9780: 26 26 20 30 3d 3d 73 74 72 63 6d 70 28 70 2d 3e  && 0==strcmp(p->
9790: 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65  pFileData->zName
97a0: 2c 20 7a 4e 61 6d 65 29 20 0a 20 20 20 20 20 20  , zName) .      
97b0: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 20 3d  ){.        ret =
97c0: 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   1;.      }.    
97d0: 7d 0a 20 20 7d 0a 20 20 41 53 59 4e 43 5f 54 52  }.  }.  ASYNC_TR
97e0: 41 43 45 28 28 22 41 43 43 45 53 53 28 25 73 29  ACE(("ACCESS(%s)
97f0: 3a 20 25 73 20 3d 20 25 64 5c 6e 22 2c 20 0a 20  : %s = %d\n", . 
9800: 20 20 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45     flags==SQLITE
9810: 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52 49 54  _ACCESS_READWRIT
9820: 45 3f 22 72 65 61 64 2d 77 72 69 74 65 22 3a 0a  E?"read-write":.
9830: 20 20 20 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54      flags==SQLIT
9840: 45 5f 41 43 43 45 53 53 5f 52 45 41 44 3f 22 72  E_ACCESS_READ?"r
9850: 65 61 64 22 3a 22 65 78 69 73 74 73 22 0a 20 20  ead":"exists".  
9860: 20 20 2c 20 7a 4e 61 6d 65 2c 20 72 65 74 29 0a    , zName, ret).
9870: 20 20 29 3b 0a 20 20 61 73 79 6e 63 5f 6d 75 74    );.  async_mut
9880: 65 78 5f 6c 65 61 76 65 28 41 53 59 4e 43 5f 4d  ex_leave(ASYNC_M
9890: 55 54 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 2a  UTEX_QUEUE);.  *
98a0: 70 52 65 73 4f 75 74 20 3d 20 72 65 74 3b 0a 20  pResOut = ret;. 
98b0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
98c0: 2a 0a 2a 2a 20 46 69 6c 6c 20 69 6e 20 7a 50 61  *.** Fill in zPa
98d0: 74 68 4f 75 74 20 77 69 74 68 20 74 68 65 20 66  thOut with the f
98e0: 75 6c 6c 20 70 61 74 68 20 74 6f 20 74 68 65 20  ull path to the 
98f0: 66 69 6c 65 20 69 64 65 6e 74 69 66 69 65 64 20  file identified 
9900: 62 79 20 7a 50 61 74 68 2e 0a 2a 2f 0a 73 74 61  by zPath..*/.sta
9910: 74 69 63 20 69 6e 74 20 61 73 79 6e 63 46 75 6c  tic int asyncFul
9920: 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 73 71 6c  lPathname(.  sql
9930: 69 74 65 33 5f 76 66 73 20 2a 70 41 73 79 6e 63  ite3_vfs *pAsync
9940: 56 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  Vfs, .  const ch
9950: 61 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e  ar *zPath, .  in
9960: 74 20 6e 50 61 74 68 4f 75 74 2c 0a 20 20 63 68  t nPathOut,.  ch
9970: 61 72 20 2a 7a 50 61 74 68 4f 75 74 0a 29 7b 0a  ar *zPathOut.){.
9980: 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69    int rc;.  sqli
9990: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20 3d 20  te3_vfs *pVfs = 
99a0: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 29 70  (sqlite3_vfs *)p
99b0: 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70 44 61  AsyncVfs->pAppDa
99c0: 74 61 3b 0a 20 20 72 63 20 3d 20 70 56 66 73 2d  ta;.  rc = pVfs-
99d0: 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 70  >xFullPathname(p
99e0: 56 66 73 2c 20 7a 50 61 74 68 2c 20 6e 50 61 74  Vfs, zPath, nPat
99f0: 68 4f 75 74 2c 20 7a 50 61 74 68 4f 75 74 29 3b  hOut, zPathOut);
9a00: 0a 0a 20 20 2f 2a 20 42 65 63 61 75 73 65 20 6f  ..  /* Because o
9a10: 66 20 74 68 65 20 77 61 79 20 69 6e 74 72 61 2d  f the way intra-
9a20: 70 72 6f 63 65 73 73 20 66 69 6c 65 20 6c 6f 63  process file loc
9a30: 6b 69 6e 67 20 77 6f 72 6b 73 2c 20 74 68 69 73  king works, this
9a40: 20 62 61 63 6b 65 6e 64 0a 20 20 2a 2a 20 6e 65   backend.  ** ne
9a50: 65 64 73 20 74 6f 20 72 65 74 75 72 6e 20 61 20  eds to return a 
9a60: 63 61 6e 6f 6e 69 63 61 6c 20 70 61 74 68 2e 20  canonical path. 
9a70: 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c  The following bl
9a80: 6f 63 6b 20 61 73 73 75 6d 65 73 20 74 68 65 0a  ock assumes the.
9a90: 20 20 2a 2a 20 66 69 6c 65 2d 73 79 73 74 65 6d    ** file-system
9aa0: 20 75 73 65 73 20 75 6e 69 78 20 73 74 79 6c 65   uses unix style
9ab0: 20 70 61 74 68 73 2e 20 0a 20 20 2a 2f 0a 20 20   paths. .  */.  
9ac0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
9ad0: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20  K ){.    int i, 
9ae0: 6a 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 20 3d  j;.    char *z =
9af0: 20 7a 50 61 74 68 4f 75 74 3b 0a 20 20 20 20 69   zPathOut;.    i
9b00: 6e 74 20 6e 20 3d 20 28 69 6e 74 29 73 74 72 6c  nt n = (int)strl
9b10: 65 6e 28 7a 29 3b 0a 20 20 20 20 77 68 69 6c 65  en(z);.    while
9b20: 28 20 6e 3e 31 20 26 26 20 7a 5b 6e 2d 31 5d 3d  ( n>1 && z[n-1]=
9b30: 3d 27 2f 27 20 29 7b 20 6e 2d 2d 3b 20 7d 0a 20  ='/' ){ n--; }. 
9b40: 20 20 20 66 6f 72 28 69 3d 6a 3d 30 3b 20 69 3c     for(i=j=0; i<
9b50: 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  n; i++){.      i
9b60: 66 28 20 7a 5b 69 5d 3d 3d 27 2f 27 20 29 7b 0a  f( z[i]=='/' ){.
9b70: 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b 69 2b          if( z[i+
9b80: 31 5d 3d 3d 27 2f 27 20 29 20 63 6f 6e 74 69 6e  1]=='/' ) contin
9b90: 75 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  ue;.        if( 
9ba0: 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 26 26 20 69  z[i+1]=='.' && i
9bb0: 2b 32 3c 6e 20 26 26 20 7a 5b 69 2b 32 5d 3d 3d  +2<n && z[i+2]==
9bc0: 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 20 20 20  '/' ){.         
9bd0: 20 69 20 2b 3d 20 31 3b 0a 20 20 20 20 20 20 20   i += 1;.       
9be0: 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20     continue;.   
9bf0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69       }.        i
9c00: 66 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 26  f( z[i+1]=='.' &
9c10: 26 20 69 2b 33 3c 6e 20 26 26 20 7a 5b 69 2b 32  & i+3<n && z[i+2
9c20: 5d 3d 3d 27 2e 27 20 26 26 20 7a 5b 69 2b 33 5d  ]=='.' && z[i+3]
9c30: 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 20  =='/' ){.       
9c40: 20 20 20 77 68 69 6c 65 28 20 6a 3e 30 20 26 26     while( j>0 &&
9c50: 20 7a 5b 6a 2d 31 5d 21 3d 27 2f 27 20 29 7b 20   z[j-1]!='/' ){ 
9c60: 6a 2d 2d 3b 20 7d 0a 20 20 20 20 20 20 20 20 20  j--; }.         
9c70: 20 69 66 28 20 6a 3e 30 20 29 7b 20 6a 2d 2d 3b   if( j>0 ){ j--;
9c80: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69 20 2b   }.          i +
9c90: 3d 20 32 3b 0a 20 20 20 20 20 20 20 20 20 20 63  = 2;.          c
9ca0: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20  ontinue;.       
9cb0: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
9cc0: 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a   z[j++] = z[i];.
9cd0: 20 20 20 20 7d 0a 20 20 20 20 7a 5b 6a 5d 20 3d      }.    z[j] =
9ce0: 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72   0;.  }..  retur
9cf0: 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76  n rc;.}.static v
9d00: 6f 69 64 20 2a 61 73 79 6e 63 44 6c 4f 70 65 6e  oid *asyncDlOpen
9d10: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 41  (sqlite3_vfs *pA
9d20: 73 79 6e 63 56 66 73 2c 20 63 6f 6e 73 74 20 63  syncVfs, const c
9d30: 68 61 72 20 2a 7a 50 61 74 68 29 7b 0a 20 20 73  har *zPath){.  s
9d40: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
9d50: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20   = (sqlite3_vfs 
9d60: 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41 70  *)pAsyncVfs->pAp
9d70: 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72 6e 20  pData;.  return 
9d80: 70 56 66 73 2d 3e 78 44 6c 4f 70 65 6e 28 70 56  pVfs->xDlOpen(pV
9d90: 66 73 2c 20 7a 50 61 74 68 29 3b 0a 7d 0a 73 74  fs, zPath);.}.st
9da0: 61 74 69 63 20 76 6f 69 64 20 61 73 79 6e 63 44  atic void asyncD
9db0: 6c 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76  lError(sqlite3_v
9dc0: 66 73 20 2a 70 41 73 79 6e 63 56 66 73 2c 20 69  fs *pAsyncVfs, i
9dd0: 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a  nt nByte, char *
9de0: 7a 45 72 72 4d 73 67 29 7b 0a 20 20 73 71 6c 69  zErrMsg){.  sqli
9df0: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20 3d 20  te3_vfs *pVfs = 
9e00: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 29 70  (sqlite3_vfs *)p
9e10: 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70 44 61  AsyncVfs->pAppDa
9e20: 74 61 3b 0a 20 20 70 56 66 73 2d 3e 78 44 6c 45  ta;.  pVfs->xDlE
9e30: 72 72 6f 72 28 70 56 66 73 2c 20 6e 42 79 74 65  rror(pVfs, nByte
9e40: 2c 20 7a 45 72 72 4d 73 67 29 3b 0a 7d 0a 73 74  , zErrMsg);.}.st
9e50: 61 74 69 63 20 76 6f 69 64 20 28 2a 61 73 79 6e  atic void (*asyn
9e60: 63 44 6c 53 79 6d 28 0a 20 20 73 71 6c 69 74 65  cDlSym(.  sqlite
9e70: 33 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66 73  3_vfs *pAsyncVfs
9e80: 2c 20 0a 20 20 76 6f 69 64 20 2a 70 48 61 6e 64  , .  void *pHand
9e90: 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  le, .  const cha
9ea0: 72 20 2a 7a 53 79 6d 62 6f 6c 0a 29 29 28 76 6f  r *zSymbol.))(vo
9eb0: 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  id){.  sqlite3_v
9ec0: 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71 6c 69  fs *pVfs = (sqli
9ed0: 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79 6e 63  te3_vfs *)pAsync
9ee0: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20  Vfs->pAppData;. 
9ef0: 20 72 65 74 75 72 6e 20 70 56 66 73 2d 3e 78 44   return pVfs->xD
9f00: 6c 53 79 6d 28 70 56 66 73 2c 20 70 48 61 6e 64  lSym(pVfs, pHand
9f10: 6c 65 2c 20 7a 53 79 6d 62 6f 6c 29 3b 0a 7d 0a  le, zSymbol);.}.
9f20: 73 74 61 74 69 63 20 76 6f 69 64 20 61 73 79 6e  static void asyn
9f30: 63 44 6c 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  cDlClose(sqlite3
9f40: 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66 73 2c  _vfs *pAsyncVfs,
9f50: 20 76 6f 69 64 20 2a 70 48 61 6e 64 6c 65 29 7b   void *pHandle){
9f60: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
9f70: 70 56 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f  pVfs = (sqlite3_
9f80: 76 66 73 20 2a 29 70 41 73 79 6e 63 56 66 73 2d  vfs *)pAsyncVfs-
9f90: 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 70 56 66  >pAppData;.  pVf
9fa0: 73 2d 3e 78 44 6c 43 6c 6f 73 65 28 70 56 66 73  s->xDlClose(pVfs
9fb0: 2c 20 70 48 61 6e 64 6c 65 29 3b 0a 7d 0a 73 74  , pHandle);.}.st
9fc0: 61 74 69 63 20 69 6e 74 20 61 73 79 6e 63 52 61  atic int asyncRa
9fd0: 6e 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33  ndomness(sqlite3
9fe0: 5f 76 66 73 20 2a 70 41 73 79 6e 63 56 66 73 2c  _vfs *pAsyncVfs,
9ff0: 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72   int nByte, char
a000: 20 2a 7a 42 75 66 4f 75 74 29 7b 0a 20 20 73 71   *zBufOut){.  sq
a010: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 20  lite3_vfs *pVfs 
a020: 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  = (sqlite3_vfs *
a030: 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41 70 70  )pAsyncVfs->pApp
a040: 44 61 74 61 3b 0a 20 20 72 65 74 75 72 6e 20 70  Data;.  return p
a050: 56 66 73 2d 3e 78 52 61 6e 64 6f 6d 6e 65 73 73  Vfs->xRandomness
a060: 28 70 56 66 73 2c 20 6e 42 79 74 65 2c 20 7a 42  (pVfs, nByte, zB
a070: 75 66 4f 75 74 29 3b 0a 7d 0a 73 74 61 74 69 63  ufOut);.}.static
a080: 20 69 6e 74 20 61 73 79 6e 63 53 6c 65 65 70 28   int asyncSleep(
a090: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 41 73  sqlite3_vfs *pAs
a0a0: 79 6e 63 56 66 73 2c 20 69 6e 74 20 6e 4d 69 63  yncVfs, int nMic
a0b0: 72 6f 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  ro){.  sqlite3_v
a0c0: 66 73 20 2a 70 56 66 73 20 3d 20 28 73 71 6c 69  fs *pVfs = (sqli
a0d0: 74 65 33 5f 76 66 73 20 2a 29 70 41 73 79 6e 63  te3_vfs *)pAsync
a0e0: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20  Vfs->pAppData;. 
a0f0: 20 72 65 74 75 72 6e 20 70 56 66 73 2d 3e 78 53   return pVfs->xS
a100: 6c 65 65 70 28 70 56 66 73 2c 20 6e 4d 69 63 72  leep(pVfs, nMicr
a110: 6f 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  o);.}.static int
a120: 20 61 73 79 6e 63 43 75 72 72 65 6e 74 54 69 6d   asyncCurrentTim
a130: 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  e(sqlite3_vfs *p
a140: 41 73 79 6e 63 56 66 73 2c 20 64 6f 75 62 6c 65  AsyncVfs, double
a150: 20 2a 70 54 69 6d 65 4f 75 74 29 7b 0a 20 20 73   *pTimeOut){.  s
a160: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
a170: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20   = (sqlite3_vfs 
a180: 2a 29 70 41 73 79 6e 63 56 66 73 2d 3e 70 41 70  *)pAsyncVfs->pAp
a190: 70 44 61 74 61 3b 0a 20 20 72 65 74 75 72 6e 20  pData;.  return 
a1a0: 70 56 66 73 2d 3e 78 43 75 72 72 65 6e 74 54 69  pVfs->xCurrentTi
a1b0: 6d 65 28 70 56 66 73 2c 20 70 54 69 6d 65 4f 75  me(pVfs, pTimeOu
a1c0: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 73 71  t);.}..static sq
a1d0: 6c 69 74 65 33 5f 76 66 73 20 61 73 79 6e 63 5f  lite3_vfs async_
a1e0: 76 66 73 20 3d 20 7b 0a 20 20 31 2c 20 20 20 20  vfs = {.  1,    
a1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a200: 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20  /* iVersion */. 
a210: 20 73 69 7a 65 6f 66 28 41 73 79 6e 63 46 69 6c   sizeof(AsyncFil
a220: 65 29 2c 20 20 20 20 2f 2a 20 73 7a 4f 73 46 69  e),    /* szOsFi
a230: 6c 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  le */.  0,      
a240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a250: 20 6d 78 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20   mxPathname */. 
a260: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
a270: 20 20 20 20 20 20 20 2f 2a 20 70 4e 65 78 74 20         /* pNext 
a280: 2a 2f 0a 20 20 53 51 4c 49 54 45 41 53 59 4e 43  */.  SQLITEASYNC
a290: 5f 56 46 53 4e 41 4d 45 2c 20 20 2f 2a 20 7a 4e  _VFSNAME,  /* zN
a2a0: 61 6d 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ame */.  0,     
a2b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
a2c0: 2a 20 70 41 70 70 44 61 74 61 20 2a 2f 0a 20 20  * pAppData */.  
a2d0: 61 73 79 6e 63 4f 70 65 6e 2c 20 20 20 20 20 20  asyncOpen,      
a2e0: 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2a        /* xOpen *
a2f0: 2f 0a 20 20 61 73 79 6e 63 44 65 6c 65 74 65 2c  /.  asyncDelete,
a300: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
a310: 6c 65 74 65 20 2a 2f 0a 20 20 61 73 79 6e 63 41  lete */.  asyncA
a320: 63 63 65 73 73 2c 20 20 20 20 20 20 20 20 20 20  ccess,          
a330: 2f 2a 20 78 41 63 63 65 73 73 20 2a 2f 0a 20 20  /* xAccess */.  
a340: 61 73 79 6e 63 46 75 6c 6c 50 61 74 68 6e 61 6d  asyncFullPathnam
a350: 65 2c 20 20 20 20 2f 2a 20 78 46 75 6c 6c 50 61  e,    /* xFullPa
a360: 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 61 73 79 6e  thname */.  asyn
a370: 63 44 6c 4f 70 65 6e 2c 20 20 20 20 20 20 20 20  cDlOpen,        
a380: 20 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f 0a    /* xDlOpen */.
a390: 20 20 61 73 79 6e 63 44 6c 45 72 72 6f 72 2c 20    asyncDlError, 
a3a0: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 45 72          /* xDlEr
a3b0: 72 6f 72 20 2a 2f 0a 20 20 61 73 79 6e 63 44 6c  ror */.  asyncDl
a3c0: 53 79 6d 2c 20 20 20 20 20 20 20 20 20 20 20 2f  Sym,           /
a3d0: 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20 20 61 73  * xDlSym */.  as
a3e0: 79 6e 63 44 6c 43 6c 6f 73 65 2c 20 20 20 20 20  yncDlClose,     
a3f0: 20 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20      /* xDlClose 
a400: 2a 2f 0a 20 20 61 73 79 6e 63 52 61 6e 64 6f 6d  */.  asyncRandom
a410: 6e 65 73 73 2c 20 20 20 20 20 20 2f 2a 20 78 44  ness,      /* xD
a420: 6c 45 72 72 6f 72 20 2a 2f 0a 20 20 61 73 79 6e  lError */.  asyn
a430: 63 53 6c 65 65 70 2c 20 20 20 20 20 20 20 20 20  cSleep,         
a440: 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20    /* xDlSym */. 
a450: 20 61 73 79 6e 63 43 75 72 72 65 6e 74 54 69 6d   asyncCurrentTim
a460: 65 20 20 20 20 20 20 2f 2a 20 78 44 6c 43 6c 6f  e      /* xDlClo
a470: 73 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 0a 2a 2a  se */.};../* .**
a480: 20 54 68 69 73 20 70 72 6f 63 65 64 75 72 65 20   This procedure 
a490: 72 75 6e 73 20 69 6e 20 61 20 73 65 70 61 72 61  runs in a separa
a4a0: 74 65 20 74 68 72 65 61 64 2c 20 72 65 61 64 69  te thread, readi
a4b0: 6e 67 20 6d 65 73 73 61 67 65 73 20 6f 66 66 20  ng messages off 
a4c0: 6f 66 20 74 68 65 0a 2a 2a 20 77 72 69 74 65 20  of the.** write 
a4d0: 71 75 65 75 65 20 61 6e 64 20 70 72 6f 63 65 73  queue and proces
a4e0: 73 69 6e 67 20 74 68 65 6d 20 6f 6e 65 20 62 79  sing them one by
a4f0: 20 6f 6e 65 2e 20 20 0a 2a 2a 0a 2a 2a 20 49 66   one.  .**.** If
a500: 20 61 73 79 6e 63 2e 77 72 69 74 65 72 48 61 6c   async.writerHal
a510: 74 4e 6f 77 20 69 73 20 74 72 75 65 2c 20 74 68  tNow is true, th
a520: 65 6e 20 74 68 69 73 20 70 72 6f 63 65 64 75 72  en this procedur
a530: 65 20 65 78 69 74 73 0a 2a 2a 20 61 66 74 65 72  e exits.** after
a540: 20 70 72 6f 63 65 73 73 69 6e 67 20 61 20 73 69   processing a si
a550: 6e 67 6c 65 20 6d 65 73 73 61 67 65 2e 0a 2a 2a  ngle message..**
a560: 0a 2a 2a 20 49 66 20 61 73 79 6e 63 2e 77 72 69  .** If async.wri
a570: 74 65 72 48 61 6c 74 57 68 65 6e 49 64 6c 65 20  terHaltWhenIdle 
a580: 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20 74 68  is true, then th
a590: 69 73 20 70 72 6f 63 65 64 75 72 65 20 65 78 69  is procedure exi
a5a0: 74 73 20 77 68 65 6e 0a 2a 2a 20 74 68 65 20 77  ts when.** the w
a5b0: 72 69 74 65 20 71 75 65 75 65 20 69 73 20 65 6d  rite queue is em
a5c0: 70 74 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 62 6f  pty..**.** If bo
a5d0: 74 68 20 6f 66 20 74 68 65 20 61 62 6f 76 65 20  th of the above 
a5e0: 76 61 72 69 61 62 6c 65 73 20 61 72 65 20 66 61  variables are fa
a5f0: 6c 73 65 2c 20 74 68 69 73 20 70 72 6f 63 65 64  lse, this proced
a600: 75 72 65 20 72 75 6e 73 0a 2a 2a 20 69 6e 64 65  ure runs.** inde
a610: 66 69 6e 61 74 65 6c 79 2c 20 77 61 69 74 69 6e  finately, waitin
a620: 67 20 66 6f 72 20 6f 70 65 72 61 74 69 6f 6e 73  g for operations
a630: 20 74 6f 20 62 65 20 61 64 64 65 64 20 74 6f 20   to be added to 
a640: 74 68 65 20 77 72 69 74 65 20 71 75 65 75 65 0a  the write queue.
a650: 2a 2a 20 61 6e 64 20 70 72 6f 63 65 73 73 69 6e  ** and processin
a660: 67 20 74 68 65 6d 20 69 6e 20 74 68 65 20 6f 72  g them in the or
a670: 64 65 72 20 69 6e 20 77 68 69 63 68 20 74 68 65  der in which the
a680: 79 20 61 72 72 69 76 65 2e 0a 2a 2a 0a 2a 2a 20  y arrive..**.** 
a690: 41 6e 20 61 72 74 69 66 69 63 61 6c 20 64 65 6c  An artifical del
a6a0: 61 79 20 6f 66 20 61 73 79 6e 63 2e 69 6f 44 65  ay of async.ioDe
a6b0: 6c 61 79 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73  lay milliseconds
a6c0: 20 69 73 20 69 6e 73 65 72 74 65 64 20 62 65 66   is inserted bef
a6d0: 6f 72 65 0a 2a 2a 20 65 61 63 68 20 77 72 69 74  ore.** each writ
a6e0: 65 20 6f 70 65 72 61 74 69 6f 6e 20 69 6e 20 6f  e operation in o
a6f0: 72 64 65 72 20 74 6f 20 73 69 6d 75 6c 61 74 65  rder to simulate
a700: 20 74 68 65 20 65 66 66 65 63 74 20 6f 66 20 61   the effect of a
a710: 20 73 6c 6f 77 20 64 69 73 6b 2e 0a 2a 2a 0a 2a   slow disk..**.*
a720: 2a 20 4f 6e 6c 79 20 6f 6e 65 20 69 6e 73 74 61  * Only one insta
a730: 6e 63 65 20 6f 66 20 74 68 69 73 20 70 72 6f 63  nce of this proc
a740: 65 64 75 72 65 20 6d 61 79 20 62 65 20 72 75 6e  edure may be run
a750: 6e 69 6e 67 20 61 74 20 61 20 74 69 6d 65 2e 0a  ning at a time..
a760: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
a770: 73 79 6e 63 57 72 69 74 65 72 54 68 72 65 61 64  syncWriterThread
a780: 28 76 6f 69 64 29 7b 0a 20 20 73 71 6c 69 74 65  (void){.  sqlite
a790: 33 5f 76 66 73 20 2a 70 56 66 73 20 3d 20 28 73  3_vfs *pVfs = (s
a7a0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 29 28 61 73  qlite3_vfs *)(as
a7b0: 79 6e 63 5f 76 66 73 2e 70 41 70 70 44 61 74 61  ync_vfs.pAppData
a7c0: 29 3b 0a 20 20 41 73 79 6e 63 57 72 69 74 65 20  );.  AsyncWrite 
a7d0: 2a 70 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63  *p = 0;.  int rc
a7e0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
a7f0: 69 6e 74 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78  int holdingMutex
a800: 20 3d 20 30 3b 0a 0a 20 20 61 73 79 6e 63 5f 6d   = 0;..  async_m
a810: 75 74 65 78 5f 65 6e 74 65 72 28 41 53 59 4e 43  utex_enter(ASYNC
a820: 5f 4d 55 54 45 58 5f 57 52 49 54 45 52 29 3b 0a  _MUTEX_WRITER);.
a830: 0a 20 20 77 68 69 6c 65 28 20 61 73 79 6e 63 2e  .  while( async.
a840: 65 48 61 6c 74 21 3d 53 51 4c 49 54 45 41 53 59  eHalt!=SQLITEASY
a850: 4e 43 5f 48 41 4c 54 5f 4e 4f 57 20 29 7b 0a 20  NC_HALT_NOW ){. 
a860: 20 20 20 69 6e 74 20 64 6f 4e 6f 74 46 72 65 65     int doNotFree
a870: 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69 74 65   = 0;.    sqlite
a880: 33 5f 66 69 6c 65 20 2a 70 42 61 73 65 20 3d 20  3_file *pBase = 
a890: 30 3b 0a 0a 20 20 20 20 69 66 28 20 21 68 6f 6c  0;..    if( !hol
a8a0: 64 69 6e 67 4d 75 74 65 78 20 29 7b 0a 20 20 20  dingMutex ){.   
a8b0: 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65     async_mutex_e
a8c0: 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54 45 58  nter(ASYNC_MUTEX
a8d0: 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 7d 0a 20  _QUEUE);.    }. 
a8e0: 20 20 20 77 68 69 6c 65 28 20 28 70 20 3d 20 61     while( (p = a
a8f0: 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74  sync.pQueueFirst
a900: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66  )==0 ){.      if
a910: 28 20 61 73 79 6e 63 2e 65 48 61 6c 74 21 3d 53  ( async.eHalt!=S
a920: 51 4c 49 54 45 41 53 59 4e 43 5f 48 41 4c 54 5f  QLITEASYNC_HALT_
a930: 4e 45 56 45 52 20 29 7b 0a 20 20 20 20 20 20 20  NEVER ){.       
a940: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61   async_mutex_lea
a950: 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51  ve(ASYNC_MUTEX_Q
a960: 55 45 55 45 29 3b 0a 20 20 20 20 20 20 20 20 62  UEUE);.        b
a970: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65 6c 73  reak;.      }els
a980: 65 7b 0a 20 20 20 20 20 20 20 20 41 53 59 4e 43  e{.        ASYNC
a990: 5f 54 52 41 43 45 28 28 22 49 44 4c 45 5c 6e 22  _TRACE(("IDLE\n"
a9a0: 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73 79 6e  ));.        asyn
a9b0: 63 5f 63 6f 6e 64 5f 77 61 69 74 28 41 53 59 4e  c_cond_wait(ASYN
a9c0: 43 5f 43 4f 4e 44 5f 51 55 45 55 45 2c 20 41 53  C_COND_QUEUE, AS
a9d0: 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29  YNC_MUTEX_QUEUE)
a9e0: 3b 0a 20 20 20 20 20 20 20 20 41 53 59 4e 43 5f  ;.        ASYNC_
a9f0: 54 52 41 43 45 28 28 22 57 41 4b 45 55 50 5c 6e  TRACE(("WAKEUP\n
aa00: 22 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  "));.      }.   
aa10: 20 7d 0a 20 20 20 20 69 66 28 20 70 3d 3d 30 20   }.    if( p==0 
aa20: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 68 6f 6c  ) break;.    hol
aa30: 64 69 6e 67 4d 75 74 65 78 20 3d 20 31 3b 0a 0a  dingMutex = 1;..
aa40: 20 20 20 20 2f 2a 20 52 69 67 68 74 20 6e 6f 77      /* Right now
aa50: 20 74 68 69 73 20 74 68 72 65 61 64 20 69 73 20   this thread is 
aa60: 68 6f 6c 64 69 6e 67 20 74 68 65 20 6d 75 74 65  holding the mute
aa70: 78 20 6f 6e 20 74 68 65 20 77 72 69 74 65 2d 6f  x on the write-o
aa80: 70 20 71 75 65 75 65 2e 0a 20 20 20 20 2a 2a 20  p queue..    ** 
aa90: 56 61 72 69 61 62 6c 65 20 27 70 27 20 70 6f 69  Variable 'p' poi
aaa0: 6e 74 73 20 74 6f 20 74 68 65 20 66 69 72 73 74  nts to the first
aab0: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 77 72   entry in the wr
aac0: 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 20 49 6e  ite-op queue. In
aad0: 0a 20 20 20 20 2a 2a 20 74 68 65 20 67 65 6e 65  .    ** the gene
aae0: 72 61 6c 20 63 61 73 65 2c 20 77 65 20 68 6f 6c  ral case, we hol
aaf0: 64 20 6f 6e 20 74 6f 20 74 68 65 20 6d 75 74 65  d on to the mute
ab00: 78 20 66 6f 72 20 74 68 65 20 65 6e 74 69 72 65  x for the entire
ab10: 20 62 6f 64 79 20 6f 66 0a 20 20 20 20 2a 2a 20   body of.    ** 
ab20: 74 68 65 20 6c 6f 6f 70 2e 20 0a 20 20 20 20 2a  the loop. .    *
ab30: 2a 0a 20 20 20 20 2a 2a 20 48 6f 77 65 76 65 72  *.    ** However
ab40: 20 69 6e 20 74 68 65 20 63 61 73 65 73 20 65 6e   in the cases en
ab50: 75 6d 65 72 61 74 65 64 20 62 65 6c 6f 77 2c 20  umerated below, 
ab60: 77 65 20 72 65 6c 69 6e 71 75 69 73 68 20 74 68  we relinquish th
ab70: 65 20 6d 75 74 65 78 2c 0a 20 20 20 20 2a 2a 20  e mutex,.    ** 
ab80: 70 65 72 66 6f 72 6d 20 74 68 65 20 49 4f 2c 20  perform the IO, 
ab90: 61 6e 64 20 74 68 65 6e 20 72 65 2d 72 65 71 75  and then re-requ
aba0: 65 73 74 20 74 68 65 20 6d 75 74 65 78 20 62 65  est the mutex be
abb0: 66 6f 72 65 20 72 65 6d 6f 76 69 6e 67 20 27 70  fore removing 'p
abc0: 27 20 66 72 6f 6d 0a 20 20 20 20 2a 2a 20 74 68  ' from.    ** th
abd0: 65 20 68 65 61 64 20 6f 66 20 74 68 65 20 77 72  e head of the wr
abe0: 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 20 54 68  ite-op queue. Th
abf0: 65 20 69 64 65 61 20 69 73 20 74 6f 20 69 6e 63  e idea is to inc
ac00: 72 65 61 73 65 20 63 6f 6e 63 75 72 72 65 6e 63  rease concurrenc
ac10: 79 20 77 69 74 68 0a 20 20 20 20 2a 2a 20 73 71  y with.    ** sq
ac20: 6c 69 74 65 20 74 68 72 65 61 64 73 2e 0a 20 20  lite threads..  
ac30: 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20 20 20 20    **.    **     
ac40: 2a 20 41 6e 20 41 53 59 4e 43 5f 43 4c 4f 53 45  * An ASYNC_CLOSE
ac50: 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20   operation..    
ac60: 2a 2a 20 20 20 20 20 2a 20 41 6e 20 41 53 59 4e  **     * An ASYN
ac70: 43 5f 4f 50 45 4e 45 58 43 4c 55 53 49 56 45 20  C_OPENEXCLUSIVE 
ac80: 6f 70 65 72 61 74 69 6f 6e 2e 20 46 6f 72 20 74  operation. For t
ac90: 68 69 73 20 6f 6e 65 2c 20 77 65 20 72 65 6c 69  his one, we reli
aca0: 6e 71 75 69 73 68 20 0a 20 20 20 20 2a 2a 20 20  nquish .    **  
acb0: 20 20 20 20 20 74 68 65 20 6d 75 74 65 78 2c 20       the mutex, 
acc0: 63 61 6c 6c 20 74 68 65 20 75 6e 64 65 72 6c 79  call the underly
acd0: 69 6e 67 20 78 4f 70 65 6e 45 78 63 6c 75 73 69  ing xOpenExclusi
ace0: 76 65 28 29 20 66 75 6e 63 74 69 6f 6e 2c 20 74  ve() function, t
acf0: 68 65 6e 0a 20 20 20 20 2a 2a 20 20 20 20 20 20  hen.    **      
ad00: 20 72 65 2d 61 71 75 69 72 65 20 74 68 65 20 6d   re-aquire the m
ad10: 75 74 65 78 20 62 65 66 6f 72 65 20 73 65 74 69  utex before seti
ad20: 6e 67 20 74 68 65 20 41 73 79 6e 63 46 69 6c 65  ng the AsyncFile
ad30: 2e 70 42 61 73 65 52 65 61 64 20 0a 20 20 20 20  .pBaseRead .    
ad40: 2a 2a 20 20 20 20 20 20 20 76 61 72 69 61 62 6c  **       variabl
ad50: 65 2e 0a 20 20 20 20 2a 2a 20 20 20 20 20 2a 20  e..    **     * 
ad60: 41 53 59 4e 43 5f 53 59 4e 43 20 61 6e 64 20 41  ASYNC_SYNC and A
ad70: 53 59 4e 43 5f 57 52 49 54 45 20 6f 70 65 72 61  SYNC_WRITE opera
ad80: 74 69 6f 6e 73 2c 20 69 66 20 0a 20 20 20 20 2a  tions, if .    *
ad90: 2a 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 41  *       SQLITE_A
ada0: 53 59 4e 43 5f 54 57 4f 5f 46 49 4c 45 48 41 4e  SYNC_TWO_FILEHAN
adb0: 44 4c 45 53 20 77 61 73 20 73 65 74 20 61 74 20  DLES was set at 
adc0: 63 6f 6d 70 69 6c 65 20 74 69 6d 65 20 61 6e 64  compile time and
add0: 20 74 77 6f 0a 20 20 20 20 2a 2a 20 20 20 20 20   two.    **     
ade0: 20 20 66 69 6c 65 2d 68 61 6e 64 6c 65 73 20 61    file-handles a
adf0: 72 65 20 6f 70 65 6e 20 66 6f 72 20 74 68 65 20  re open for the 
ae00: 70 61 72 74 69 63 75 6c 61 72 20 66 69 6c 65 20  particular file 
ae10: 62 65 69 6e 67 20 22 73 79 6e 63 65 64 22 2e 0a  being "synced"..
ae20: 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 61      */.    if( a
ae30: 73 79 6e 63 2e 69 6f 45 72 72 6f 72 21 3d 53 51  sync.ioError!=SQ
ae40: 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6f 70  LITE_OK && p->op
ae50: 21 3d 41 53 59 4e 43 5f 43 4c 4f 53 45 20 29 7b  !=ASYNC_CLOSE ){
ae60: 0a 20 20 20 20 20 20 70 2d 3e 6f 70 20 3d 20 41  .      p->op = A
ae70: 53 59 4e 43 5f 4e 4f 4f 50 3b 0a 20 20 20 20 7d  SYNC_NOOP;.    }
ae80: 0a 20 20 20 20 69 66 28 20 70 2d 3e 70 46 69 6c  .    if( p->pFil
ae90: 65 44 61 74 61 20 29 7b 0a 20 20 20 20 20 20 70  eData ){.      p
aea0: 42 61 73 65 20 3d 20 70 2d 3e 70 46 69 6c 65 44  Base = p->pFileD
aeb0: 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74 65 3b  ata->pBaseWrite;
aec0: 0a 20 20 20 20 20 20 69 66 28 20 0a 20 20 20 20  .      if( .    
aed0: 20 20 20 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43      p->op==ASYNC
aee0: 5f 43 4c 4f 53 45 20 7c 7c 20 0a 20 20 20 20 20  _CLOSE || .     
aef0: 20 20 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f     p->op==ASYNC_
af00: 4f 50 45 4e 45 58 43 4c 55 53 49 56 45 20 7c 7c  OPENEXCLUSIVE ||
af10: 0a 20 20 20 20 20 20 20 20 28 70 42 61 73 65 2d  .        (pBase-
af20: 3e 70 4d 65 74 68 6f 64 73 20 26 26 20 28 70 2d  >pMethods && (p-
af30: 3e 6f 70 3d 3d 41 53 59 4e 43 5f 53 59 4e 43 20  >op==ASYNC_SYNC 
af40: 7c 7c 20 70 2d 3e 6f 70 3d 3d 41 53 59 4e 43 5f  || p->op==ASYNC_
af50: 57 52 49 54 45 29 20 29 20 0a 20 20 20 20 20 20  WRITE) ) .      
af60: 29 7b 0a 20 20 20 20 20 20 20 20 61 73 79 6e 63  ){.        async
af70: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59  _mutex_leave(ASY
af80: 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b  NC_MUTEX_QUEUE);
af90: 0a 20 20 20 20 20 20 20 20 68 6f 6c 64 69 6e 67  .        holding
afa0: 4d 75 74 65 78 20 3d 20 30 3b 0a 20 20 20 20 20  Mutex = 0;.     
afb0: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 21 70 42   }.      if( !pB
afc0: 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b  ase->pMethods ){
afd0: 0a 20 20 20 20 20 20 20 20 70 42 61 73 65 20 3d  .        pBase =
afe0: 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 70   p->pFileData->p
aff0: 42 61 73 65 52 65 61 64 3b 0a 20 20 20 20 20 20  BaseRead;.      
b000: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 77 69  }.    }..    swi
b010: 74 63 68 28 20 70 2d 3e 6f 70 20 29 7b 0a 20 20  tch( p->op ){.  
b020: 20 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f 4e      case ASYNC_N
b030: 4f 4f 50 3a 0a 20 20 20 20 20 20 20 20 62 72 65  OOP:.        bre
b040: 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 65 20  ak;..      case 
b050: 41 53 59 4e 43 5f 57 52 49 54 45 3a 0a 20 20 20  ASYNC_WRITE:.   
b060: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 42 61       assert( pBa
b070: 73 65 20 29 3b 0a 20 20 20 20 20 20 20 20 41 53  se );.        AS
b080: 59 4e 43 5f 54 52 41 43 45 28 28 22 57 52 49 54  YNC_TRACE(("WRIT
b090: 45 20 25 73 20 25 64 20 62 79 74 65 73 20 61 74  E %s %d bytes at
b0a0: 20 25 64 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20   %d\n",.        
b0b0: 20 20 20 20 20 20 20 20 70 2d 3e 70 46 69 6c 65          p->pFile
b0c0: 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 70 2d 3e  Data->zName, p->
b0d0: 6e 42 79 74 65 2c 20 70 2d 3e 69 4f 66 66 73 65  nByte, p->iOffse
b0e0: 74 29 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20  t));.        rc 
b0f0: 3d 20 70 42 61 73 65 2d 3e 70 4d 65 74 68 6f 64  = pBase->pMethod
b100: 73 2d 3e 78 57 72 69 74 65 28 70 42 61 73 65 2c  s->xWrite(pBase,
b110: 20 28 76 6f 69 64 20 2a 29 28 70 2d 3e 7a 42 75   (void *)(p->zBu
b120: 66 29 2c 20 70 2d 3e 6e 42 79 74 65 2c 20 70 2d  f), p->nByte, p-
b130: 3e 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20  >iOffset);.     
b140: 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20     break;..     
b150: 20 63 61 73 65 20 41 53 59 4e 43 5f 53 59 4e 43   case ASYNC_SYNC
b160: 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  :.        assert
b170: 28 20 70 42 61 73 65 20 29 3b 0a 20 20 20 20 20  ( pBase );.     
b180: 20 20 20 41 53 59 4e 43 5f 54 52 41 43 45 28 28     ASYNC_TRACE((
b190: 22 53 59 4e 43 20 25 73 5c 6e 22 2c 20 70 2d 3e  "SYNC %s\n", p->
b1a0: 70 46 69 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65  pFileData->zName
b1b0: 29 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  ));.        rc =
b1c0: 20 70 42 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73   pBase->pMethods
b1d0: 2d 3e 78 53 79 6e 63 28 70 42 61 73 65 2c 20 70  ->xSync(pBase, p
b1e0: 2d 3e 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20  ->nByte);.      
b1f0: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20    break;..      
b200: 63 61 73 65 20 41 53 59 4e 43 5f 54 52 55 4e 43  case ASYNC_TRUNC
b210: 41 54 45 3a 0a 20 20 20 20 20 20 20 20 61 73 73  ATE:.        ass
b220: 65 72 74 28 20 70 42 61 73 65 20 29 3b 0a 20 20  ert( pBase );.  
b230: 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41 43        ASYNC_TRAC
b240: 45 28 28 22 54 52 55 4e 43 41 54 45 20 25 73 20  E(("TRUNCATE %s 
b250: 74 6f 20 25 64 20 62 79 74 65 73 5c 6e 22 2c 20  to %d bytes\n", 
b260: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
b270: 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 2d 3e 7a   p->pFileData->z
b280: 4e 61 6d 65 2c 20 70 2d 3e 69 4f 66 66 73 65 74  Name, p->iOffset
b290: 29 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  ));.        rc =
b2a0: 20 70 42 61 73 65 2d 3e 70 4d 65 74 68 6f 64 73   pBase->pMethods
b2b0: 2d 3e 78 54 72 75 6e 63 61 74 65 28 70 42 61 73  ->xTruncate(pBas
b2c0: 65 2c 20 70 2d 3e 69 4f 66 66 73 65 74 29 3b 0a  e, p->iOffset);.
b2d0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a          break;..
b2e0: 20 20 20 20 20 20 63 61 73 65 20 41 53 59 4e 43        case ASYNC
b2f0: 5f 43 4c 4f 53 45 3a 20 7b 0a 20 20 20 20 20 20  _CLOSE: {.      
b300: 20 20 41 73 79 6e 63 46 69 6c 65 44 61 74 61 20    AsyncFileData 
b310: 2a 70 44 61 74 61 20 3d 20 70 2d 3e 70 46 69 6c  *pData = p->pFil
b320: 65 44 61 74 61 3b 0a 20 20 20 20 20 20 20 20 41  eData;.        A
b330: 53 59 4e 43 5f 54 52 41 43 45 28 28 22 43 4c 4f  SYNC_TRACE(("CLO
b340: 53 45 20 25 73 5c 6e 22 2c 20 70 2d 3e 70 46 69  SE %s\n", p->pFi
b350: 6c 65 44 61 74 61 2d 3e 7a 4e 61 6d 65 29 29 3b  leData->zName));
b360: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 44 61  .        if( pDa
b370: 74 61 2d 3e 70 42 61 73 65 57 72 69 74 65 2d 3e  ta->pBaseWrite->
b380: 70 4d 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20  pMethods ){.    
b390: 20 20 20 20 20 20 70 44 61 74 61 2d 3e 70 42 61        pData->pBa
b3a0: 73 65 57 72 69 74 65 2d 3e 70 4d 65 74 68 6f 64  seWrite->pMethod
b3b0: 73 2d 3e 78 43 6c 6f 73 65 28 70 44 61 74 61 2d  s->xClose(pData-
b3c0: 3e 70 42 61 73 65 57 72 69 74 65 29 3b 0a 20 20  >pBaseWrite);.  
b3d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
b3e0: 69 66 28 20 70 44 61 74 61 2d 3e 70 42 61 73 65  if( pData->pBase
b3f0: 52 65 61 64 2d 3e 70 4d 65 74 68 6f 64 73 20 29  Read->pMethods )
b400: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 44 61 74  {.          pDat
b410: 61 2d 3e 70 42 61 73 65 52 65 61 64 2d 3e 70 4d  a->pBaseRead->pM
b420: 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70  ethods->xClose(p
b430: 44 61 74 61 2d 3e 70 42 61 73 65 52 65 61 64 29  Data->pBaseRead)
b440: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20  ;.        }..   
b450: 20 20 20 20 20 2f 2a 20 55 6e 6c 69 6e 6b 20 41       /* Unlink A
b460: 73 79 6e 63 46 69 6c 65 44 61 74 61 2e 6c 6f 63  syncFileData.loc
b470: 6b 20 66 72 6f 6d 20 74 68 65 20 6c 69 6e 6b 65  k from the linke
b480: 64 20 6c 69 73 74 20 6f 66 20 41 73 79 6e 63 46  d list of AsyncF
b490: 69 6c 65 4c 6f 63 6b 20 0a 20 20 20 20 20 20 20  ileLock .       
b4a0: 20 2a 2a 20 73 74 72 75 63 74 75 72 65 73 20 66   ** structures f
b4b0: 6f 72 20 74 68 69 73 20 66 69 6c 65 2e 20 4f 62  or this file. Ob
b4c0: 74 61 69 6e 20 74 68 65 20 61 73 79 6e 63 2e 6c  tain the async.l
b4d0: 6f 63 6b 4d 75 74 65 78 20 6d 75 74 65 78 20 0a  ockMutex mutex .
b4e0: 20 20 20 20 20 20 20 20 2a 2a 20 62 65 66 6f 72          ** befor
b4f0: 65 20 64 6f 69 6e 67 20 73 6f 2e 0a 20 20 20 20  e doing so..    
b500: 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 61      */.        a
b510: 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65 72  sync_mutex_enter
b520: 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43  (ASYNC_MUTEX_LOC
b530: 4b 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  K);.        rc =
b540: 20 75 6e 6c 69 6e 6b 41 73 79 6e 63 46 69 6c 65   unlinkAsyncFile
b550: 28 70 44 61 74 61 29 3b 0a 20 20 20 20 20 20 20  (pData);.       
b560: 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61   async_mutex_lea
b570: 76 65 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c  ve(ASYNC_MUTEX_L
b580: 4f 43 4b 29 3b 0a 0a 20 20 20 20 20 20 20 20 69  OCK);..        i
b590: 66 28 20 21 68 6f 6c 64 69 6e 67 4d 75 74 65 78  f( !holdingMutex
b5a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 61 73   ){.          as
b5b0: 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28  ync_mutex_enter(
b5c0: 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55  ASYNC_MUTEX_QUEU
b5d0: 45 29 3b 0a 20 20 20 20 20 20 20 20 20 20 68 6f  E);.          ho
b5e0: 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20 31 3b 0a  ldingMutex = 1;.
b5f0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
b600: 20 20 61 73 73 65 72 74 5f 6d 75 74 65 78 5f 69    assert_mutex_i
b610: 73 5f 68 65 6c 64 28 41 53 59 4e 43 5f 4d 55 54  s_held(ASYNC_MUT
b620: 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20  EX_QUEUE);.     
b630: 20 20 20 61 73 79 6e 63 2e 70 51 75 65 75 65 46     async.pQueueF
b640: 69 72 73 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b  irst = p->pNext;
b650: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
b660: 5f 66 72 65 65 28 70 44 61 74 61 29 3b 0a 20 20  _free(pData);.  
b670: 20 20 20 20 20 20 64 6f 4e 6f 74 46 72 65 65 20        doNotFree 
b680: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 62 72 65  = 1;.        bre
b690: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  ak;.      }..   
b6a0: 20 20 20 63 61 73 65 20 41 53 59 4e 43 5f 55 4e     case ASYNC_UN
b6b0: 4c 4f 43 4b 3a 20 7b 0a 20 20 20 20 20 20 20 20  LOCK: {.        
b6c0: 41 73 79 6e 63 57 72 69 74 65 20 2a 70 49 74 65  AsyncWrite *pIte
b6d0: 72 3b 0a 20 20 20 20 20 20 20 20 41 73 79 6e 63  r;.        Async
b6e0: 46 69 6c 65 44 61 74 61 20 2a 70 44 61 74 61 20  FileData *pData 
b6f0: 3d 20 70 2d 3e 70 46 69 6c 65 44 61 74 61 3b 0a  = p->pFileData;.
b700: 20 20 20 20 20 20 20 20 69 6e 74 20 65 4c 6f 63          int eLoc
b710: 6b 20 3d 20 70 2d 3e 6e 42 79 74 65 3b 0a 0a 20  k = p->nByte;.. 
b720: 20 20 20 20 20 20 20 2f 2a 20 57 68 65 6e 20 61         /* When a
b730: 20 66 69 6c 65 20 69 73 20 6c 6f 63 6b 65 64 20   file is locked 
b740: 62 79 20 53 51 4c 69 74 65 20 75 73 69 6e 67 20  by SQLite using 
b750: 74 68 65 20 61 73 79 6e 63 20 62 61 63 6b 65 6e  the async backen
b760: 64 2c 20 69 74 20 69 73 20 0a 20 20 20 20 20 20  d, it is .      
b770: 20 20 2a 2a 20 6c 6f 63 6b 65 64 20 77 69 74 68    ** locked with
b780: 69 6e 20 74 68 65 20 27 72 65 61 6c 27 20 66 69  in the 'real' fi
b790: 6c 65 2d 73 79 73 74 65 6d 20 73 79 6e 63 68 72  le-system synchr
b7a0: 6f 6e 6f 75 73 6c 79 2e 20 57 68 65 6e 20 69 74  onously. When it
b7b0: 20 69 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 75   is.        ** u
b7c0: 6e 6c 6f 63 6b 65 64 2c 20 61 6e 20 41 53 59 4e  nlocked, an ASYN
b7d0: 43 5f 55 4e 4c 4f 43 4b 20 65 76 65 6e 74 20 69  C_UNLOCK event i
b7e0: 73 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 77  s added to the w
b7f0: 72 69 74 65 2d 71 75 65 75 65 20 74 6f 0a 20 20  rite-queue to.  
b800: 20 20 20 20 20 20 2a 2a 20 75 6e 6c 6f 63 6b 20        ** unlock 
b810: 74 68 65 20 66 69 6c 65 20 61 73 79 6e 63 68 72  the file asynchr
b820: 6f 6e 6f 75 73 6c 79 2e 20 54 68 65 20 64 65 73  onously. The des
b830: 69 67 6e 20 6f 66 20 74 68 65 20 61 73 79 6e 63  ign of the async
b840: 20 62 61 63 6b 65 6e 64 0a 20 20 20 20 20 20 20   backend.       
b850: 20 2a 2a 20 72 65 71 75 69 72 65 73 20 74 68 61   ** requires tha
b860: 74 20 74 68 65 20 27 72 65 61 6c 27 20 66 69 6c  t the 'real' fil
b870: 65 2d 73 79 73 74 65 6d 20 66 69 6c 65 20 62 65  e-system file be
b880: 20 6c 6f 63 6b 65 64 20 66 72 6f 6d 20 74 68 65   locked from the
b890: 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 69 6d 65  .        ** time
b8a0: 20 74 68 61 74 20 53 51 4c 69 74 65 20 66 69 72   that SQLite fir
b8b0: 73 74 20 6c 6f 63 6b 73 20 69 74 20 28 61 6e 64  st locks it (and
b8c0: 20 70 72 6f 62 61 62 6c 79 20 72 65 61 64 73 20   probably reads 
b8d0: 66 72 6f 6d 20 69 74 29 0a 20 20 20 20 20 20 20  from it).       
b8e0: 20 2a 2a 20 75 6e 74 69 6c 20 61 6c 6c 20 61 73   ** until all as
b8f0: 79 6e 63 68 72 6f 6e 6f 75 73 20 77 72 69 74 65  ynchronous write
b900: 20 65 76 65 6e 74 73 20 74 68 61 74 20 77 65 72   events that wer
b910: 65 20 73 63 68 65 64 75 6c 65 64 20 62 65 66 6f  e scheduled befo
b920: 72 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 53 51  re.        ** SQ
b930: 4c 69 74 65 20 75 6e 6c 6f 63 6b 65 64 20 74 68  Lite unlocked th
b940: 65 20 66 69 6c 65 20 68 61 76 65 20 62 65 65 6e  e file have been
b950: 20 70 72 6f 63 65 73 73 65 64 2e 0a 20 20 20 20   processed..    
b960: 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a      **.        *
b970: 2a 20 54 68 69 73 20 69 73 20 6d 6f 72 65 20 63  * This is more c
b980: 6f 6d 70 6c 65 78 20 69 66 20 53 51 4c 69 74 65  omplex if SQLite
b990: 20 6c 6f 63 6b 73 20 61 6e 64 20 75 6e 6c 6f 63   locks and unloc
b9a0: 6b 73 20 74 68 65 20 66 69 6c 65 20 6d 75 6c 74  ks the file mult
b9b0: 69 70 6c 65 0a 20 20 20 20 20 20 20 20 2a 2a 20  iple.        ** 
b9c0: 74 69 6d 65 73 20 69 6e 20 71 75 69 63 6b 20 73  times in quick s
b9d0: 75 63 63 65 73 73 69 6f 6e 2e 20 46 6f 72 20 65  uccession. For e
b9e0: 78 61 6d 70 6c 65 2c 20 69 66 20 53 51 4c 69 74  xample, if SQLit
b9f0: 65 20 64 6f 65 73 3a 20 0a 20 20 20 20 20 20 20  e does: .       
ba00: 20 2a 2a 20 0a 20 20 20 20 20 20 20 20 2a 2a 20   ** .        ** 
ba10: 20 20 6c 6f 63 6b 2c 20 77 72 69 74 65 2c 20 75    lock, write, u
ba20: 6e 6c 6f 63 6b 2c 20 6c 6f 63 6b 2c 20 77 72 69  nlock, lock, wri
ba30: 74 65 2c 20 75 6e 6c 6f 63 6b 0a 20 20 20 20 20  te, unlock.     
ba40: 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a     **.        **
ba50: 20 45 61 63 68 20 22 6c 6f 63 6b 22 20 6f 70 65   Each "lock" ope
ba60: 72 61 74 69 6f 6e 20 6c 6f 63 6b 73 20 74 68 65  ration locks the
ba70: 20 66 69 6c 65 20 69 6d 6d 65 64 69 61 74 65 6c   file immediatel
ba80: 79 2e 20 45 61 63 68 20 22 77 72 69 74 65 22 20  y. Each "write" 
ba90: 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 6e 64 20  .        ** and 
baa0: 22 75 6e 6c 6f 63 6b 22 20 6f 70 65 72 61 74 69  "unlock" operati
bab0: 6f 6e 20 61 64 64 73 20 61 6e 20 65 76 65 6e 74  on adds an event
bac0: 20 74 6f 20 74 68 65 20 65 76 65 6e 74 20 71 75   to the event qu
bad0: 65 75 65 2e 20 49 66 20 74 68 65 0a 20 20 20 20  eue. If the.    
bae0: 20 20 20 20 2a 2a 20 73 65 63 6f 6e 64 20 22 6c      ** second "l
baf0: 6f 63 6b 22 20 6f 70 65 72 61 74 69 6f 6e 20 69  ock" operation i
bb00: 73 20 70 65 72 66 6f 72 6d 65 64 20 62 65 66 6f  s performed befo
bb10: 72 65 20 74 68 65 20 66 69 72 73 74 20 22 75 6e  re the first "un
bb20: 6c 6f 63 6b 22 0a 20 20 20 20 20 20 20 20 2a 2a  lock".        **
bb30: 20 6f 70 65 72 61 74 69 6f 6e 20 68 61 73 20 62   operation has b
bb40: 65 65 6e 20 70 72 6f 63 65 73 73 65 64 20 61 73  een processed as
bb50: 79 6e 63 68 72 6f 6e 6f 75 73 6c 79 2c 20 74 68  ynchronously, th
bb60: 65 6e 20 74 68 65 20 66 69 72 73 74 0a 20 20 20  en the first.   
bb70: 20 20 20 20 20 2a 2a 20 22 75 6e 6c 6f 63 6b 22       ** "unlock"
bb80: 20 63 61 6e 6e 6f 74 20 62 65 20 73 61 66 65 6c   cannot be safel
bb90: 79 20 70 72 6f 63 65 73 73 65 64 20 61 73 20 69  y processed as i
bba0: 73 2c 20 73 69 6e 63 65 20 74 68 69 73 20 77 6f  s, since this wo
bbb0: 75 6c 64 20 6d 65 61 6e 0a 20 20 20 20 20 20 20  uld mean.       
bbc0: 20 2a 2a 20 74 68 65 20 66 69 6c 65 20 77 61 73   ** the file was
bbd0: 20 75 6e 6c 6f 63 6b 65 64 20 77 68 65 6e 20 74   unlocked when t
bbe0: 68 65 20 73 65 63 6f 6e 64 20 22 77 72 69 74 65  he second "write
bbf0: 22 20 6f 70 65 72 61 74 69 6f 6e 20 69 73 0a 20  " operation is. 
bc00: 20 20 20 20 20 20 20 2a 2a 20 70 72 6f 63 65 73         ** proces
bc10: 73 65 64 2e 20 54 6f 20 77 6f 72 6b 20 61 72 6f  sed. To work aro
bc20: 75 6e 64 20 74 68 69 73 2c 20 77 68 65 6e 20 70  und this, when p
bc30: 72 6f 63 65 73 73 69 6e 67 20 61 6e 20 41 53 59  rocessing an ASY
bc40: 4e 43 5f 55 4e 4c 4f 43 4b 0a 20 20 20 20 20 20  NC_UNLOCK.      
bc50: 20 20 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 2c 20    ** operation, 
bc60: 53 51 4c 69 74 65 3a 0a 20 20 20 20 20 20 20 20  SQLite:.        
bc70: 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 20 20  **.        **   
bc80: 31 29 20 55 6e 6c 6f 63 6b 73 20 74 68 65 20 66  1) Unlocks the f
bc90: 69 6c 65 20 74 6f 20 74 68 65 20 6d 69 6e 69 6d  ile to the minim
bca0: 75 6d 20 6f 66 20 74 68 65 20 61 72 67 75 6d 65  um of the argume
bcb0: 6e 74 20 70 61 73 73 65 64 20 74 6f 0a 20 20 20  nt passed to.   
bcc0: 20 20 20 20 20 2a 2a 20 20 20 20 20 20 74 68 65       **      the
bcd0: 20 78 55 6e 6c 6f 63 6b 28 29 20 63 61 6c 6c 20   xUnlock() call 
bce0: 61 6e 64 20 74 68 65 20 63 75 72 72 65 6e 74 20  and the current 
bcf0: 6c 6f 63 6b 20 66 72 6f 6d 20 53 51 4c 69 74 65  lock from SQLite
bd00: 27 73 20 70 6f 69 6e 74 0a 20 20 20 20 20 20 20  's point.       
bd10: 20 2a 2a 20 20 20 20 20 20 6f 66 20 76 69 65 77   **      of view
bd20: 2c 20 61 6e 64 0a 20 20 20 20 20 20 20 20 2a 2a  , and.        **
bd30: 0a 20 20 20 20 20 20 20 20 2a 2a 20 20 20 32 29  .        **   2)
bd40: 20 4f 6e 6c 79 20 75 6e 6c 6f 63 6b 73 20 74 68   Only unlocks th
bd50: 65 20 66 69 6c 65 20 61 74 20 61 6c 6c 20 69 66  e file at all if
bd60: 20 74 68 69 73 20 65 76 65 6e 74 20 69 73 20 74   this event is t
bd70: 68 65 20 6c 61 73 74 0a 20 20 20 20 20 20 20 20  he last.        
bd80: 2a 2a 20 20 20 20 20 20 41 53 59 4e 43 5f 55 4e  **      ASYNC_UN
bd90: 4c 4f 43 4b 20 65 76 65 6e 74 20 6f 6e 20 74 68  LOCK event on th
bda0: 69 73 20 66 69 6c 65 20 69 6e 20 74 68 65 20 77  is file in the w
bdb0: 72 69 74 65 2d 71 75 65 75 65 2e 0a 20 20 20 20  rite-queue..    
bdc0: 20 20 20 20 2a 2f 20 0a 20 20 20 20 20 20 20 20      */ .        
bdd0: 61 73 73 65 72 74 28 20 68 6f 6c 64 69 6e 67 4d  assert( holdingM
bde0: 75 74 65 78 3d 3d 31 20 29 3b 0a 20 20 20 20 20  utex==1 );.     
bdf0: 20 20 20 61 73 73 65 72 74 28 20 61 73 79 6e 63     assert( async
be00: 2e 70 51 75 65 75 65 46 69 72 73 74 3d 3d 70 20  .pQueueFirst==p 
be10: 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 70  );.        for(p
be20: 49 74 65 72 3d 61 73 79 6e 63 2e 70 51 75 65 75  Iter=async.pQueu
be30: 65 46 69 72 73 74 2d 3e 70 4e 65 78 74 3b 20 70  eFirst->pNext; p
be40: 49 74 65 72 3b 20 70 49 74 65 72 3d 70 49 74 65  Iter; pIter=pIte
be50: 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20  r->pNext){.     
be60: 20 20 20 20 20 69 66 28 20 70 49 74 65 72 2d 3e       if( pIter->
be70: 70 46 69 6c 65 44 61 74 61 3d 3d 70 44 61 74 61  pFileData==pData
be80: 20 26 26 20 70 49 74 65 72 2d 3e 6f 70 3d 3d 41   && pIter->op==A
be90: 53 59 4e 43 5f 55 4e 4c 4f 43 4b 20 29 20 62 72  SYNC_UNLOCK ) br
bea0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  eak;.        }. 
beb0: 20 20 20 20 20 20 20 69 66 28 20 21 70 49 74 65         if( !pIte
bec0: 72 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 61  r ){.          a
bed0: 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65 72  sync_mutex_enter
bee0: 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43  (ASYNC_MUTEX_LOC
bef0: 4b 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70 44  K);.          pD
bf00: 61 74 61 2d 3e 6c 6f 63 6b 2e 65 41 73 79 6e 63  ata->lock.eAsync
bf10: 4c 6f 63 6b 20 3d 20 4d 49 4e 28 0a 20 20 20 20  Lock = MIN(.    
bf20: 20 20 20 20 20 20 20 20 20 20 70 44 61 74 61 2d            pData-
bf30: 3e 6c 6f 63 6b 2e 65 41 73 79 6e 63 4c 6f 63 6b  >lock.eAsyncLock
bf40: 2c 20 4d 41 58 28 70 44 61 74 61 2d 3e 6c 6f 63  , MAX(pData->loc
bf50: 6b 2e 65 4c 6f 63 6b 2c 20 65 4c 6f 63 6b 29 0a  k.eLock, eLock).
bf60: 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20            );.   
bf70: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 70 44         assert(pD
bf80: 61 74 61 2d 3e 6c 6f 63 6b 2e 65 41 73 79 6e 63  ata->lock.eAsync
bf90: 4c 6f 63 6b 3e 3d 70 44 61 74 61 2d 3e 6c 6f 63  Lock>=pData->loc
bfa0: 6b 2e 65 4c 6f 63 6b 29 3b 0a 20 20 20 20 20 20  k.eLock);.      
bfb0: 20 20 20 20 72 63 20 3d 20 67 65 74 46 69 6c 65      rc = getFile
bfc0: 4c 6f 63 6b 28 70 44 61 74 61 2d 3e 70 4c 6f 63  Lock(pData->pLoc
bfd0: 6b 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73  k);.          as
bfe0: 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  ync_mutex_leave(
bff0: 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b  ASYNC_MUTEX_LOCK
c000: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
c010: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
c020: 20 20 7d 0a 0a 20 20 20 20 20 20 63 61 73 65 20    }..      case 
c030: 41 53 59 4e 43 5f 44 45 4c 45 54 45 3a 0a 20 20  ASYNC_DELETE:.  
c040: 20 20 20 20 20 20 41 53 59 4e 43 5f 54 52 41 43        ASYNC_TRAC
c050: 45 28 28 22 44 45 4c 45 54 45 20 25 73 5c 6e 22  E(("DELETE %s\n"
c060: 2c 20 70 2d 3e 7a 42 75 66 29 29 3b 0a 20 20 20  , p->zBuf));.   
c070: 20 20 20 20 20 72 63 20 3d 20 70 56 66 73 2d 3e       rc = pVfs->
c080: 78 44 65 6c 65 74 65 28 70 56 66 73 2c 20 70 2d  xDelete(pVfs, p-
c090: 3e 7a 42 75 66 2c 20 28 69 6e 74 29 70 2d 3e 69  >zBuf, (int)p->i
c0a0: 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 20  Offset);.       
c0b0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
c0c0: 49 4f 45 52 52 5f 44 45 4c 45 54 45 5f 4e 4f 45  IOERR_DELETE_NOE
c0d0: 4e 54 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  NT ) rc = SQLITE
c0e0: 5f 4f 4b 3b 0a 20 20 20 20 20 20 20 20 62 72 65  _OK;.        bre
c0f0: 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 65 20  ak;..      case 
c100: 41 53 59 4e 43 5f 4f 50 45 4e 45 58 43 4c 55 53  ASYNC_OPENEXCLUS
c110: 49 56 45 3a 20 7b 0a 20 20 20 20 20 20 20 20 69  IVE: {.        i
c120: 6e 74 20 66 6c 61 67 73 20 3d 20 28 69 6e 74 29  nt flags = (int)
c130: 70 2d 3e 69 4f 66 66 73 65 74 3b 0a 20 20 20 20  p->iOffset;.    
c140: 20 20 20 20 41 73 79 6e 63 46 69 6c 65 44 61 74      AsyncFileDat
c150: 61 20 2a 70 44 61 74 61 20 3d 20 70 2d 3e 70 46  a *pData = p->pF
c160: 69 6c 65 44 61 74 61 3b 0a 20 20 20 20 20 20 20  ileData;.       
c170: 20 41 53 59 4e 43 5f 54 52 41 43 45 28 28 22 4f   ASYNC_TRACE(("O
c180: 50 45 4e 20 25 73 20 66 6c 61 67 73 3d 25 64 5c  PEN %s flags=%d\
c190: 6e 22 2c 20 70 2d 3e 7a 42 75 66 2c 20 28 69 6e  n", p->zBuf, (in
c1a0: 74 29 70 2d 3e 69 4f 66 66 73 65 74 29 29 3b 0a  t)p->iOffset));.
c1b0: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 70          assert(p
c1c0: 44 61 74 61 2d 3e 70 42 61 73 65 52 65 61 64 2d  Data->pBaseRead-
c1d0: 3e 70 4d 65 74 68 6f 64 73 3d 3d 30 20 26 26 20  >pMethods==0 && 
c1e0: 70 44 61 74 61 2d 3e 70 42 61 73 65 57 72 69 74  pData->pBaseWrit
c1f0: 65 2d 3e 70 4d 65 74 68 6f 64 73 3d 3d 30 29 3b  e->pMethods==0);
c200: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 56  .        rc = pV
c210: 66 73 2d 3e 78 4f 70 65 6e 28 70 56 66 73 2c 20  fs->xOpen(pVfs, 
c220: 70 44 61 74 61 2d 3e 7a 4e 61 6d 65 2c 20 70 44  pData->zName, pD
c230: 61 74 61 2d 3e 70 42 61 73 65 52 65 61 64 2c 20  ata->pBaseRead, 
c240: 66 6c 61 67 73 2c 20 30 29 3b 0a 20 20 20 20 20  flags, 0);.     
c250: 20 20 20 61 73 73 65 72 74 28 20 68 6f 6c 64 69     assert( holdi
c260: 6e 67 4d 75 74 65 78 3d 3d 30 20 29 3b 0a 20 20  ngMutex==0 );.  
c270: 20 20 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65        async_mute
c280: 78 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55  x_enter(ASYNC_MU
c290: 54 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20  TEX_QUEUE);.    
c2a0: 20 20 20 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78      holdingMutex
c2b0: 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 62 72   = 1;.        br
c2c0: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  eak;.      }..  
c2d0: 20 20 20 20 64 65 66 61 75 6c 74 3a 20 61 73 73      default: ass
c2e0: 65 72 74 28 21 22 49 6c 6c 65 67 61 6c 20 76 61  ert(!"Illegal va
c2f0: 6c 75 65 20 66 6f 72 20 41 73 79 6e 63 57 72 69  lue for AsyncWri
c300: 74 65 2e 6f 70 22 29 3b 0a 20 20 20 20 7d 0a 0a  te.op");.    }..
c310: 20 20 20 20 2f 2a 20 49 66 20 77 65 20 64 69 64      /* If we did
c320: 6e 27 74 20 68 61 6e 67 20 6f 6e 20 74 6f 20 74  n't hang on to t
c330: 68 65 20 6d 75 74 65 78 20 64 75 72 69 6e 67 20  he mutex during 
c340: 74 68 65 20 49 4f 20 6f 70 2c 20 6f 62 74 61 69  the IO op, obtai
c350: 6e 20 69 74 20 6e 6f 77 0a 20 20 20 20 2a 2a 20  n it now.    ** 
c360: 73 6f 20 74 68 61 74 20 74 68 65 20 41 73 79 6e  so that the Asyn
c370: 63 57 72 69 74 65 20 73 74 72 75 63 74 75 72 65  cWrite structure
c380: 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20 72   can be safely r
c390: 65 6d 6f 76 65 64 20 66 72 6f 6d 20 74 68 65 20  emoved from the 
c3a0: 0a 20 20 20 20 2a 2a 20 67 6c 6f 62 61 6c 20 77  .    ** global w
c3b0: 72 69 74 65 2d 6f 70 20 71 75 65 75 65 2e 0a 20  rite-op queue.. 
c3c0: 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 21 68     */.    if( !h
c3d0: 6f 6c 64 69 6e 67 4d 75 74 65 78 20 29 7b 0a 20  oldingMutex ){. 
c3e0: 20 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78       async_mutex
c3f0: 5f 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54  _enter(ASYNC_MUT
c400: 45 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20  EX_QUEUE);.     
c410: 20 68 6f 6c 64 69 6e 67 4d 75 74 65 78 20 3d 20   holdingMutex = 
c420: 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20  1;.    }.    /* 
c430: 41 53 59 4e 43 5f 54 52 41 43 45 28 28 22 55 4e  ASYNC_TRACE(("UN
c440: 4c 49 4e 4b 20 25 70 5c 6e 22 2c 20 70 29 29 3b  LINK %p\n", p));
c450: 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 3d 3d 61   */.    if( p==a
c460: 73 79 6e 63 2e 70 51 75 65 75 65 4c 61 73 74 20  sync.pQueueLast 
c470: 29 7b 0a 20 20 20 20 20 20 61 73 79 6e 63 2e 70  ){.      async.p
c480: 51 75 65 75 65 4c 61 73 74 20 3d 20 30 3b 0a 20  QueueLast = 0;. 
c490: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 21 64 6f     }.    if( !do
c4a0: 4e 6f 74 46 72 65 65 20 29 7b 0a 20 20 20 20 20  NotFree ){.     
c4b0: 20 61 73 73 65 72 74 5f 6d 75 74 65 78 5f 69 73   assert_mutex_is
c4c0: 5f 68 65 6c 64 28 41 53 59 4e 43 5f 4d 55 54 45  _held(ASYNC_MUTE
c4d0: 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20 20  X_QUEUE);.      
c4e0: 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73  async.pQueueFirs
c4f0: 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  t = p->pNext;.  
c500: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
c510: 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  (p);.    }.    a
c520: 73 73 65 72 74 28 20 68 6f 6c 64 69 6e 67 4d 75  ssert( holdingMu
c530: 74 65 78 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 41  tex );..    /* A
c540: 6e 20 49 4f 20 65 72 72 6f 72 20 68 61 73 20 6f  n IO error has o
c550: 63 63 75 72 72 65 64 2e 20 57 65 20 63 61 6e 6e  ccurred. We cann
c560: 6f 74 20 72 65 70 6f 72 74 20 74 68 65 20 65 72  ot report the er
c570: 72 6f 72 20 62 61 63 6b 20 74 6f 20 74 68 65 0a  ror back to the.
c580: 20 20 20 20 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f      ** connectio
c590: 6e 20 74 68 61 74 20 72 65 71 75 65 73 74 65 64  n that requested
c5a0: 20 74 68 65 20 49 2f 4f 20 73 69 6e 63 65 20 74   the I/O since t
c5b0: 68 65 20 65 72 72 6f 72 20 68 61 70 70 65 6e 65  he error happene
c5c0: 64 20 0a 20 20 20 20 2a 2a 20 61 73 79 6e 63 68  d .    ** asynch
c5d0: 72 6f 6e 6f 75 73 6c 79 2e 20 20 54 68 65 20 63  ronously.  The c
c5e0: 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 73 20 61 6c  onnection has al
c5f0: 72 65 61 64 79 20 6d 6f 76 65 64 20 6f 6e 2e 20  ready moved on. 
c600: 20 54 68 65 72 65 20 0a 20 20 20 20 2a 2a 20 72   There .    ** r
c610: 65 61 6c 6c 79 20 69 73 20 6e 6f 62 6f 64 79 20  eally is nobody 
c620: 74 6f 20 72 65 70 6f 72 74 20 74 68 65 20 65 72  to report the er
c630: 72 6f 72 20 74 6f 2e 0a 20 20 20 20 2a 2a 0a 20  ror to..    **. 
c640: 20 20 20 2a 2a 20 54 68 65 20 66 69 6c 65 20 66     ** The file f
c650: 6f 72 20 77 68 69 63 68 20 74 68 65 20 65 72 72  or which the err
c660: 6f 72 20 6f 63 63 75 72 72 65 64 20 6d 61 79 20  or occurred may 
c670: 68 61 76 65 20 62 65 65 6e 20 61 20 64 61 74 61  have been a data
c680: 62 61 73 65 20 6f 72 0a 20 20 20 20 2a 2a 20 6a  base or.    ** j
c690: 6f 75 72 6e 61 6c 20 66 69 6c 65 2e 20 52 65 67  ournal file. Reg
c6a0: 61 72 64 6c 65 73 73 2c 20 6e 6f 6e 65 20 6f 66  ardless, none of
c6b0: 20 74 68 65 20 63 75 72 72 65 6e 74 6c 79 20 71   the currently q
c6c0: 75 65 75 65 64 20 6f 70 65 72 61 74 69 6f 6e 73  ueued operations
c6d0: 0a 20 20 20 20 2a 2a 20 61 73 73 6f 63 69 61 74  .    ** associat
c6e0: 65 64 20 77 69 74 68 20 74 68 65 20 73 61 6d 65  ed with the same
c6f0: 20 64 61 74 61 62 61 73 65 20 73 68 6f 75 6c 64   database should
c700: 20 6e 6f 77 20 62 65 20 70 65 72 66 6f 72 6d 65   now be performe
c710: 64 2e 20 4e 6f 72 20 73 68 6f 75 6c 64 0a 20 20  d. Nor should.  
c720: 20 20 2a 2a 20 61 6e 79 20 73 75 62 73 65 71 75    ** any subsequ
c730: 65 6e 74 6c 79 20 72 65 71 75 65 73 74 65 64 20  ently requested 
c740: 49 4f 20 6f 6e 20 65 69 74 68 65 72 20 61 20 64  IO on either a d
c750: 61 74 61 62 61 73 65 20 6f 72 20 6a 6f 75 72 6e  atabase or journ
c760: 61 6c 20 66 69 6c 65 20 0a 20 20 20 20 2a 2a 20  al file .    ** 
c770: 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 65 20 73  handle for the s
c780: 61 6d 65 20 64 61 74 61 62 61 73 65 20 62 65 20  ame database be 
c790: 61 63 63 65 70 74 65 64 20 75 6e 74 69 6c 20 74  accepted until t
c7a0: 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65  he main database
c7b0: 0a 20 20 20 20 2a 2a 20 66 69 6c 65 20 68 61 6e  .    ** file han
c7c0: 64 6c 65 20 68 61 73 20 62 65 65 6e 20 63 6c 6f  dle has been clo
c7d0: 73 65 64 20 61 6e 64 20 72 65 6f 70 65 6e 65 64  sed and reopened
c7e0: 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20  ..    **.    ** 
c7f0: 46 75 72 74 68 65 72 6d 6f 72 65 2c 20 6e 6f 20  Furthermore, no 
c800: 66 75 72 74 68 65 72 20 49 4f 20 73 68 6f 75 6c  further IO shoul
c810: 64 20 62 65 20 71 75 65 75 65 64 20 6f 72 20 70  d be queued or p
c820: 65 72 66 6f 72 6d 65 64 20 6f 6e 20 61 6e 79 20  erformed on any 
c830: 66 69 6c 65 0a 20 20 20 20 2a 2a 20 68 61 6e 64  file.    ** hand
c840: 6c 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  le associated wi
c850: 74 68 20 61 20 64 61 74 61 62 61 73 65 20 74 68  th a database th
c860: 61 74 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  at may have been
c870: 20 70 61 72 74 20 6f 66 20 61 20 0a 20 20 20 20   part of a .    
c880: 2a 2a 20 6d 75 6c 74 69 2d 66 69 6c 65 20 74 72  ** multi-file tr
c890: 61 6e 73 61 63 74 69 6f 6e 20 74 68 61 74 20 69  ansaction that i
c8a0: 6e 63 6c 75 64 65 64 20 74 68 65 20 64 61 74 61  ncluded the data
c8b0: 62 61 73 65 20 61 73 73 6f 63 69 61 74 65 64 20  base associated 
c8c0: 77 69 74 68 20 0a 20 20 20 20 2a 2a 20 74 68 65  with .    ** the
c8d0: 20 49 4f 20 65 72 72 6f 72 20 28 69 2e 65 2e 20   IO error (i.e. 
c8e0: 61 20 64 61 74 61 62 61 73 65 20 41 54 54 41 43  a database ATTAC
c8f0: 48 65 64 20 74 6f 20 74 68 65 20 73 61 6d 65 20  Hed to the same 
c900: 68 61 6e 64 6c 65 20 61 74 20 73 6f 6d 65 20 0a  handle at some .
c910: 20 20 20 20 2a 2a 20 70 6f 69 6e 74 20 69 6e 20      ** point in 
c920: 74 69 6d 65 29 2e 0a 20 20 20 20 2a 2f 0a 20 20  time)..    */.  
c930: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
c940: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 61 73 79  _OK ){.      asy
c950: 6e 63 2e 69 6f 45 72 72 6f 72 20 3d 20 72 63 3b  nc.ioError = rc;
c960: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20  .    }..    if( 
c970: 61 73 79 6e 63 2e 69 6f 45 72 72 6f 72 20 26 26  async.ioError &&
c980: 20 21 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69   !async.pQueueFi
c990: 72 73 74 20 29 7b 0a 20 20 20 20 20 20 61 73 79  rst ){.      asy
c9a0: 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 41  nc_mutex_enter(A
c9b0: 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43 4b 29  SYNC_MUTEX_LOCK)
c9c0: 3b 0a 20 20 20 20 20 20 69 66 28 20 30 3d 3d 61  ;.      if( 0==a
c9d0: 73 79 6e 63 2e 70 4c 6f 63 6b 20 29 7b 0a 20 20  sync.pLock ){.  
c9e0: 20 20 20 20 20 20 61 73 79 6e 63 2e 69 6f 45 72        async.ioEr
c9f0: 72 6f 72 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b  ror = SQLITE_OK;
ca00: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
ca10: 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65  sync_mutex_leave
ca20: 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 4c 4f 43  (ASYNC_MUTEX_LOC
ca30: 4b 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  K);.    }..    /
ca40: 2a 20 44 72 6f 70 20 74 68 65 20 71 75 65 75 65  * Drop the queue
ca50: 20 6d 75 74 65 78 20 62 65 66 6f 72 65 20 63 6f   mutex before co
ca60: 6e 74 69 6e 75 69 6e 67 20 74 6f 20 74 68 65 20  ntinuing to the 
ca70: 6e 65 78 74 20 77 72 69 74 65 20 6f 70 65 72 61  next write opera
ca80: 74 69 6f 6e 0a 20 20 20 20 2a 2a 20 69 6e 20 6f  tion.    ** in o
ca90: 72 64 65 72 20 74 6f 20 67 69 76 65 20 6f 74 68  rder to give oth
caa0: 65 72 20 74 68 72 65 61 64 73 20 61 20 63 68 61  er threads a cha
cab0: 6e 63 65 20 74 6f 20 77 6f 72 6b 20 77 69 74 68  nce to work with
cac0: 20 74 68 65 20 77 72 69 74 65 20 71 75 65 75 65   the write queue
cad0: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  ..    */.    if(
cae0: 20 21 61 73 79 6e 63 2e 70 51 75 65 75 65 46 69   !async.pQueueFi
caf0: 72 73 74 20 7c 7c 20 21 61 73 79 6e 63 2e 69 6f  rst || !async.io
cb00: 45 72 72 6f 72 20 29 7b 0a 20 20 20 20 20 20 61  Error ){.      a
cb10: 73 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65  sync_mutex_leave
cb20: 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45  (ASYNC_MUTEX_QUE
cb30: 55 45 29 3b 0a 20 20 20 20 20 20 68 6f 6c 64 69  UE);.      holdi
cb40: 6e 67 4d 75 74 65 78 20 3d 20 30 3b 0a 20 20 20  ngMutex = 0;.   
cb50: 20 20 20 69 66 28 20 61 73 79 6e 63 2e 69 6f 44     if( async.ioD
cb60: 65 6c 61 79 3e 30 20 29 7b 0a 20 20 20 20 20 20  elay>0 ){.      
cb70: 20 20 70 56 66 73 2d 3e 78 53 6c 65 65 70 28 70    pVfs->xSleep(p
cb80: 56 66 73 2c 20 61 73 79 6e 63 2e 69 6f 44 65 6c  Vfs, async.ioDel
cb90: 61 79 2a 31 30 30 30 29 3b 0a 20 20 20 20 20 20  ay*1000);.      
cba0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 61  }else{.        a
cbb0: 73 79 6e 63 5f 73 63 68 65 64 5f 79 69 65 6c 64  sync_sched_yield
cbc0: 28 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ();.      }.    
cbd0: 7d 0a 20 20 7d 0a 20 20 0a 20 20 61 73 79 6e 63  }.  }.  .  async
cbe0: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59  _mutex_leave(ASY
cbf0: 4e 43 5f 4d 55 54 45 58 5f 57 52 49 54 45 52 29  NC_MUTEX_WRITER)
cc00: 3b 0a 20 20 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f  ;.  return;.}../
cc10: 2a 0a 2a 2a 20 49 6e 73 74 61 6c 6c 20 74 68 65  *.** Install the
cc20: 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 56 46   asynchronous VF
cc30: 53 2e 0a 2a 2f 20 0a 69 6e 74 20 73 71 6c 69 74  S..*/ .int sqlit
cc40: 65 33 61 73 79 6e 63 5f 69 6e 69 74 69 61 6c 69  e3async_initiali
cc50: 7a 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ze(const char *z
cc60: 50 61 72 65 6e 74 2c 20 69 6e 74 20 69 73 44 65  Parent, int isDe
cc70: 66 61 75 6c 74 29 7b 0a 20 20 69 6e 74 20 72 63  fault){.  int rc
cc80: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
cc90: 69 66 28 20 61 73 79 6e 63 5f 76 66 73 2e 70 41  if( async_vfs.pA
cca0: 70 70 44 61 74 61 3d 3d 30 20 29 7b 0a 20 20 20  ppData==0 ){.   
ccb0: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 50   sqlite3_vfs *pP
ccc0: 61 72 65 6e 74 20 3d 20 73 71 6c 69 74 65 33 5f  arent = sqlite3_
ccd0: 76 66 73 5f 66 69 6e 64 28 7a 50 61 72 65 6e 74  vfs_find(zParent
cce0: 29 3b 0a 20 20 20 20 69 66 28 20 21 70 50 61 72  );.    if( !pPar
ccf0: 65 6e 74 20 7c 7c 20 61 73 79 6e 63 5f 6f 73 5f  ent || async_os_
cd00: 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 29 7b 0a  initialize() ){.
cd10: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
cd20: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 65 6c  E_ERROR;.    }el
cd30: 73 65 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b  se if( SQLITE_OK
cd40: 21 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  !=(rc = sqlite3_
cd50: 76 66 73 5f 72 65 67 69 73 74 65 72 28 26 61 73  vfs_register(&as
cd60: 79 6e 63 5f 76 66 73 2c 20 69 73 44 65 66 61 75  ync_vfs, isDefau
cd70: 6c 74 29 29 20 29 7b 0a 20 20 20 20 20 20 61 73  lt)) ){.      as
cd80: 79 6e 63 5f 6f 73 5f 73 68 75 74 64 6f 77 6e 28  ync_os_shutdown(
cd90: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
cda0: 20 20 20 20 61 73 79 6e 63 5f 76 66 73 2e 70 41      async_vfs.pA
cdb0: 70 70 44 61 74 61 20 3d 20 28 76 6f 69 64 20 2a  ppData = (void *
cdc0: 29 70 50 61 72 65 6e 74 3b 0a 20 20 20 20 20 20  )pParent;.      
cdd0: 61 73 79 6e 63 5f 76 66 73 2e 6d 78 50 61 74 68  async_vfs.mxPath
cde0: 6e 61 6d 65 20 3d 20 28 28 73 71 6c 69 74 65 33  name = ((sqlite3
cdf0: 5f 76 66 73 20 2a 29 61 73 79 6e 63 5f 76 66 73  _vfs *)async_vfs
ce00: 2e 70 41 70 70 44 61 74 61 29 2d 3e 6d 78 50 61  .pAppData)->mxPa
ce10: 74 68 6e 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20  thname;.    }.  
ce20: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
ce30: 0a 0a 2f 2a 0a 2a 2a 20 55 6e 69 6e 73 74 61 6c  ../*.** Uninstal
ce40: 6c 20 74 68 65 20 61 73 79 6e 63 68 72 6f 6e 6f  l the asynchrono
ce50: 75 73 20 56 46 53 2e 0a 2a 2f 0a 76 6f 69 64 20  us VFS..*/.void 
ce60: 73 71 6c 69 74 65 33 61 73 79 6e 63 5f 73 68 75  sqlite3async_shu
ce70: 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20 20 69  tdown(void){.  i
ce80: 66 28 20 61 73 79 6e 63 5f 76 66 73 2e 70 41 70  f( async_vfs.pAp
ce90: 70 44 61 74 61 20 29 7b 0a 20 20 20 20 61 73 79  pData ){.    asy
cea0: 6e 63 5f 6f 73 5f 73 68 75 74 64 6f 77 6e 28 29  nc_os_shutdown()
ceb0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 76 66  ;.    sqlite3_vf
cec0: 73 5f 75 6e 72 65 67 69 73 74 65 72 28 28 73 71  s_unregister((sq
ced0: 6c 69 74 65 33 5f 76 66 73 20 2a 29 26 61 73 79  lite3_vfs *)&asy
cee0: 6e 63 5f 76 66 73 29 3b 0a 20 20 20 20 61 73 79  nc_vfs);.    asy
cef0: 6e 63 5f 76 66 73 2e 70 41 70 70 44 61 74 61 20  nc_vfs.pAppData 
cf00: 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  = 0;.  }.}../*.*
cf10: 2a 20 50 72 6f 63 65 73 73 20 65 76 65 6e 74 73  * Process events
cf20: 20 6f 6e 20 74 68 65 20 77 72 69 74 65 2d 71 75   on the write-qu
cf30: 65 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  eue..*/.void sql
cf40: 69 74 65 33 61 73 79 6e 63 5f 72 75 6e 28 76 6f  ite3async_run(vo
cf50: 69 64 29 7b 0a 20 20 61 73 79 6e 63 57 72 69 74  id){.  asyncWrit
cf60: 65 72 54 68 72 65 61 64 28 29 3b 0a 7d 0a 0a 2f  erThread();.}../
cf70: 2a 0a 2a 2a 20 43 6f 6e 74 72 6f 6c 2f 63 6f 6e  *.** Control/con
cf80: 66 69 67 75 72 65 20 74 68 65 20 61 73 79 6e 63  figure the async
cf90: 68 72 6f 6e 6f 75 73 20 49 4f 20 73 79 73 74 65  hronous IO syste
cfa0: 6d 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  m..*/.int sqlite
cfb0: 33 61 73 79 6e 63 5f 63 6f 6e 74 72 6f 6c 28 69  3async_control(i
cfc0: 6e 74 20 6f 70 2c 20 2e 2e 2e 29 7b 0a 20 20 76  nt op, ...){.  v
cfd0: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f  a_list ap;.  va_
cfe0: 73 74 61 72 74 28 61 70 2c 20 6f 70 29 3b 0a 20  start(ap, op);. 
cff0: 20 73 77 69 74 63 68 28 20 6f 70 20 29 7b 0a 20   switch( op ){. 
d000: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 41 53     case SQLITEAS
d010: 59 4e 43 5f 48 41 4c 54 3a 20 7b 0a 20 20 20 20  YNC_HALT: {.    
d020: 20 20 69 6e 74 20 65 57 68 65 6e 20 3d 20 76 61    int eWhen = va
d030: 5f 61 72 67 28 61 70 2c 20 69 6e 74 29 3b 0a 20  _arg(ap, int);. 
d040: 20 20 20 20 20 69 66 28 20 65 57 68 65 6e 21 3d       if( eWhen!=
d050: 53 51 4c 49 54 45 41 53 59 4e 43 5f 48 41 4c 54  SQLITEASYNC_HALT
d060: 5f 4e 45 56 45 52 0a 20 20 20 20 20 20 20 26 26  _NEVER.       &&
d070: 20 65 57 68 65 6e 21 3d 53 51 4c 49 54 45 41 53   eWhen!=SQLITEAS
d080: 59 4e 43 5f 48 41 4c 54 5f 4e 4f 57 0a 20 20 20  YNC_HALT_NOW.   
d090: 20 20 20 20 26 26 20 65 57 68 65 6e 21 3d 53 51      && eWhen!=SQ
d0a0: 4c 49 54 45 41 53 59 4e 43 5f 48 41 4c 54 5f 49  LITEASYNC_HALT_I
d0b0: 44 4c 45 0a 20 20 20 20 20 20 29 7b 0a 20 20 20  DLE.      ){.   
d0c0: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
d0d0: 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 20 20 20  TE_MISUSE;.     
d0e0: 20 7d 0a 20 20 20 20 20 20 61 73 79 6e 63 2e 65   }.      async.e
d0f0: 48 61 6c 74 20 3d 20 65 57 68 65 6e 3b 0a 20 20  Halt = eWhen;.  
d100: 20 20 20 20 61 73 79 6e 63 5f 6d 75 74 65 78 5f      async_mutex_
d110: 65 6e 74 65 72 28 41 53 59 4e 43 5f 4d 55 54 45  enter(ASYNC_MUTE
d120: 58 5f 51 55 45 55 45 29 3b 0a 20 20 20 20 20 20  X_QUEUE);.      
d130: 61 73 79 6e 63 5f 63 6f 6e 64 5f 73 69 67 6e 61  async_cond_signa
d140: 6c 28 41 53 59 4e 43 5f 43 4f 4e 44 5f 51 55 45  l(ASYNC_COND_QUE
d150: 55 45 29 3b 0a 20 20 20 20 20 20 61 73 79 6e 63  UE);.      async
d160: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53 59  _mutex_leave(ASY
d170: 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29 3b  NC_MUTEX_QUEUE);
d180: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
d190: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 53 51    }..    case SQ
d1a0: 4c 49 54 45 41 53 59 4e 43 5f 44 45 4c 41 59 3a  LITEASYNC_DELAY:
d1b0: 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 44 65   {.      int iDe
d1c0: 6c 61 79 20 3d 20 76 61 5f 61 72 67 28 61 70 2c  lay = va_arg(ap,
d1d0: 20 69 6e 74 29 3b 0a 20 20 20 20 20 20 69 66 28   int);.      if(
d1e0: 20 69 44 65 6c 61 79 3c 30 20 29 7b 0a 20 20 20   iDelay<0 ){.   
d1f0: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
d200: 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 20 20 20  TE_MISUSE;.     
d210: 20 7d 0a 20 20 20 20 20 20 61 73 79 6e 63 2e 69   }.      async.i
d220: 6f 44 65 6c 61 79 20 3d 20 69 44 65 6c 61 79 3b  oDelay = iDelay;
d230: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
d240: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 53 51    }..    case SQ
d250: 4c 49 54 45 41 53 59 4e 43 5f 4c 4f 43 4b 46 49  LITEASYNC_LOCKFI
d260: 4c 45 53 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74  LES: {.      int
d270: 20 62 4c 6f 63 6b 20 3d 20 76 61 5f 61 72 67 28   bLock = va_arg(
d280: 61 70 2c 20 69 6e 74 29 3b 0a 20 20 20 20 20 20  ap, int);.      
d290: 61 73 79 6e 63 5f 6d 75 74 65 78 5f 65 6e 74 65  async_mutex_ente
d2a0: 72 28 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55  r(ASYNC_MUTEX_QU
d2b0: 45 55 45 29 3b 0a 20 20 20 20 20 20 69 66 28 20  EUE);.      if( 
d2c0: 61 73 79 6e 63 2e 6e 46 69 6c 65 20 7c 7c 20 61  async.nFile || a
d2d0: 73 79 6e 63 2e 70 51 75 65 75 65 46 69 72 73 74  sync.pQueueFirst
d2e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73 79 6e   ){.        asyn
d2f0: 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 41 53  c_mutex_leave(AS
d300: 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55 45 29  YNC_MUTEX_QUEUE)
d310: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
d320: 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a   SQLITE_MISUSE;.
d330: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73        }.      as
d340: 79 6e 63 2e 62 4c 6f 63 6b 46 69 6c 65 73 20 3d  ync.bLockFiles =
d350: 20 62 4c 6f 63 6b 3b 0a 20 20 20 20 20 20 61 73   bLock;.      as
d360: 79 6e 63 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  ync_mutex_leave(
d370: 41 53 59 4e 43 5f 4d 55 54 45 58 5f 51 55 45 55  ASYNC_MUTEX_QUEU
d380: 45 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  E);.      break;
d390: 0a 20 20 20 20 7d 0a 20 20 20 20 20 20 0a 20 20  .    }.      .  
d3a0: 20 20 63 61 73 65 20 53 51 4c 49 54 45 41 53 59    case SQLITEASY
d3b0: 4e 43 5f 47 45 54 5f 48 41 4c 54 3a 20 7b 0a 20  NC_GET_HALT: {. 
d3c0: 20 20 20 20 20 69 6e 74 20 2a 70 65 57 68 65 6e       int *peWhen
d3d0: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 69 6e   = va_arg(ap, in
d3e0: 74 20 2a 29 3b 0a 20 20 20 20 20 20 2a 70 65 57  t *);.      *peW
d3f0: 68 65 6e 20 3d 20 61 73 79 6e 63 2e 65 48 61 6c  hen = async.eHal
d400: 74 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  t;.      break;.
d410: 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20 53      }.    case S
d420: 51 4c 49 54 45 41 53 59 4e 43 5f 47 45 54 5f 44  QLITEASYNC_GET_D
d430: 45 4c 41 59 3a 20 7b 0a 20 20 20 20 20 20 69 6e  ELAY: {.      in
d440: 74 20 2a 70 69 44 65 6c 61 79 20 3d 20 76 61 5f  t *piDelay = va_
d450: 61 72 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b 0a  arg(ap, int *);.
d460: 20 20 20 20 20 20 2a 70 69 44 65 6c 61 79 20 3d        *piDelay =
d470: 20 61 73 79 6e 63 2e 69 6f 44 65 6c 61 79 3b 0a   async.ioDelay;.
d480: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
d490: 20 7d 0a 20 20 20 20 63 61 73 65 20 53 51 4c 49   }.    case SQLI
d4a0: 54 45 41 53 59 4e 43 5f 47 45 54 5f 4c 4f 43 4b  TEASYNC_GET_LOCK
d4b0: 46 49 4c 45 53 3a 20 7b 0a 20 20 20 20 20 20 69  FILES: {.      i
d4c0: 6e 74 20 2a 70 69 44 65 6c 61 79 20 3d 20 76 61  nt *piDelay = va
d4d0: 5f 61 72 67 28 61 70 2c 20 69 6e 74 20 2a 29 3b  _arg(ap, int *);
d4e0: 0a 20 20 20 20 20 20 2a 70 69 44 65 6c 61 79 20  .      *piDelay 
d4f0: 3d 20 61 73 79 6e 63 2e 62 4c 6f 63 6b 46 69 6c  = async.bLockFil
d500: 65 73 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  es;.      break;
d510: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 64 65 66 61  .    }..    defa
d520: 75 6c 74 3a 0a 20 20 20 20 20 20 72 65 74 75 72  ult:.      retur
d530: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
d540: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
d550: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69  ITE_OK;.}..#endi
d560: 66 20 2f 2a 20 21 64 65 66 69 6e 65 64 28 53 51  f /* !defined(SQ
d570: 4c 49 54 45 5f 43 4f 52 45 29 20 7c 7c 20 64 65  LITE_CORE) || de
d580: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41  fined(SQLITE_ENA
d590: 42 4c 45 5f 41 53 59 4e 43 49 4f 29 20 2a 2f 0a  BLE_ASYNCIO) */.
d5a0: 0a                                               .