/ Hex Artifact Content
Login

Artifact a5dbb0b06d046219e25f4f59998f6067e9d0761e4e06d35a70d0d7409c136c4f:


0000: 2f 2a 0a 2a 2a 20 32 30 31 37 20 41 70 72 69 6c  /*.** 2017 April
0010: 20 32 34 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75   24.**.** The au
0020: 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63  thor disclaims c
0030: 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73  opyright to this
0040: 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49   source code.  I
0050: 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20  n place of.** a 
0060: 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65  legal notice, he
0070: 72 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67  re is a blessing
0080: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79  :.**.**    May y
0090: 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e  ou do good and n
00a0: 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d  ot evil..**    M
00b0: 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67  ay you find forg
00c0: 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72  iveness for your
00d0: 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65  self and forgive
00e0: 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d   others..**    M
00f0: 61 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65  ay you share fre
0100: 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e  ely, never takin
0110: 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20  g more than you 
0120: 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a  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 0a 2a 2f 0a 0a 23 69 6e 63 6c 75 64 65 20  **.*/..#include 
0180: 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 23  "sqliteInt.h"..#
0190: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 53 45 52  ifdef SQLITE_SER
01a0: 56 45 52 5f 45 44 49 54 49 4f 4e 0a 0a 2f 2a 0a  VER_EDITION../*.
01b0: 2a 2a 20 50 61 67 65 2d 6c 6f 63 6b 69 6e 67 20  ** Page-locking 
01c0: 73 6c 6f 74 20 66 6f 72 6d 61 74 3a 0a 2a 2a 0a  slot format:.**.
01d0: 2a 2a 20 20 20 41 73 73 75 6d 69 6e 67 20 48 4d  **   Assuming HM
01e0: 41 5f 4d 41 58 5f 54 52 41 4e 53 41 43 54 49 4f  A_MAX_TRANSACTIO
01f0: 4e 49 44 20 69 73 20 73 65 74 20 74 6f 20 31 36  NID is set to 16
0200: 2e 0a 2a 2a 0a 2a 2a 20 20 20 54 68 65 20 6c 65  ..**.**   The le
0210: 61 73 74 2d 73 69 67 6e 69 66 69 63 61 6e 74 20  ast-significant 
0220: 31 36 20 62 69 74 73 20 61 72 65 20 75 73 65 64  16 bits are used
0230: 20 66 6f 72 20 72 65 61 64 20 6c 6f 63 6b 73 2e   for read locks.
0240: 20 57 68 65 6e 20 61 20 72 65 61 64 0a 2a 2a 20   When a read.** 
0250: 20 20 6c 6f 63 6b 20 69 73 20 74 61 6b 65 6e 2c    lock is taken,
0260: 20 74 68 65 20 63 6c 69 65 6e 74 20 73 65 74 73   the client sets
0270: 20 74 68 65 20 62 69 74 20 61 73 73 6f 63 69 61   the bit associa
0280: 74 65 64 20 77 69 74 68 20 69 74 73 20 0a 2a 2a  ted with its .**
0290: 20 20 20 74 72 61 6e 73 61 63 74 69 6f 6e 2d 69     transaction-i
02a0: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 54 68 65 20 6e  d..**.**   The n
02b0: 65 78 74 20 35 20 62 69 74 73 20 61 72 65 20 73  ext 5 bits are s
02c0: 65 74 20 74 6f 20 30 20 69 66 20 6e 6f 20 63 6c  et to 0 if no cl
02d0: 69 65 6e 74 20 63 75 72 72 65 6e 74 6c 79 20 68  ient currently h
02e0: 6f 6c 64 73 20 61 20 77 72 69 74 65 0a 2a 2a 20  olds a write.** 
02f0: 20 20 6c 6f 63 6b 2e 20 4f 72 20 74 6f 20 28 74    lock. Or to (t
0300: 72 61 6e 73 61 63 74 69 6f 6e 2d 69 64 20 2b 20  ransaction-id + 
0310: 31 29 20 69 66 20 61 20 77 72 69 74 65 20 6c 6f  1) if a write lo
0320: 63 6b 20 69 73 20 68 65 6c 64 2e 0a 2a 2a 0a 2a  ck is held..**.*
0330: 2a 20 20 20 54 68 65 20 6e 65 78 74 20 38 20 62  *   The next 8 b
0340: 69 74 73 20 61 72 65 20 73 65 74 20 74 6f 20 74  its are set to t
0350: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 72 61  he number of tra
0360: 6e 73 69 65 6e 74 2d 72 65 61 64 20 6c 6f 63 6b  nsient-read lock
0370: 73 20 0a 2a 2a 20 20 20 63 75 72 72 65 6e 74 6c  s .**   currentl
0380: 79 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 70 61  y held on the pa
0390: 67 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48  ge..*/.#define H
03a0: 4d 41 5f 53 4c 4f 54 5f 52 4c 5f 42 49 54 53 20  MA_SLOT_RL_BITS 
03b0: 31 36 20 20 20 20 20 20 20 2f 2a 20 62 69 74 73  16       /* bits
03c0: 20 66 6f 72 20 52 65 61 64 20 4c 6f 63 6b 73 20   for Read Locks 
03d0: 2a 2f 0a 23 64 65 66 69 6e 65 20 48 4d 41 5f 53  */.#define HMA_S
03e0: 4c 4f 54 5f 57 4c 5f 42 49 54 53 20 35 20 20 20  LOT_WL_BITS 5   
03f0: 20 20 20 20 20 2f 2a 20 62 69 74 73 20 66 6f 72       /* bits for
0400: 20 57 72 69 74 65 20 4c 6f 63 6b 73 20 2a 2f 0a   Write Locks */.
0410: 23 64 65 66 69 6e 65 20 48 4d 41 5f 53 4c 4f 54  #define HMA_SLOT
0420: 5f 54 52 5f 42 49 54 53 20 38 20 20 20 20 20 20  _TR_BITS 8      
0430: 20 20 2f 2a 20 62 69 74 73 20 66 6f 72 20 54 72    /* bits for Tr
0440: 61 6e 73 69 65 6e 74 20 52 65 61 64 65 72 20 6c  ansient Reader l
0450: 6f 63 6b 73 20 2a 2f 0a 0a 23 64 65 66 69 6e 65  ocks */..#define
0460: 20 48 4d 41 5f 53 4c 4f 54 5f 52 4c 57 4c 5f 42   HMA_SLOT_RLWL_B
0470: 49 54 53 20 28 48 4d 41 5f 53 4c 4f 54 5f 52 4c  ITS (HMA_SLOT_RL
0480: 5f 42 49 54 53 20 2b 20 48 4d 41 5f 53 4c 4f 54  _BITS + HMA_SLOT
0490: 5f 57 4c 5f 42 49 54 53 29 0a 0a 0a 23 64 65 66  _WL_BITS)...#def
04a0: 69 6e 65 20 48 4d 41 5f 53 4c 4f 54 5f 52 4c 5f  ine HMA_SLOT_RL_
04b0: 4d 41 53 4b 20 28 28 31 20 3c 3c 20 48 4d 41 5f  MASK ((1 << HMA_
04c0: 53 4c 4f 54 5f 52 4c 5f 42 49 54 53 29 2d 31 29  SLOT_RL_BITS)-1)
04d0: 0a 23 64 65 66 69 6e 65 20 48 4d 41 5f 53 4c 4f  .#define HMA_SLO
04e0: 54 5f 57 4c 5f 4d 41 53 4b 20 28 28 28 31 20 3c  T_WL_MASK (((1 <
04f0: 3c 20 48 4d 41 5f 53 4c 4f 54 5f 57 4c 5f 42 49  < HMA_SLOT_WL_BI
0500: 54 53 29 2d 31 29 20 3c 3c 20 48 4d 41 5f 53 4c  TS)-1) << HMA_SL
0510: 4f 54 5f 52 4c 5f 42 49 54 53 29 0a 23 64 65 66  OT_RL_BITS).#def
0520: 69 6e 65 20 48 4d 41 5f 53 4c 4f 54 5f 54 52 5f  ine HMA_SLOT_TR_
0530: 4d 41 53 4b 20 28 28 28 31 20 3c 3c 20 48 4d 41  MASK (((1 << HMA
0540: 5f 53 4c 4f 54 5f 54 52 5f 42 49 54 53 29 2d 31  _SLOT_TR_BITS)-1
0550: 29 20 3c 3c 20 48 4d 41 5f 53 4c 4f 54 5f 52 4c  ) << HMA_SLOT_RL
0560: 57 4c 5f 42 49 54 53 29 0a 0a 0a 2f 2a 20 4e 75  WL_BITS).../* Nu
0570: 6d 62 65 72 20 6f 66 20 70 61 67 65 2d 6c 6f 63  mber of page-loc
0580: 6b 69 6e 67 20 73 6c 6f 74 73 20 2a 2f 0a 23 64  king slots */.#d
0590: 65 66 69 6e 65 20 48 4d 41 5f 50 41 47 45 4c 4f  efine HMA_PAGELO
05a0: 43 4b 5f 53 4c 4f 54 53 20 28 32 35 36 2a 31 30  CK_SLOTS (256*10
05b0: 32 34 29 0a 0a 2f 2a 20 4d 61 78 69 6d 75 6d 20  24)../* Maximum 
05c0: 63 6f 6e 63 75 72 72 65 6e 74 20 72 65 61 64 2f  concurrent read/
05d0: 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f  write transactio
05e0: 6e 73 20 2a 2f 0a 23 64 65 66 69 6e 65 20 48 4d  ns */.#define HM
05f0: 41 5f 4d 41 58 5f 54 52 41 4e 53 41 43 54 49 4f  A_MAX_TRANSACTIO
0600: 4e 49 44 20 31 36 0a 0a 0a 23 64 65 66 69 6e 65  NID 16...#define
0610: 20 48 4d 41 5f 48 41 53 48 5f 53 49 5a 45 20 35   HMA_HASH_SIZE 5
0620: 31 32 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72  12../*.** The ar
0630: 67 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20 6d  gument to this m
0640: 61 63 72 6f 20 69 73 20 74 68 65 20 76 61 6c 75  acro is the valu
0650: 65 20 6f 66 20 61 20 6c 6f 63 6b 69 6e 67 20 73  e of a locking s
0660: 6c 6f 74 2e 20 49 74 20 72 65 74 75 72 6e 73 0a  lot. It returns.
0670: 2a 2a 20 2d 31 20 69 66 20 6e 6f 20 63 6c 69 65  ** -1 if no clie
0680: 6e 74 20 63 75 72 72 65 6e 74 6c 79 20 68 6f 6c  nt currently hol
0690: 64 73 20 74 68 65 20 77 72 69 74 65 20 6c 6f 63  ds the write loc
06a0: 6b 2c 20 6f 72 20 74 68 65 20 74 72 61 6e 73 61  k, or the transa
06b0: 63 74 69 6f 6e 2d 69 64 0a 2a 2a 20 6f 66 20 74  ction-id.** of t
06c0: 68 65 20 6c 6f 63 6b 65 72 20 6f 74 68 65 72 77  he locker otherw
06d0: 69 73 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  ise..*/.#define 
06e0: 73 6c 6f 74 47 65 74 57 72 69 74 65 72 28 76 29  slotGetWriter(v)
06f0: 20 28 28 28 28 69 6e 74 29 28 76 29 26 48 4d 41   ((((int)(v)&HMA
0700: 5f 53 4c 4f 54 5f 57 4c 5f 4d 41 53 4b 29 20 3e  _SLOT_WL_MASK) >
0710: 3e 20 48 4d 41 5f 53 4c 4f 54 5f 52 4c 5f 42 49  > HMA_SLOT_RL_BI
0720: 54 53 29 20 2d 20 31 29 0a 0a 2f 2a 0a 2a 2a 20  TS) - 1)../*.** 
0730: 54 68 65 20 61 72 67 75 6d 65 6e 74 20 74 6f 20  The argument to 
0740: 74 68 69 73 20 6d 61 63 72 6f 20 69 73 20 74 68  this macro is th
0750: 65 20 76 61 6c 75 65 20 6f 66 20 61 20 6c 6f 63  e value of a loc
0760: 6b 69 6e 67 20 73 6c 6f 74 2e 20 54 68 69 73 20  king slot. This 
0770: 6d 61 63 72 6f 0a 2a 2a 20 72 65 74 75 72 6e 73  macro.** returns
0780: 20 74 68 65 20 63 75 72 72 65 6e 74 20 6e 75 6d   the current num
0790: 62 65 72 20 6f 66 20 73 6c 6f 77 20 72 65 61 64  ber of slow read
07a0: 65 72 20 63 6c 69 65 6e 74 73 20 72 65 61 64 69  er clients readi
07b0: 6e 67 20 74 68 65 20 70 61 67 65 2e 0a 2a 2f 0a  ng the page..*/.
07c0: 23 64 65 66 69 6e 65 20 73 6c 6f 74 47 65 74 53  #define slotGetS
07d0: 6c 6f 77 52 65 61 64 65 72 73 28 76 29 20 28 28  lowReaders(v) ((
07e0: 28 76 29 20 26 20 48 4d 41 5f 53 4c 4f 54 5f 54  (v) & HMA_SLOT_T
07f0: 52 5f 4d 41 53 4b 29 20 3e 3e 20 48 4d 41 5f 53  R_MASK) >> HMA_S
0800: 4c 4f 54 5f 52 4c 57 4c 5f 42 49 54 53 29 0a 0a  LOT_RLWL_BITS)..
0810: 23 64 65 66 69 6e 65 20 73 6c 6f 74 52 65 61 64  #define slotRead
0820: 65 72 4d 61 73 6b 28 76 29 20 28 28 76 29 20 26  erMask(v) ((v) &
0830: 20 48 4d 41 5f 53 4c 4f 54 5f 52 4c 5f 4d 41 53   HMA_SLOT_RL_MAS
0840: 4b 29 0a 0a 23 69 6e 63 6c 75 64 65 20 22 75 6e  K)..#include "un
0850: 69 73 74 64 2e 68 22 0a 23 69 6e 63 6c 75 64 65  istd.h".#include
0860: 20 22 66 63 6e 74 6c 2e 68 22 0a 23 69 6e 63 6c   "fcntl.h".#incl
0870: 75 64 65 20 22 73 79 73 2f 6d 6d 61 6e 2e 68 22  ude "sys/mman.h"
0880: 0a 23 69 6e 63 6c 75 64 65 20 22 73 79 73 2f 74  .#include "sys/t
0890: 79 70 65 73 2e 68 22 0a 23 69 6e 63 6c 75 64 65  ypes.h".#include
08a0: 20 22 73 79 73 2f 73 74 61 74 2e 68 22 0a 23 69   "sys/stat.h".#i
08b0: 6e 63 6c 75 64 65 20 22 65 72 72 6e 6f 2e 68 22  nclude "errno.h"
08c0: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
08d0: 20 53 65 72 76 65 72 44 62 20 53 65 72 76 65 72   ServerDb Server
08e0: 44 62 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  Db;.typedef stru
08f0: 63 74 20 53 65 72 76 65 72 4a 6f 75 72 6e 61 6c  ct ServerJournal
0900: 20 53 65 72 76 65 72 4a 6f 75 72 6e 61 6c 3b 0a   ServerJournal;.
0910: 0a 73 74 72 75 63 74 20 53 65 72 76 65 72 47 6c  .struct ServerGl
0920: 6f 62 61 6c 20 7b 0a 20 20 53 65 72 76 65 72 44  obal {.  ServerD
0930: 62 20 2a 70 44 62 3b 20 20 20 20 20 20 20 20 20  b *pDb;         
0940: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6e 6b           /* Link
0950: 65 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 53  ed list of all S
0960: 65 72 76 65 72 48 4d 41 20 6f 62 6a 65 63 74 73  erverHMA objects
0970: 20 2a 2f 0a 7d 3b 0a 73 74 61 74 69 63 20 73 74   */.};.static st
0980: 72 75 63 74 20 53 65 72 76 65 72 47 6c 6f 62 61  ruct ServerGloba
0990: 6c 20 67 5f 73 65 72 76 65 72 3b 0a 0a 73 74 72  l g_server;..str
09a0: 75 63 74 20 53 65 72 76 65 72 4a 6f 75 72 6e 61  uct ServerJourna
09b0: 6c 20 7b 0a 20 20 63 68 61 72 20 2a 7a 4a 6f 75  l {.  char *zJou
09c0: 72 6e 61 6c 3b 0a 20 20 73 71 6c 69 74 65 33 5f  rnal;.  sqlite3_
09d0: 66 69 6c 65 20 2a 6a 66 64 3b 0a 7d 3b 0a 0a 2f  file *jfd;.};../
09e0: 2a 0a 2a 2a 20 54 68 65 72 65 20 69 73 20 6f 6e  *.** There is on
09f0: 65 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  e instance of th
0a00: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72 75  e following stru
0a10: 63 74 75 72 65 20 66 6f 72 20 65 61 63 68 20 64  cture for each d
0a20: 69 73 74 69 6e 63 74 20 0a 2a 2a 20 64 61 74 61  istinct .** data
0a30: 62 61 73 65 20 66 69 6c 65 20 6f 70 65 6e 65 64  base file opened
0a40: 20 69 6e 20 73 65 72 76 65 72 20 6d 6f 64 65 20   in server mode 
0a50: 62 79 20 74 68 69 73 20 70 72 6f 63 65 73 73 2e  by this process.
0a60: 0a 2a 2f 0a 73 74 72 75 63 74 20 53 65 72 76 65  .*/.struct Serve
0a70: 72 44 62 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f  rDb {.  sqlite3_
0a80: 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20 20  mutex *mutex;   
0a90: 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e 2d 72          /* Non-r
0aa0: 65 63 75 72 73 69 76 65 20 6d 75 74 65 78 20 2a  ecursive mutex *
0ab0: 2f 0a 20 20 69 6e 74 20 6e 43 6c 69 65 6e 74 3b  /.  int nClient;
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ad0: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 6e      /* Current n
0ae0: 75 6d 62 65 72 20 6f 66 20 63 6c 69 65 6e 74 73  umber of clients
0af0: 20 2a 2f 0a 20 20 69 6e 74 20 62 49 6e 69 74 3b   */.  int bInit;
0b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b10: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 6f 6e        /* True on
0b20: 63 65 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 2a  ce initialized *
0b30: 2f 0a 20 20 75 33 32 20 74 72 61 6e 73 6d 61 73  /.  u32 transmas
0b40: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
0b50: 20 20 20 20 2f 2a 20 42 69 74 6d 61 73 6b 20 6f      /* Bitmask o
0b60: 66 20 74 61 6b 65 6e 20 74 72 61 6e 73 61 63 74  f taken transact
0b70: 69 6f 6e 20 69 64 73 20 2a 2f 0a 20 20 75 33 32  ion ids */.  u32
0b80: 20 2a 61 53 6c 6f 74 3b 20 20 20 20 20 20 20 20   *aSlot;        
0b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0ba0: 41 72 72 61 79 20 6f 66 20 70 61 67 65 20 6c 6f  Array of page lo
0bb0: 63 6b 69 6e 67 20 73 6c 6f 74 73 20 2a 2f 0a 20  cking slots */. 
0bc0: 20 69 36 34 20 61 46 69 6c 65 49 64 5b 32 5d 3b   i64 aFileId[2];
0bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0be0: 20 2f 2a 20 4f 70 61 71 75 65 20 56 46 53 20 66   /* Opaque VFS f
0bf0: 69 6c 65 2d 69 64 20 2a 2f 0a 20 20 53 65 72 76  ile-id */.  Serv
0c00: 65 72 44 62 20 2a 70 4e 65 78 74 3b 20 20 20 20  erDb *pNext;    
0c10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0c20: 65 78 74 20 64 62 20 69 6e 20 74 68 69 73 20 70  ext db in this p
0c30: 72 6f 63 65 73 73 20 2a 2f 0a 0a 20 20 73 71 6c  rocess */..  sql
0c40: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b 0a  ite3_vfs *pVfs;.
0c50: 20 20 53 65 72 76 65 72 4a 6f 75 72 6e 61 6c 20    ServerJournal 
0c60: 61 4a 72 6e 6c 5b 48 4d 41 5f 4d 41 58 5f 54 52  aJrnl[HMA_MAX_TR
0c70: 41 4e 53 41 43 54 49 4f 4e 49 44 5d 3b 0a 20 20  ANSACTIONID];.  
0c80: 75 38 20 2a 61 4a 72 6e 6c 46 64 53 70 61 63 65  u8 *aJrnlFdSpace
0c90: 3b 0a 0a 20 20 69 6e 74 20 69 4e 65 78 74 43 6f  ;..  int iNextCo
0ca0: 6d 6d 69 74 3b 20 20 20 20 20 20 20 20 20 20 20  mmit;           
0cb0: 20 20 20 20 20 2f 2a 20 43 6f 6d 6d 69 74 20 69       /* Commit i
0cc0: 64 20 66 6f 72 20 6e 65 78 74 20 70 72 65 2d 63  d for next pre-c
0cd0: 6f 6d 6d 69 74 20 63 61 6c 6c 20 2a 2f 20 0a 20  ommit call */ . 
0ce0: 20 53 65 72 76 65 72 20 2a 70 43 6f 6d 6d 69 74   Server *pCommit
0cf0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0d00: 20 2f 2a 20 4c 69 73 74 20 6f 66 20 63 6f 6e 6e   /* List of conn
0d10: 65 63 74 69 6f 6e 73 20 63 75 72 72 65 6e 74 6c  ections currentl
0d20: 79 20 63 6f 6d 6d 69 74 69 6e 67 20 2a 2f 0a 20  y commiting */. 
0d30: 20 53 65 72 76 65 72 20 2a 70 52 65 61 64 65 72   Server *pReader
0d40: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0d50: 20 2f 2a 20 43 6f 6e 6e 65 63 74 69 6f 6e 73 20   /* Connections 
0d60: 69 6e 20 73 6c 6f 77 65 72 2d 72 65 61 64 65 72  in slower-reader
0d70: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a   transaction */.
0d80: 20 20 53 65 72 76 65 72 50 61 67 65 20 2a 70 50    ServerPage *pP
0d90: 67 46 69 72 73 74 3b 20 20 20 20 20 20 20 20 20  gFirst;         
0da0: 20 20 2f 2a 20 46 69 72 73 74 20 28 6f 6c 64 65    /* First (olde
0db0: 73 74 29 20 69 6e 20 6c 69 73 74 20 6f 66 20 70  st) in list of p
0dc0: 61 67 65 73 20 2a 2f 0a 20 20 53 65 72 76 65 72  ages */.  Server
0dd0: 50 61 67 65 20 2a 70 50 67 4c 61 73 74 3b 20 20  Page *pPgLast;  
0de0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73            /* Las
0df0: 74 20 28 6e 65 77 65 73 74 29 20 69 6e 20 6c 69  t (newest) in li
0e00: 73 74 20 6f 66 20 70 61 67 65 73 20 2a 2f 0a 20  st of pages */. 
0e10: 20 53 65 72 76 65 72 50 61 67 65 20 2a 61 70 50   ServerPage *apP
0e20: 67 5b 48 4d 41 5f 48 41 53 48 5f 53 49 5a 45 5d  g[HMA_HASH_SIZE]
0e30: 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 63 65  ;.};../*.** Once
0e40: 20 69 6e 73 74 61 6e 63 65 20 66 6f 72 20 65 61   instance for ea
0e50: 63 68 20 63 6c 69 65 6e 74 20 63 6f 6e 6e 65 63  ch client connec
0e60: 74 69 6f 6e 20 6f 70 65 6e 20 6f 6e 20 61 20 73  tion open on a s
0e70: 65 72 76 65 72 20 6d 6f 64 65 20 64 61 74 61 62  erver mode datab
0e80: 61 73 65 0a 2a 2a 20 69 6e 20 74 68 69 73 20 70  ase.** in this p
0e90: 72 6f 63 65 73 73 2e 0a 2a 2f 0a 73 74 72 75 63  rocess..*/.struc
0ea0: 74 20 53 65 72 76 65 72 20 7b 0a 20 20 53 65 72  t Server {.  Ser
0eb0: 76 65 72 44 62 20 2a 70 44 62 3b 20 20 20 20 20  verDb *pDb;     
0ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0ed0: 44 61 74 61 62 61 73 65 20 6f 62 6a 65 63 74 20  Database object 
0ee0: 2a 2f 0a 20 20 50 61 67 65 72 20 2a 70 50 61 67  */.  Pager *pPag
0ef0: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  er;             
0f00: 20 20 20 20 20 2f 2a 20 41 73 73 6f 63 69 61 74       /* Associat
0f10: 65 64 20 70 61 67 65 72 20 6f 62 6a 65 63 74 20  ed pager object 
0f20: 2a 2f 0a 20 20 69 6e 74 20 65 54 72 61 6e 73 3b  */.  int eTrans;
0f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f40: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 74       /* One of t
0f50: 68 65 20 53 45 52 56 45 52 5f 54 52 41 4e 53 5f  he SERVER_TRANS_
0f60: 78 78 78 20 76 61 6c 75 65 73 20 2a 2f 20 0a 20  xxx values */ . 
0f70: 20 69 6e 74 20 69 54 72 61 6e 73 49 64 3b 20 20   int iTransId;  
0f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f90: 20 2f 2a 20 43 75 72 72 65 6e 74 20 74 72 61 6e   /* Current tran
0fa0: 73 61 63 74 69 6f 6e 20 69 64 20 28 6f 72 20 2d  saction id (or -
0fb0: 31 29 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6d  1) */.  int iCom
0fc0: 6d 69 74 49 64 3b 20 20 20 20 20 20 20 20 20 20  mitId;          
0fd0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65          /* Curre
0fe0: 6e 74 20 63 6f 6d 6d 69 74 20 69 64 20 28 6f 72  nt commit id (or
0ff0: 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c   0) */.  int nAl
1000: 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20 20 20  loc;            
1010: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 6c 6c 6f           /* Allo
1020: 63 61 74 65 64 20 73 69 7a 65 20 6f 66 20 61 4c  cated size of aL
1030: 6f 63 6b 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20  ock[] array */. 
1040: 20 69 6e 74 20 6e 4c 6f 63 6b 3b 20 20 20 20 20   int nLock;     
1050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1060: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e   /* Number of en
1070: 74 72 69 65 73 20 69 6e 20 61 4c 6f 63 6b 5b 5d  tries in aLock[]
1080: 20 2a 2f 0a 20 20 75 33 32 20 2a 61 4c 6f 63 6b   */.  u32 *aLock
1090: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
10a0: 20 20 20 20 20 20 2f 2a 20 4d 61 70 70 65 64 20        /* Mapped 
10b0: 6c 6f 63 6b 20 66 69 6c 65 20 2a 2f 0a 20 20 53  lock file */.  S
10c0: 65 72 76 65 72 20 2a 70 4e 65 78 74 3b 20 20 20  erver *pNext;   
10d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10e0: 2a 20 4e 65 78 74 20 69 6e 20 70 43 6f 6d 6d 69  * Next in pCommi
10f0: 74 20 6f 72 20 70 52 65 61 64 65 72 20 6c 69 73  t or pReader lis
1100: 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 50  t */.};../*.** P
1110: 6f 73 73 69 62 6c 65 20 76 61 6c 75 65 73 20 66  ossible values f
1120: 6f 72 20 53 65 72 76 65 72 2e 65 54 72 61 6e 73  or Server.eTrans
1130: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 53 45 52  ..*/.#define SER
1140: 56 45 52 5f 54 52 41 4e 53 5f 4e 4f 4e 45 20 20  VER_TRANS_NONE  
1150: 20 20 20 20 30 0a 23 64 65 66 69 6e 65 20 53 45      0.#define SE
1160: 52 56 45 52 5f 54 52 41 4e 53 5f 52 45 41 44 4f  RVER_TRANS_READO
1170: 4e 4c 59 20 20 31 0a 23 64 65 66 69 6e 65 20 53  NLY  1.#define S
1180: 45 52 56 45 52 5f 54 52 41 4e 53 5f 52 45 41 44  ERVER_TRANS_READ
1190: 57 52 49 54 45 20 32 0a 0a 23 64 65 66 69 6e 65  WRITE 2..#define
11a0: 20 53 45 52 56 45 52 5f 57 52 49 54 45 5f 4c 4f   SERVER_WRITE_LO
11b0: 43 4b 20 33 0a 23 64 65 66 69 6e 65 20 53 45 52  CK 3.#define SER
11c0: 56 45 52 5f 52 45 41 44 5f 4c 4f 43 4b 20 20 32  VER_READ_LOCK  2
11d0: 0a 23 64 65 66 69 6e 65 20 53 45 52 56 45 52 5f  .#define SERVER_
11e0: 4e 4f 5f 4c 4f 43 4b 20 20 20 20 31 0a 0a 2f 2a  NO_LOCK    1../*
11f0: 0a 2a 2a 20 47 6c 6f 62 61 6c 20 6d 75 74 65 78  .** Global mutex
1200: 20 66 75 6e 63 74 69 6f 6e 73 20 75 73 65 64 20   functions used 
1210: 62 79 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20  by code in this 
1220: 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  file..*/.static 
1230: 76 6f 69 64 20 73 65 72 76 65 72 45 6e 74 65 72  void serverEnter
1240: 4d 75 74 65 78 28 76 6f 69 64 29 7b 0a 20 20 73  Mutex(void){.  s
1250: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
1260: 65 72 28 73 71 6c 69 74 65 33 4d 75 74 65 78 41  er(sqlite3MutexA
1270: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
1280: 58 5f 53 54 41 54 49 43 5f 41 50 50 31 29 29 3b  X_STATIC_APP1));
1290: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  .}.static void s
12a0: 65 72 76 65 72 4c 65 61 76 65 4d 75 74 65 78 28  erverLeaveMutex(
12b0: 76 6f 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33  void){.  sqlite3
12c0: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c  _mutex_leave(sql
12d0: 69 74 65 33 4d 75 74 65 78 41 6c 6c 6f 63 28 53  ite3MutexAlloc(S
12e0: 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54  QLITE_MUTEX_STAT
12f0: 49 43 5f 41 50 50 31 29 29 3b 0a 7d 0a 73 74 61  IC_APP1));.}.sta
1300: 74 69 63 20 76 6f 69 64 20 73 65 72 76 65 72 41  tic void serverA
1310: 73 73 65 72 74 4d 75 74 65 78 48 65 6c 64 28 76  ssertMutexHeld(v
1320: 6f 69 64 29 7b 0a 20 20 61 73 73 65 72 74 28 20  oid){.  assert( 
1330: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
1340: 6c 64 28 73 71 6c 69 74 65 33 4d 75 74 65 78 41  ld(sqlite3MutexA
1350: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
1360: 58 5f 53 54 41 54 49 43 5f 41 50 50 31 29 29 20  X_STATIC_APP1)) 
1370: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
1380: 20 73 65 72 76 65 72 46 69 6e 64 44 61 74 61 62   serverFindDatab
1390: 61 73 65 28 53 65 72 76 65 72 20 2a 70 4e 65 77  ase(Server *pNew
13a0: 2c 20 69 36 34 20 2a 61 46 69 6c 65 49 64 29 7b  , i64 *aFileId){
13b0: 0a 20 20 53 65 72 76 65 72 44 62 20 2a 70 3b 0a  .  ServerDb *p;.
13c0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
13d0: 45 5f 4f 4b 3b 0a 20 20 73 65 72 76 65 72 45 6e  E_OK;.  serverEn
13e0: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 66 6f  terMutex();.  fo
13f0: 72 28 70 3d 67 5f 73 65 72 76 65 72 2e 70 44 62  r(p=g_server.pDb
1400: 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29  ; p; p=p->pNext)
1410: 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 61 46 69  {.    if( p->aFi
1420: 6c 65 49 64 5b 30 5d 3d 3d 61 46 69 6c 65 49 64  leId[0]==aFileId
1430: 5b 30 5d 20 26 26 20 70 2d 3e 61 46 69 6c 65 49  [0] && p->aFileI
1440: 64 5b 31 5d 3d 3d 61 46 69 6c 65 49 64 5b 31 5d  d[1]==aFileId[1]
1450: 20 29 7b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b   ){.      break;
1460: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28  .    }.  }.  if(
1470: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 70 20 3d   p==0 ){.    p =
1480: 20 28 53 65 72 76 65 72 44 62 2a 29 73 71 6c 69   (ServerDb*)sqli
1490: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69  te3MallocZero(si
14a0: 7a 65 6f 66 28 53 65 72 76 65 72 44 62 29 29 3b  zeof(ServerDb));
14b0: 0a 20 20 20 20 69 66 28 20 70 20 29 7b 0a 20 20  .    if( p ){.  
14c0: 20 20 20 20 70 2d 3e 61 53 6c 6f 74 20 3d 20 28      p->aSlot = (
14d0: 75 33 32 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  u32*)sqlite3Mall
14e0: 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 75 33  ocZero(sizeof(u3
14f0: 32 29 2a 48 4d 41 5f 50 41 47 45 4c 4f 43 4b 5f  2)*HMA_PAGELOCK_
1500: 53 4c 4f 54 53 29 3b 0a 20 20 20 20 20 20 69 66  SLOTS);.      if
1510: 28 20 70 2d 3e 61 53 6c 6f 74 3d 3d 30 20 29 7b  ( p->aSlot==0 ){
1520: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
1530: 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b  LITE_NOMEM_BKPT;
1540: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
1550: 20 20 20 20 20 20 70 2d 3e 6d 75 74 65 78 20 3d        p->mutex =
1560: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61   sqlite3_mutex_a
1570: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
1580: 58 5f 46 41 53 54 29 3b 0a 23 69 66 20 53 51 4c  X_FAST);.#if SQL
1590: 49 54 45 5f 54 48 52 45 41 44 53 41 46 45 21 3d  ITE_THREADSAFE!=
15a0: 30 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 2d  0.        if( p-
15b0: 3e 6d 75 74 65 78 3d 3d 30 20 29 20 72 63 20 3d  >mutex==0 ) rc =
15c0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b   SQLITE_NOMEM_BK
15d0: 50 54 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20  PT;.#endif.     
15e0: 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63   }..      if( rc
15f0: 3d 3d 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29  ==SQLITE_NOMEM )
1600: 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  {.        sqlite
1610: 33 5f 66 72 65 65 28 70 2d 3e 61 53 6c 6f 74 29  3_free(p->aSlot)
1620: 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  ;.        sqlite
1630: 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 20  3_free(p);.     
1640: 20 20 20 70 20 3d 20 30 3b 0a 20 20 20 20 20 20     p = 0;.      
1650: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70  }else{.        p
1660: 2d 3e 6e 43 6c 69 65 6e 74 20 3d 20 31 3b 0a 20  ->nClient = 1;. 
1670: 20 20 20 20 20 20 20 70 2d 3e 69 4e 65 78 74 43         p->iNextC
1680: 6f 6d 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 20  ommit = 1;.     
1690: 20 20 20 70 2d 3e 61 46 69 6c 65 49 64 5b 30 5d     p->aFileId[0]
16a0: 20 3d 20 61 46 69 6c 65 49 64 5b 30 5d 3b 0a 20   = aFileId[0];. 
16b0: 20 20 20 20 20 20 20 70 2d 3e 61 46 69 6c 65 49         p->aFileI
16c0: 64 5b 31 5d 20 3d 20 61 46 69 6c 65 49 64 5b 31  d[1] = aFileId[1
16d0: 5d 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 70 4e  ];.        p->pN
16e0: 65 78 74 20 3d 20 67 5f 73 65 72 76 65 72 2e 70  ext = g_server.p
16f0: 44 62 3b 0a 20 20 20 20 20 20 20 20 67 5f 73 65  Db;.        g_se
1700: 72 76 65 72 2e 70 44 62 20 3d 20 70 3b 0a 20 20  rver.pDb = p;.  
1710: 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b      }.    }else{
1720: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
1730: 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20  TE_NOMEM_BKPT;. 
1740: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20     }.  }else{.  
1750: 20 20 70 2d 3e 6e 43 6c 69 65 6e 74 2b 2b 3b 0a    p->nClient++;.
1760: 20 20 7d 0a 20 20 70 4e 65 77 2d 3e 70 44 62 20    }.  pNew->pDb 
1770: 3d 20 70 3b 0a 20 20 73 65 72 76 65 72 4c 65 61  = p;.  serverLea
1780: 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74  veMutex();.  ret
1790: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
17a0: 20 46 72 65 65 20 61 6c 6c 20 72 65 73 6f 75 72   Free all resour
17b0: 63 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  ces allocated by
17c0: 20 73 65 72 76 65 72 49 6e 69 74 44 61 74 61 62   serverInitDatab
17d0: 61 73 65 28 29 20 61 73 73 6f 63 69 61 74 65 64  ase() associated
17e0: 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6f 62 6a   with the.** obj
17f0: 65 63 74 20 70 61 73 73 65 64 20 61 73 20 74 68  ect passed as th
1800: 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e  e only argument.
1810: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1820: 73 65 72 76 65 72 53 68 75 74 64 6f 77 6e 44 61  serverShutdownDa
1830: 74 61 62 61 73 65 28 53 65 72 76 65 72 44 62 20  tabase(ServerDb 
1840: 2a 70 44 62 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  *pDb){.  int i;.
1850: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 4d  .  for(i=0; i<HM
1860: 41 5f 4d 41 58 5f 54 52 41 4e 53 41 43 54 49 4f  A_MAX_TRANSACTIO
1870: 4e 49 44 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 53  NID; i++){.    S
1880: 65 72 76 65 72 4a 6f 75 72 6e 61 6c 20 2a 70 4a  erverJournal *pJ
1890: 20 3d 20 26 70 44 62 2d 3e 61 4a 72 6e 6c 5b 69   = &pDb->aJrnl[i
18a0: 5d 3b 0a 20 20 20 20 69 66 28 20 70 4a 2d 3e 6a  ];.    if( pJ->j
18b0: 66 64 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  fd ){.      sqli
18c0: 74 65 33 4f 73 43 6c 6f 73 65 28 70 4a 2d 3e 6a  te3OsClose(pJ->j
18d0: 66 64 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  fd);.      sqlit
18e0: 65 33 4f 73 44 65 6c 65 74 65 28 70 44 62 2d 3e  e3OsDelete(pDb->
18f0: 70 56 66 73 2c 20 70 4a 2d 3e 7a 4a 6f 75 72 6e  pVfs, pJ->zJourn
1900: 61 6c 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20  al, 0);.    }.  
1910: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
1920: 4a 2d 3e 7a 4a 6f 75 72 6e 61 6c 29 3b 0a 20 20  J->zJournal);.  
1930: 7d 0a 20 20 6d 65 6d 73 65 74 28 70 44 62 2d 3e  }.  memset(pDb->
1940: 61 4a 72 6e 6c 2c 20 30 2c 20 73 69 7a 65 6f 66  aJrnl, 0, sizeof
1950: 28 53 65 72 76 65 72 4a 6f 75 72 6e 61 6c 29 2a  (ServerJournal)*
1960: 48 4d 41 5f 4d 41 58 5f 54 52 41 4e 53 41 43 54  HMA_MAX_TRANSACT
1970: 49 4f 4e 49 44 29 3b 0a 0a 20 20 69 66 28 20 70  IONID);..  if( p
1980: 44 62 2d 3e 61 4a 72 6e 6c 46 64 53 70 61 63 65  Db->aJrnlFdSpace
1990: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
19a0: 66 72 65 65 28 70 44 62 2d 3e 61 4a 72 6e 6c 46  free(pDb->aJrnlF
19b0: 64 53 70 61 63 65 29 3b 0a 20 20 20 20 70 44 62  dSpace);.    pDb
19c0: 2d 3e 61 4a 72 6e 6c 46 64 53 70 61 63 65 20 3d  ->aJrnlFdSpace =
19d0: 20 30 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74   0;.  }..  sqlit
19e0: 65 33 5f 66 72 65 65 28 70 44 62 2d 3e 61 53 6c  e3_free(pDb->aSl
19f0: 6f 74 29 3b 0a 20 20 70 44 62 2d 3e 62 49 6e 69  ot);.  pDb->bIni
1a00: 74 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  t = 0;.}../*.** 
1a10: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
1a20: 20 63 61 6c 6c 65 64 20 77 68 65 6e 20 74 68 65   called when the
1a30: 20 76 65 72 79 20 66 69 72 73 74 20 63 6f 6e 6e   very first conn
1a40: 65 63 74 69 6f 6e 20 74 6f 20 61 20 64 61 74 61  ection to a data
1a50: 62 61 73 65 0a 2a 2a 20 69 73 20 65 73 74 61 62  base.** is estab
1a60: 6c 69 73 68 65 64 2e 20 49 74 20 69 73 20 72 65  lished. It is re
1a70: 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 20 72 6f  sponsible for ro
1a80: 6c 6c 69 6e 67 20 62 61 63 6b 20 61 6e 79 20 68  lling back any h
1a90: 6f 74 20 6a 6f 75 72 6e 61 6c 0a 2a 2a 20 66 69  ot journal.** fi
1aa0: 6c 65 73 20 66 6f 75 6e 64 20 69 6e 20 74 68 65  les found in the
1ab0: 20 66 69 6c 65 2d 73 79 73 74 65 6d 2e 0a 2a 2f   file-system..*/
1ac0: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 72 76  .static int serv
1ad0: 65 72 49 6e 69 74 44 61 74 61 62 61 73 65 28 53  erInitDatabase(S
1ae0: 65 72 76 65 72 20 2a 70 4e 65 77 29 7b 0a 20 20  erver *pNew){.  
1af0: 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74  int nByte;.  int
1b00: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1b10: 0a 20 20 53 65 72 76 65 72 44 62 20 2a 70 44 62  .  ServerDb *pDb
1b20: 20 3d 20 70 4e 65 77 2d 3e 70 44 62 3b 0a 20 20   = pNew->pDb;.  
1b30: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
1b40: 73 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  s;.  const char 
1b50: 2a 7a 46 69 6c 65 6e 61 6d 65 20 3d 20 73 71 6c  *zFilename = sql
1b60: 69 74 65 33 50 61 67 65 72 46 69 6c 65 6e 61 6d  ite3PagerFilenam
1b70: 65 28 70 4e 65 77 2d 3e 70 50 61 67 65 72 2c 20  e(pNew->pPager, 
1b80: 30 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 7a  0);..  assert( z
1b90: 46 69 6c 65 6e 61 6d 65 20 29 3b 0a 20 20 70 56  Filename );.  pV
1ba0: 66 73 20 3d 20 70 44 62 2d 3e 70 56 66 73 20 3d  fs = pDb->pVfs =
1bb0: 20 73 71 6c 69 74 65 33 50 61 67 65 72 56 66 73   sqlite3PagerVfs
1bc0: 28 70 4e 65 77 2d 3e 70 50 61 67 65 72 29 3b 0a  (pNew->pPager);.
1bd0: 20 20 6e 42 79 74 65 20 3d 20 52 4f 55 4e 44 38    nByte = ROUND8
1be0: 28 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 29  (pVfs->szOsFile)
1bf0: 20 2a 20 48 4d 41 5f 4d 41 58 5f 54 52 41 4e 53   * HMA_MAX_TRANS
1c00: 41 43 54 49 4f 4e 49 44 3b 0a 20 20 70 44 62 2d  ACTIONID;.  pDb-
1c10: 3e 61 4a 72 6e 6c 46 64 53 70 61 63 65 20 3d 20  >aJrnlFdSpace = 
1c20: 28 75 38 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  (u8*)sqlite3Mall
1c30: 6f 63 5a 65 72 6f 28 6e 42 79 74 65 29 3b 0a 20  ocZero(nByte);. 
1c40: 20 69 66 28 20 70 44 62 2d 3e 61 4a 72 6e 6c 46   if( pDb->aJrnlF
1c50: 64 53 70 61 63 65 3d 3d 30 20 29 7b 0a 20 20 20  dSpace==0 ){.   
1c60: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
1c70: 45 4d 5f 42 4b 50 54 3b 0a 20 20 7d 65 6c 73 65  EM_BKPT;.  }else
1c80: 7b 0a 20 20 20 20 75 38 20 2a 61 20 3d 20 70 44  {.    u8 *a = pD
1c90: 62 2d 3e 61 4a 72 6e 6c 46 64 53 70 61 63 65 3b  b->aJrnlFdSpace;
1ca0: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
1cb0: 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c  for(i=0; rc==SQL
1cc0: 49 54 45 5f 4f 4b 20 26 26 20 69 3c 48 4d 41 5f  ITE_OK && i<HMA_
1cd0: 4d 41 58 5f 54 52 41 4e 53 41 43 54 49 4f 4e 49  MAX_TRANSACTIONI
1ce0: 44 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  D; i++){.      i
1cf0: 6e 74 20 62 45 78 69 73 74 73 20 3d 20 30 3b 0a  nt bExists = 0;.
1d00: 20 20 20 20 20 20 53 65 72 76 65 72 4a 6f 75 72        ServerJour
1d10: 6e 61 6c 20 2a 70 4a 20 3d 20 26 70 44 62 2d 3e  nal *pJ = &pDb->
1d20: 61 4a 72 6e 6c 5b 69 5d 3b 0a 20 20 20 20 20 20  aJrnl[i];.      
1d30: 70 4a 2d 3e 6a 66 64 20 3d 20 28 73 71 6c 69 74  pJ->jfd = (sqlit
1d40: 65 33 5f 66 69 6c 65 2a 29 26 61 5b 52 4f 55 4e  e3_file*)&a[ROUN
1d50: 44 38 28 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c  D8(pVfs->szOsFil
1d60: 65 29 2a 69 5d 3b 0a 20 20 20 20 20 20 70 4a 2d  e)*i];.      pJ-
1d70: 3e 7a 4a 6f 75 72 6e 61 6c 20 3d 20 73 71 6c 69  >zJournal = sqli
1d80: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 2d  te3_mprintf("%s-
1d90: 6a 6f 75 72 6e 61 6c 25 64 22 2c 20 7a 46 69 6c  journal%d", zFil
1da0: 65 6e 61 6d 65 2c 20 69 29 3b 0a 20 20 20 20 20  ename, i);.     
1db0: 20 69 66 28 20 70 4a 2d 3e 7a 4a 6f 75 72 6e 61   if( pJ->zJourna
1dc0: 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  l==0 ){.        
1dd0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
1de0: 4d 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 20 20  M_BKPT;.        
1df0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a  break;.      }..
1e00: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
1e10: 65 33 4f 73 41 63 63 65 73 73 28 70 56 66 73 2c  e3OsAccess(pVfs,
1e20: 20 70 4a 2d 3e 7a 4a 6f 75 72 6e 61 6c 2c 20 53   pJ->zJournal, S
1e30: 51 4c 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49  QLITE_ACCESS_EXI
1e40: 53 54 53 2c 20 26 62 45 78 69 73 74 73 29 3b 0a  STS, &bExists);.
1e50: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
1e60: 4c 49 54 45 5f 4f 4b 20 26 26 20 62 45 78 69 73  LITE_OK && bExis
1e70: 74 73 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  ts ){.        in
1e80: 74 20 66 6c 61 67 73 20 3d 20 53 51 4c 49 54 45  t flags = SQLITE
1e90: 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 7c  _OPEN_READWRITE|
1ea0: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e  SQLITE_OPEN_MAIN
1eb0: 5f 4a 4f 55 52 4e 41 4c 3b 0a 20 20 20 20 20 20  _JOURNAL;.      
1ec0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
1ed0: 4f 70 65 6e 28 70 56 66 73 2c 20 70 4a 2d 3e 7a  Open(pVfs, pJ->z
1ee0: 4a 6f 75 72 6e 61 6c 2c 20 70 4a 2d 3e 6a 66 64  Journal, pJ->jfd
1ef0: 2c 20 66 6c 61 67 73 2c 20 26 66 6c 61 67 73 29  , flags, &flags)
1f00: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
1f10: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
1f20: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71           rc = sq
1f30: 6c 69 74 65 33 50 61 67 65 72 52 6f 6c 6c 62 61  lite3PagerRollba
1f40: 63 6b 4a 6f 75 72 6e 61 6c 28 70 4e 65 77 2d 3e  ckJournal(pNew->
1f50: 70 50 61 67 65 72 2c 20 70 4a 2d 3e 6a 66 64 29  pPager, pJ->jfd)
1f60: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
1f70: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
1f80: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1f90: 4f 4b 20 29 7b 0a 20 20 20 20 70 44 62 2d 3e 62  OK ){.    pDb->b
1fa0: 49 6e 69 74 20 3d 20 31 3b 0a 20 20 7d 65 6c 73  Init = 1;.  }els
1fb0: 65 7b 0a 20 20 20 20 73 65 72 76 65 72 53 68 75  e{.    serverShu
1fc0: 74 64 6f 77 6e 44 61 74 61 62 61 73 65 28 70 4e  tdownDatabase(pN
1fd0: 65 77 2d 3e 70 44 62 29 3b 0a 20 20 7d 0a 20 20  ew->pDb);.  }.  
1fe0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1ff0: 0a 2a 2a 20 43 6c 6f 73 65 20 74 68 65 20 63 6f  .** Close the co
2000: 6e 6e 65 63 74 69 6f 6e 2e 0a 2a 2f 0a 76 6f 69  nnection..*/.voi
2010: 64 20 73 71 6c 69 74 65 33 53 65 72 76 65 72 44  d sqlite3ServerD
2020: 69 73 63 6f 6e 6e 65 63 74 28 53 65 72 76 65 72  isconnect(Server
2030: 20 2a 70 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c   *p, sqlite3_fil
2040: 65 20 2a 64 62 66 64 29 7b 0a 20 20 53 65 72 76  e *dbfd){.  Serv
2050: 65 72 44 62 20 2a 70 44 62 20 3d 20 70 2d 3e 70  erDb *pDb = p->p
2060: 44 62 3b 0a 0a 20 20 73 65 72 76 65 72 45 6e 74  Db;..  serverEnt
2070: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 44 62  erMutex();.  pDb
2080: 2d 3e 6e 43 6c 69 65 6e 74 2d 2d 3b 0a 20 20 69  ->nClient--;.  i
2090: 66 28 20 70 44 62 2d 3e 6e 43 6c 69 65 6e 74 3d  f( pDb->nClient=
20a0: 3d 30 20 29 7b 0a 20 20 20 20 53 65 72 76 65 72  =0 ){.    Server
20b0: 44 62 20 2a 2a 70 70 3b 0a 20 20 20 20 73 65 72  Db **pp;.    ser
20c0: 76 65 72 53 68 75 74 64 6f 77 6e 44 61 74 61 62  verShutdownDatab
20d0: 61 73 65 28 70 44 62 29 3b 0a 20 20 20 20 66 6f  ase(pDb);.    fo
20e0: 72 28 70 70 3d 26 67 5f 73 65 72 76 65 72 2e 70  r(pp=&g_server.p
20f0: 44 62 3b 20 2a 70 70 21 3d 70 44 62 3b 20 70 70  Db; *pp!=pDb; pp
2100: 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29  =&((*pp)->pNext)
2110: 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20 70 44 62  );.    *pp = pDb
2120: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c  ->pNext;.    sql
2130: 69 74 65 33 5f 6d 75 74 65 78 5f 66 72 65 65 28  ite3_mutex_free(
2140: 70 44 62 2d 3e 6d 75 74 65 78 29 3b 0a 20 20 20  pDb->mutex);.   
2150: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 44   sqlite3_free(pD
2160: 62 29 3b 0a 20 20 7d 0a 20 20 73 65 72 76 65 72  b);.  }.  server
2170: 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 0a 20  LeaveMutex();.. 
2180: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
2190: 3e 61 4c 6f 63 6b 29 3b 0a 20 20 73 71 6c 69 74  >aLock);.  sqlit
21a0: 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f  e3_free(p);.}../
21b0: 2a 0a 2a 2a 20 43 6f 6e 6e 65 63 74 20 74 6f 20  *.** Connect to 
21c0: 74 68 65 20 73 79 73 74 65 6d 2e 0a 2a 2f 0a 69  the system..*/.i
21d0: 6e 74 20 73 71 6c 69 74 65 33 53 65 72 76 65 72  nt sqlite3Server
21e0: 43 6f 6e 6e 65 63 74 28 0a 20 20 50 61 67 65 72  Connect(.  Pager
21f0: 20 2a 70 50 61 67 65 72 2c 0a 20 20 53 65 72 76   *pPager,.  Serv
2200: 65 72 20 2a 2a 70 70 4f 75 74 20 20 20 20 20 20  er **ppOut      
2210: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
2220: 55 54 3a 20 53 65 72 76 65 72 20 68 61 6e 64 6c  UT: Server handl
2230: 65 20 2a 2f 0a 29 7b 0a 20 20 53 65 72 76 65 72  e */.){.  Server
2240: 20 2a 70 4e 65 77 20 3d 20 30 3b 0a 20 20 73 71   *pNew = 0;.  sq
2250: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 64 62 66 64  lite3_file *dbfd
2260: 20 3d 20 73 71 6c 69 74 65 33 50 61 67 65 72 46   = sqlite3PagerF
2270: 69 6c 65 28 70 50 61 67 65 72 29 3b 0a 20 20 69  ile(pPager);.  i
2280: 36 34 20 61 46 69 6c 65 49 64 5b 32 5d 3b 0a 20  64 aFileId[2];. 
2290: 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d   int rc;..  rc =
22a0: 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f   sqlite3OsFileCo
22b0: 6e 74 72 6f 6c 28 64 62 66 64 2c 20 53 51 4c 49  ntrol(dbfd, SQLI
22c0: 54 45 5f 46 43 4e 54 4c 5f 46 49 4c 45 49 44 2c  TE_FCNTL_FILEID,
22d0: 20 28 76 6f 69 64 2a 29 61 46 69 6c 65 49 64 29   (void*)aFileId)
22e0: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
22f0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 4e 65  TE_OK ){.    pNe
2300: 77 20 3d 20 28 53 65 72 76 65 72 2a 29 73 71 6c  w = (Server*)sql
2310: 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73  ite3MallocZero(s
2320: 69 7a 65 6f 66 28 53 65 72 76 65 72 29 29 3b 0a  izeof(Server));.
2330: 20 20 20 20 69 66 28 20 70 4e 65 77 20 29 7b 0a      if( pNew ){.
2340: 20 20 20 20 20 20 70 4e 65 77 2d 3e 70 50 61 67        pNew->pPag
2350: 65 72 20 3d 20 70 50 61 67 65 72 3b 0a 20 20 20  er = pPager;.   
2360: 20 20 20 70 4e 65 77 2d 3e 69 54 72 61 6e 73 49     pNew->iTransI
2370: 64 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 72 63  d = -1;.      rc
2380: 20 3d 20 73 65 72 76 65 72 46 69 6e 64 44 61 74   = serverFindDat
2390: 61 62 61 73 65 28 70 4e 65 77 2c 20 61 46 69 6c  abase(pNew, aFil
23a0: 65 49 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20  eId);.      if( 
23b0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
23c0: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
23d0: 5f 66 72 65 65 28 70 4e 65 77 29 3b 0a 20 20 20  _free(pNew);.   
23e0: 20 20 20 20 20 70 4e 65 77 20 3d 20 30 3b 0a 20       pNew = 0;. 
23f0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
2400: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
2410: 78 5f 65 6e 74 65 72 28 70 4e 65 77 2d 3e 70 44  x_enter(pNew->pD
2420: 62 2d 3e 6d 75 74 65 78 29 3b 0a 20 20 20 20 20  b->mutex);.     
2430: 20 20 20 69 66 28 20 70 4e 65 77 2d 3e 70 44 62     if( pNew->pDb
2440: 2d 3e 62 49 6e 69 74 3d 3d 30 20 29 7b 0a 20 20  ->bInit==0 ){.  
2450: 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 72          rc = ser
2460: 76 65 72 49 6e 69 74 44 61 74 61 62 61 73 65 28  verInitDatabase(
2470: 70 4e 65 77 29 3b 0a 20 20 20 20 20 20 20 20 7d  pNew);.        }
2480: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
2490: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 4e 65  _mutex_leave(pNe
24a0: 77 2d 3e 70 44 62 2d 3e 6d 75 74 65 78 29 3b 0a  w->pDb->mutex);.
24b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
24c0: 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  e{.      rc = SQ
24d0: 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b  LITE_NOMEM_BKPT;
24e0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70  .    }.  }..  *p
24f0: 70 4f 75 74 20 3d 20 70 4e 65 77 3b 0a 20 20 72  pOut = pNew;.  r
2500: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
2510: 2a 2a 20 42 65 67 69 6e 20 61 20 74 72 61 6e 73  ** Begin a trans
2520: 61 63 74 69 6f 6e 2e 0a 2a 2f 0a 69 6e 74 20 73  action..*/.int s
2530: 71 6c 69 74 65 33 53 65 72 76 65 72 42 65 67 69  qlite3ServerBegi
2540: 6e 28 53 65 72 76 65 72 20 2a 70 2c 20 69 6e 74  n(Server *p, int
2550: 20 62 52 65 61 64 6f 6e 6c 79 29 7b 0a 20 20 69   bReadonly){.  i
2560: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2570: 4b 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 65 54 72  K;..  if( p->eTr
2580: 61 6e 73 3d 3d 53 45 52 56 45 52 5f 54 52 41 4e  ans==SERVER_TRAN
2590: 53 5f 4e 4f 4e 45 20 29 7b 0a 20 20 20 20 69 6e  S_NONE ){.    in
25a0: 74 20 69 64 3b 0a 20 20 20 20 53 65 72 76 65 72  t id;.    Server
25b0: 44 62 20 2a 70 44 62 20 3d 20 70 2d 3e 70 44 62  Db *pDb = p->pDb
25c0: 3b 0a 20 20 20 20 75 33 32 20 74 3b 0a 0a 20 20  ;.    u32 t;..  
25d0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 69 54 72    assert( p->iTr
25e0: 61 6e 73 49 64 3c 30 20 29 3b 0a 20 20 20 20 61  ansId<0 );.    a
25f0: 73 73 65 72 74 28 20 70 2d 3e 70 4e 65 78 74 3d  ssert( p->pNext=
2600: 3d 30 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  =0 );.    sqlite
2610: 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 44  3_mutex_enter(pD
2620: 62 2d 3e 6d 75 74 65 78 29 3b 0a 0a 20 20 20 20  b->mutex);..    
2630: 69 66 28 20 62 52 65 61 64 6f 6e 6c 79 20 29 7b  if( bReadonly ){
2640: 0a 20 20 20 20 20 20 53 65 72 76 65 72 20 2a 70  .      Server *p
2650: 49 74 65 72 3b 0a 20 20 20 20 20 20 70 2d 3e 69  Iter;.      p->i
2660: 43 6f 6d 6d 69 74 49 64 20 3d 20 70 44 62 2d 3e  CommitId = pDb->
2670: 69 4e 65 78 74 43 6f 6d 6d 69 74 3b 0a 20 20 20  iNextCommit;.   
2680: 20 20 20 66 6f 72 28 70 49 74 65 72 3d 70 44 62     for(pIter=pDb
2690: 2d 3e 70 43 6f 6d 6d 69 74 3b 20 70 49 74 65 72  ->pCommit; pIter
26a0: 3b 20 70 49 74 65 72 3d 70 49 74 65 72 2d 3e 70  ; pIter=pIter->p
26b0: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20 69  Next){.        i
26c0: 66 28 20 70 49 74 65 72 2d 3e 69 43 6f 6d 6d 69  f( pIter->iCommi
26d0: 74 49 64 3c 70 2d 3e 69 43 6f 6d 6d 69 74 49 64  tId<p->iCommitId
26e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 2d   ){.          p-
26f0: 3e 69 43 6f 6d 6d 69 74 49 64 20 3d 20 70 49 74  >iCommitId = pIt
2700: 65 72 2d 3e 69 43 6f 6d 6d 69 74 49 64 3b 0a 20  er->iCommitId;. 
2710: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
2720: 0a 20 20 20 20 20 20 70 2d 3e 70 4e 65 78 74 20  .      p->pNext 
2730: 3d 20 70 44 62 2d 3e 70 52 65 61 64 65 72 3b 0a  = pDb->pReader;.
2740: 20 20 20 20 20 20 70 44 62 2d 3e 70 52 65 61 64        pDb->pRead
2750: 65 72 20 3d 20 70 3b 0a 20 20 20 20 20 20 70 2d  er = p;.      p-
2760: 3e 65 54 72 61 6e 73 20 3d 20 53 45 52 56 45 52  >eTrans = SERVER
2770: 5f 54 52 41 4e 53 5f 52 45 41 44 4f 4e 4c 59 3b  _TRANS_READONLY;
2780: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
2790: 20 20 2f 2a 20 46 69 6e 64 20 61 20 74 72 61 6e    /* Find a tran
27a0: 73 61 63 74 69 6f 6e 20 69 64 20 74 6f 20 75 73  saction id to us
27b0: 65 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20  e */.      rc = 
27c0: 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20 20  SQLITE_BUSY;.   
27d0: 20 20 20 74 20 3d 20 70 44 62 2d 3e 74 72 61 6e     t = pDb->tran
27e0: 73 6d 61 73 6b 3b 0a 20 20 20 20 20 20 66 6f 72  smask;.      for
27f0: 28 69 64 3d 30 3b 20 69 64 3c 48 4d 41 5f 4d 41  (id=0; id<HMA_MA
2800: 58 5f 54 52 41 4e 53 41 43 54 49 4f 4e 49 44 3b  X_TRANSACTIONID;
2810: 20 69 64 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20   id++){.        
2820: 69 66 28 20 28 74 20 26 20 28 31 20 3c 3c 20 69  if( (t & (1 << i
2830: 64 29 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  d))==0 ){.      
2840: 20 20 20 20 74 20 3d 20 74 20 7c 20 28 31 20 3c      t = t | (1 <
2850: 3c 20 69 64 29 3b 0a 20 20 20 20 20 20 20 20 20  < id);.         
2860: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
2870: 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b  .          break
2880: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
2890: 20 20 7d 0a 20 20 20 20 20 20 70 44 62 2d 3e 74    }.      pDb->t
28a0: 72 61 6e 73 6d 61 73 6b 20 3d 20 74 3b 0a 20 20  ransmask = t;.  
28b0: 20 20 20 20 70 2d 3e 65 54 72 61 6e 73 20 3d 20      p->eTrans = 
28c0: 53 45 52 56 45 52 5f 54 52 41 4e 53 5f 52 45 41  SERVER_TRANS_REA
28d0: 44 57 52 49 54 45 3b 0a 20 20 20 20 7d 0a 0a 20  DWRITE;.    }.. 
28e0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
28f0: 5f 6c 65 61 76 65 28 70 44 62 2d 3e 6d 75 74 65  _leave(pDb->mute
2900: 78 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 63 3d  x);..    if( rc=
2910: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 62 52  =SQLITE_OK && bR
2920: 65 61 64 6f 6e 6c 79 3d 3d 30 20 29 7b 0a 20 20  eadonly==0 ){.  
2930: 20 20 20 20 53 65 72 76 65 72 4a 6f 75 72 6e 61      ServerJourna
2940: 6c 20 2a 70 4a 72 6e 6c 20 3d 20 26 70 44 62 2d  l *pJrnl = &pDb-
2950: 3e 61 4a 72 6e 6c 5b 69 64 5d 3b 0a 20 20 20 20  >aJrnl[id];.    
2960: 20 20 73 71 6c 69 74 65 33 50 61 67 65 72 53 65    sqlite3PagerSe
2970: 72 76 65 72 4a 6f 75 72 6e 61 6c 28 70 2d 3e 70  rverJournal(p->p
2980: 50 61 67 65 72 2c 20 70 4a 72 6e 6c 2d 3e 6a 66  Pager, pJrnl->jf
2990: 64 2c 20 70 4a 72 6e 6c 2d 3e 7a 4a 6f 75 72 6e  d, pJrnl->zJourn
29a0: 61 6c 29 3b 0a 20 20 20 20 20 20 70 2d 3e 69 54  al);.      p->iT
29b0: 72 61 6e 73 49 64 20 3d 20 69 64 3b 0a 20 20 20  ransId = id;.   
29c0: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
29d0: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76   rc;.}..static v
29e0: 6f 69 64 20 73 65 72 76 65 72 52 65 6c 65 61 73  oid serverReleas
29f0: 65 4c 6f 63 6b 73 28 53 65 72 76 65 72 20 2a 70  eLocks(Server *p
2a00: 29 7b 0a 20 20 53 65 72 76 65 72 44 62 20 2a 70  ){.  ServerDb *p
2a10: 44 62 20 3d 20 70 2d 3e 70 44 62 3b 0a 20 20 69  Db = p->pDb;.  i
2a20: 6e 74 20 69 3b 0a 20 20 61 73 73 65 72 74 28 20  nt i;.  assert( 
2a30: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
2a40: 6c 64 28 70 44 62 2d 3e 6d 75 74 65 78 29 20 29  ld(pDb->mutex) )
2a50: 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  ;..  for(i=0; i<
2a60: 70 2d 3e 6e 4c 6f 63 6b 3b 20 69 2b 2b 29 7b 0a  p->nLock; i++){.
2a70: 20 20 20 20 75 33 32 20 2a 70 53 6c 6f 74 20 3d      u32 *pSlot =
2a80: 20 26 70 44 62 2d 3e 61 53 6c 6f 74 5b 70 2d 3e   &pDb->aSlot[p->
2a90: 61 4c 6f 63 6b 5b 69 5d 20 25 20 48 4d 41 5f 50  aLock[i] % HMA_P
2aa0: 41 47 45 4c 4f 43 4b 5f 53 4c 4f 54 53 5d 3b 0a  AGELOCK_SLOTS];.
2ab0: 20 20 20 20 69 66 28 20 73 6c 6f 74 47 65 74 57      if( slotGetW
2ac0: 72 69 74 65 72 28 2a 70 53 6c 6f 74 29 3d 3d 70  riter(*pSlot)==p
2ad0: 2d 3e 69 54 72 61 6e 73 49 64 20 29 7b 0a 20 20  ->iTransId ){.  
2ae0: 20 20 20 20 2a 70 53 6c 6f 74 20 2d 3d 20 28 28      *pSlot -= ((
2af0: 70 2d 3e 69 54 72 61 6e 73 49 64 20 2b 20 31 29  p->iTransId + 1)
2b00: 20 3c 3c 20 48 4d 41 5f 4d 41 58 5f 54 52 41 4e   << HMA_MAX_TRAN
2b10: 53 41 43 54 49 4f 4e 49 44 29 3b 0a 20 20 20 20  SACTIONID);.    
2b20: 7d 0a 20 20 20 20 2a 70 53 6c 6f 74 20 26 3d 20  }.    *pSlot &= 
2b30: 7e 28 28 75 33 32 29 31 20 3c 3c 20 70 2d 3e 69  ~((u32)1 << p->i
2b40: 54 72 61 6e 73 49 64 29 3b 0a 20 20 7d 0a 0a 20  TransId);.  }.. 
2b50: 20 70 2d 3e 6e 4c 6f 63 6b 20 3d 20 30 3b 0a 7d   p->nLock = 0;.}
2b60: 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 61 20 74 72  ../*.** End a tr
2b70: 61 6e 73 61 63 74 69 6f 6e 20 28 61 6e 64 20 72  ansaction (and r
2b80: 65 6c 65 61 73 65 20 61 6c 6c 20 6c 6f 63 6b 73  elease all locks
2b90: 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  )..*/.int sqlite
2ba0: 33 53 65 72 76 65 72 45 6e 64 28 53 65 72 76 65  3ServerEnd(Serve
2bb0: 72 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72 63 20  r *p){.  int rc 
2bc0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
2bd0: 66 28 20 70 2d 3e 65 54 72 61 6e 73 21 3d 53 45  f( p->eTrans!=SE
2be0: 52 56 45 52 5f 54 52 41 4e 53 5f 4e 4f 4e 45 20  RVER_TRANS_NONE 
2bf0: 29 7b 0a 20 20 20 20 53 65 72 76 65 72 20 2a 2a  ){.    Server **
2c00: 70 70 3b 0a 20 20 20 20 53 65 72 76 65 72 44 62  pp;.    ServerDb
2c10: 20 2a 70 44 62 20 3d 20 70 2d 3e 70 44 62 3b 0a   *pDb = p->pDb;.
2c20: 20 20 20 20 53 65 72 76 65 72 50 61 67 65 20 2a      ServerPage *
2c30: 70 46 72 65 65 20 3d 20 30 3b 0a 20 20 20 20 53  pFree = 0;.    S
2c40: 65 72 76 65 72 50 61 67 65 20 2a 70 50 67 20 3d  erverPage *pPg =
2c50: 20 30 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33   0;..    sqlite3
2c60: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 44 62  _mutex_enter(pDb
2c70: 2d 3e 6d 75 74 65 78 29 3b 0a 0a 20 20 20 20 69  ->mutex);..    i
2c80: 66 28 20 70 2d 3e 65 54 72 61 6e 73 3d 3d 53 45  f( p->eTrans==SE
2c90: 52 56 45 52 5f 54 52 41 4e 53 5f 52 45 41 44 4f  RVER_TRANS_READO
2ca0: 4e 4c 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  NLY ){.      /* 
2cb0: 52 65 6d 6f 76 65 20 74 68 65 20 63 6f 6e 6e 65  Remove the conne
2cc0: 63 74 69 6f 6e 20 66 72 6f 6d 20 74 68 65 20 72  ction from the r
2cd0: 65 61 64 65 72 73 20 6c 69 73 74 20 2a 2f 0a 20  eaders list */. 
2ce0: 20 20 20 20 20 66 6f 72 28 70 70 3d 26 70 44 62       for(pp=&pDb
2cf0: 2d 3e 70 52 65 61 64 65 72 3b 20 2a 70 70 21 3d  ->pReader; *pp!=
2d00: 70 3b 20 70 70 20 3d 20 26 28 28 2a 70 70 29 2d  p; pp = &((*pp)-
2d10: 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20 20 20  >pNext));.      
2d20: 2a 70 70 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a  *pp = p->pNext;.
2d30: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
2d40: 20 73 65 72 76 65 72 52 65 6c 65 61 73 65 4c 6f   serverReleaseLo
2d50: 63 6b 73 28 70 29 3b 0a 0a 20 20 20 20 20 20 2f  cks(p);..      /
2d60: 2a 20 43 6c 65 61 72 20 74 68 65 20 62 69 74 20  * Clear the bit 
2d70: 69 6e 20 74 68 65 20 74 72 61 6e 73 61 63 74 69  in the transacti
2d80: 6f 6e 20 6d 61 73 6b 2e 20 2a 2f 0a 20 20 20 20  on mask. */.    
2d90: 20 20 70 44 62 2d 3e 74 72 61 6e 73 6d 61 73 6b    pDb->transmask
2da0: 20 26 3d 20 7e 28 28 75 33 32 29 31 20 3c 3c 20   &= ~((u32)1 << 
2db0: 70 2d 3e 69 54 72 61 6e 73 49 64 29 3b 0a 0a 20  p->iTransId);.. 
2dc0: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20       /* If this 
2dd0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20 69 6e  connection is in
2de0: 20 74 68 65 20 63 6f 6d 6d 69 74 74 65 72 73 20   the committers 
2df0: 6c 69 73 74 2c 20 72 65 6d 6f 76 65 20 69 74 2e  list, remove it.
2e00: 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 70 70   */.      for(pp
2e10: 3d 26 70 44 62 2d 3e 70 43 6f 6d 6d 69 74 3b 20  =&pDb->pCommit; 
2e20: 2a 70 70 3b 20 70 70 20 3d 20 26 28 28 2a 70 70  *pp; pp = &((*pp
2e30: 29 2d 3e 70 4e 65 78 74 29 29 7b 0a 20 20 20 20  )->pNext)){.    
2e40: 20 20 20 20 69 66 28 20 2a 70 70 3d 3d 70 20 29      if( *pp==p )
2e50: 7b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 70 20  {.          *pp 
2e60: 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  = p->pNext;.    
2e70: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
2e80: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
2e90: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 53 65 65     }..    /* See
2ea0: 20 69 66 20 69 74 20 69 73 20 70 6f 73 73 69 62   if it is possib
2eb0: 6c 65 20 74 6f 20 66 72 65 65 20 61 6e 79 20 53  le to free any S
2ec0: 65 72 76 65 72 50 61 67 65 20 72 65 63 6f 72 64  erverPage record
2ed0: 73 2e 20 49 66 20 73 6f 2c 20 72 65 6d 6f 76 65  s. If so, remove
2ee0: 0a 20 20 20 20 2a 2a 20 74 68 65 6d 20 66 72 6f  .    ** them fro
2ef0: 6d 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73  m the linked lis
2f00: 74 20 61 6e 64 20 68 61 73 68 20 74 61 62 6c 65  t and hash table
2f10: 2c 20 62 75 74 20 64 6f 20 6e 6f 74 20 63 61 6c  , but do not cal
2f20: 6c 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29  l sqlite3_free()
2f30: 0a 20 20 20 20 2a 2a 20 6f 6e 20 74 68 65 6d 20  .    ** on them 
2f40: 75 6e 74 69 6c 20 74 68 65 20 6d 75 74 65 78 20  until the mutex 
2f50: 68 61 73 20 62 65 65 6e 20 72 65 6c 65 61 73 65  has been release
2f60: 64 2e 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70  d.  */.    if( p
2f70: 44 62 2d 3e 70 50 67 46 69 72 73 74 20 29 7b 0a  Db->pPgFirst ){.
2f80: 20 20 20 20 20 20 53 65 72 76 65 72 20 2a 70 49        Server *pI
2f90: 74 65 72 3b 0a 20 20 20 20 20 20 69 6e 74 20 69  ter;.      int i
2fa0: 4f 6c 64 65 73 74 20 3d 20 30 78 37 46 46 46 46  Oldest = 0x7FFFF
2fb0: 46 46 46 3b 0a 20 20 20 20 20 20 66 6f 72 28 70  FFF;.      for(p
2fc0: 49 74 65 72 3d 70 44 62 2d 3e 70 52 65 61 64 65  Iter=pDb->pReade
2fd0: 72 3b 20 70 49 74 65 72 3b 20 70 49 74 65 72 3d  r; pIter; pIter=
2fe0: 70 49 74 65 72 2d 3e 70 4e 65 78 74 29 7b 0a 20  pIter->pNext){. 
2ff0: 20 20 20 20 20 20 20 69 4f 6c 64 65 73 74 20 3d         iOldest =
3000: 20 4d 49 4e 28 69 4f 6c 64 65 73 74 2c 20 70 49   MIN(iOldest, pI
3010: 74 65 72 2d 3e 69 43 6f 6d 6d 69 74 49 64 29 3b  ter->iCommitId);
3020: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 66  .      }.      f
3030: 6f 72 28 70 49 74 65 72 3d 70 44 62 2d 3e 70 43  or(pIter=pDb->pC
3040: 6f 6d 6d 69 74 3b 20 70 49 74 65 72 3b 20 70 49  ommit; pIter; pI
3050: 74 65 72 3d 70 49 74 65 72 2d 3e 70 4e 65 78 74  ter=pIter->pNext
3060: 29 7b 0a 20 20 20 20 20 20 20 20 69 4f 6c 64 65  ){.        iOlde
3070: 73 74 20 3d 20 4d 49 4e 28 69 4f 6c 64 65 73 74  st = MIN(iOldest
3080: 2c 20 70 49 74 65 72 2d 3e 69 43 6f 6d 6d 69 74  , pIter->iCommit
3090: 49 64 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  Id);.      }..  
30a0: 20 20 20 20 70 46 72 65 65 20 3d 20 70 44 62 2d      pFree = pDb-
30b0: 3e 70 50 67 46 69 72 73 74 3b 0a 20 20 20 20 20  >pPgFirst;.     
30c0: 20 66 6f 72 28 70 50 67 3d 70 44 62 2d 3e 70 50   for(pPg=pDb->pP
30d0: 67 46 69 72 73 74 3b 20 70 50 67 20 26 26 20 70  gFirst; pPg && p
30e0: 50 67 2d 3e 69 43 6f 6d 6d 69 74 49 64 3c 69 4f  Pg->iCommitId<iO
30f0: 6c 64 65 73 74 3b 20 70 50 67 3d 70 50 67 2d 3e  ldest; pPg=pPg->
3100: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20  pNext){.        
3110: 69 66 28 20 70 50 67 2d 3e 70 48 61 73 68 50 72  if( pPg->pHashPr
3120: 65 76 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ev ){.          
3130: 70 50 67 2d 3e 70 48 61 73 68 50 72 65 76 2d 3e  pPg->pHashPrev->
3140: 70 48 61 73 68 4e 65 78 74 20 3d 20 70 50 67 2d  pHashNext = pPg-
3150: 3e 70 48 61 73 68 4e 65 78 74 3b 0a 20 20 20 20  >pHashNext;.    
3160: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
3170: 20 20 20 20 20 69 6e 74 20 69 48 61 73 68 20 3d       int iHash =
3180: 20 70 50 67 2d 3e 70 67 6e 6f 20 25 20 48 4d 41   pPg->pgno % HMA
3190: 5f 48 41 53 48 5f 53 49 5a 45 3b 0a 20 20 20 20  _HASH_SIZE;.    
31a0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 44        assert( pD
31b0: 62 2d 3e 61 70 50 67 5b 69 48 61 73 68 5d 3d 3d  b->apPg[iHash]==
31c0: 70 50 67 20 29 3b 0a 20 20 20 20 20 20 20 20 20  pPg );.         
31d0: 20 70 44 62 2d 3e 61 70 50 67 5b 69 48 61 73 68   pDb->apPg[iHash
31e0: 5d 20 3d 20 70 50 67 2d 3e 70 48 61 73 68 4e 65  ] = pPg->pHashNe
31f0: 78 74 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  xt;.        }.  
3200: 20 20 20 20 20 20 69 66 28 20 70 50 67 2d 3e 70        if( pPg->p
3210: 48 61 73 68 4e 65 78 74 20 29 7b 0a 20 20 20 20  HashNext ){.    
3220: 20 20 20 20 20 20 70 50 67 2d 3e 70 48 61 73 68        pPg->pHash
3230: 4e 65 78 74 2d 3e 70 48 61 73 68 50 72 65 76 20  Next->pHashPrev 
3240: 3d 20 70 50 67 2d 3e 70 48 61 73 68 50 72 65 76  = pPg->pHashPrev
3250: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
3260: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 70 50    }.      if( pP
3270: 67 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  g==0 ){.        
3280: 70 44 62 2d 3e 70 50 67 46 69 72 73 74 20 3d 20  pDb->pPgFirst = 
3290: 70 44 62 2d 3e 70 50 67 4c 61 73 74 20 3d 20 30  pDb->pPgLast = 0
32a0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
32b0: 20 20 20 20 20 20 20 70 44 62 2d 3e 70 50 67 46         pDb->pPgF
32c0: 69 72 73 74 20 3d 20 70 50 67 3b 0a 20 20 20 20  irst = pPg;.    
32d0: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73    }.    }..    s
32e0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
32f0: 76 65 28 70 44 62 2d 3e 6d 75 74 65 78 29 3b 0a  ve(pDb->mutex);.
3300: 0a 20 20 20 20 2f 2a 20 43 61 6c 6c 20 73 71 6c  .    /* Call sql
3310: 69 74 65 33 5f 66 72 65 65 28 29 20 6f 6e 20 61  ite3_free() on a
3320: 6e 79 20 70 61 67 65 73 20 74 68 61 74 20 77 65  ny pages that we
3330: 72 65 20 75 6e 6c 69 6e 6b 65 64 20 66 72 6f 6d  re unlinked from
3340: 20 74 68 65 20 68 61 73 68 0a 20 20 20 20 2a 2a   the hash.    **
3350: 20 74 61 62 6c 65 20 61 62 6f 76 65 2e 20 2a 2f   table above. */
3360: 0a 20 20 20 20 77 68 69 6c 65 28 20 70 46 72 65  .    while( pFre
3370: 65 20 26 26 20 70 46 72 65 65 21 3d 70 50 67 20  e && pFree!=pPg 
3380: 29 7b 0a 20 20 20 20 20 20 53 65 72 76 65 72 50  ){.      ServerP
3390: 61 67 65 20 2a 70 4e 65 78 74 20 3d 20 70 46 72  age *pNext = pFr
33a0: 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ee->pNext;.     
33b0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 46   sqlite3_free(pF
33c0: 72 65 65 29 3b 0a 20 20 20 20 20 20 70 46 72 65  ree);.      pFre
33d0: 65 20 3d 20 70 4e 65 78 74 3b 0a 20 20 20 20 7d  e = pNext;.    }
33e0: 0a 0a 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d  ..    p->pNext =
33f0: 20 30 3b 0a 20 20 20 20 70 2d 3e 65 54 72 61 6e   0;.    p->eTran
3400: 73 20 3d 20 53 45 52 56 45 52 5f 54 52 41 4e 53  s = SERVER_TRANS
3410: 5f 4e 4f 4e 45 3b 0a 20 20 20 20 70 2d 3e 69 54  _NONE;.    p->iT
3420: 72 61 6e 73 49 64 20 3d 20 2d 31 3b 0a 20 20 20  ransId = -1;.   
3430: 20 70 2d 3e 69 43 6f 6d 6d 69 74 49 64 20 3d 20   p->iCommitId = 
3440: 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  0;.  }.  return 
3450: 72 63 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74  rc;.}..int sqlit
3460: 65 33 53 65 72 76 65 72 50 72 65 43 6f 6d 6d 69  e3ServerPreCommi
3470: 74 28 53 65 72 76 65 72 20 2a 70 2c 20 53 65 72  t(Server *p, Ser
3480: 76 65 72 50 61 67 65 20 2a 70 50 67 29 7b 0a 20  verPage *pPg){. 
3490: 20 53 65 72 76 65 72 44 62 20 2a 70 44 62 20 3d   ServerDb *pDb =
34a0: 20 70 2d 3e 70 44 62 3b 0a 20 20 69 6e 74 20 72   p->pDb;.  int r
34b0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
34c0: 20 53 65 72 76 65 72 50 61 67 65 20 2a 70 49 74   ServerPage *pIt
34d0: 65 72 3b 0a 0a 20 20 69 66 28 20 70 50 67 3d 3d  er;..  if( pPg==
34e0: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
34f0: 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69 74 65 33  E_OK;..  sqlite3
3500: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 44 62  _mutex_enter(pDb
3510: 2d 3e 6d 75 74 65 78 29 3b 0a 0a 20 20 2f 2a 20  ->mutex);..  /* 
3520: 41 73 73 69 67 6e 20 61 20 63 6f 6d 6d 69 74 20  Assign a commit 
3530: 69 64 20 74 6f 20 74 68 69 73 20 74 72 61 6e 73  id to this trans
3540: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65  action */.  asse
3550: 72 74 28 20 70 2d 3e 69 43 6f 6d 6d 69 74 49 64  rt( p->iCommitId
3560: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
3570: 20 70 2d 3e 65 54 72 61 6e 73 3d 3d 53 45 52 56   p->eTrans==SERV
3580: 45 52 5f 54 52 41 4e 53 5f 52 45 41 44 57 52 49  ER_TRANS_READWRI
3590: 54 45 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  TE );.  assert( 
35a0: 70 2d 3e 69 54 72 61 6e 73 49 64 3e 3d 30 20 29  p->iTransId>=0 )
35b0: 3b 0a 0a 20 20 70 2d 3e 69 43 6f 6d 6d 69 74 49  ;..  p->iCommitI
35c0: 64 20 3d 20 70 44 62 2d 3e 69 4e 65 78 74 43 6f  d = pDb->iNextCo
35d0: 6d 6d 69 74 2b 2b 3b 0a 0a 20 20 2f 2a 20 49 74  mmit++;..  /* It
35e0: 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 6c  erate through al
35f0: 6c 20 70 61 67 65 73 2e 20 46 6f 72 20 65 61 63  l pages. For eac
3600: 68 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 31  h:.  **.  **   1
3610: 2e 20 53 65 74 20 74 68 65 20 69 43 6f 6d 6d 69  . Set the iCommi
3620: 74 49 64 20 66 69 65 6c 64 2e 0a 20 20 2a 2a 20  tId field..  ** 
3630: 20 20 32 2e 20 41 64 64 20 74 68 65 20 70 61 67    2. Add the pag
3640: 65 20 74 6f 20 74 68 65 20 68 61 73 68 20 74 61  e to the hash ta
3650: 62 6c 65 2e 0a 20 20 2a 2a 20 20 20 33 2e 20 57  ble..  **   3. W
3660: 61 69 74 20 75 6e 74 69 6c 20 61 6c 6c 20 73 6c  ait until all sl
3670: 6f 77 2d 72 65 61 64 65 72 20 6c 6f 63 6b 73 20  ow-reader locks 
3680: 68 61 76 65 20 63 6c 65 61 72 65 64 2e 0a 20 20  have cleared..  
3690: 2a 2f 0a 20 20 66 6f 72 28 70 49 74 65 72 3d 70  */.  for(pIter=p
36a0: 50 67 3b 20 70 49 74 65 72 3b 20 70 49 74 65 72  Pg; pIter; pIter
36b0: 3d 70 49 74 65 72 2d 3e 70 4e 65 78 74 29 7b 0a  =pIter->pNext){.
36c0: 20 20 20 20 75 33 32 20 2a 70 53 6c 6f 74 20 3d      u32 *pSlot =
36d0: 20 26 70 44 62 2d 3e 61 53 6c 6f 74 5b 70 49 74   &pDb->aSlot[pIt
36e0: 65 72 2d 3e 70 67 6e 6f 20 25 20 48 4d 41 5f 50  er->pgno % HMA_P
36f0: 41 47 45 4c 4f 43 4b 5f 53 4c 4f 54 53 5d 3b 0a  AGELOCK_SLOTS];.
3700: 20 20 20 20 69 6e 74 20 69 48 61 73 68 20 3d 20      int iHash = 
3710: 70 49 74 65 72 2d 3e 70 67 6e 6f 20 25 20 48 4d  pIter->pgno % HM
3720: 41 5f 48 41 53 48 5f 53 49 5a 45 3b 0a 20 20 20  A_HASH_SIZE;.   
3730: 20 70 49 74 65 72 2d 3e 69 43 6f 6d 6d 69 74 49   pIter->iCommitI
3740: 64 20 3d 20 70 2d 3e 69 43 6f 6d 6d 69 74 49 64  d = p->iCommitId
3750: 3b 0a 20 20 20 20 70 49 74 65 72 2d 3e 70 48 61  ;.    pIter->pHa
3760: 73 68 4e 65 78 74 20 3d 20 70 44 62 2d 3e 61 70  shNext = pDb->ap
3770: 50 67 5b 69 48 61 73 68 5d 3b 0a 20 20 20 20 69  Pg[iHash];.    i
3780: 66 28 20 70 49 74 65 72 2d 3e 70 48 61 73 68 4e  f( pIter->pHashN
3790: 65 78 74 20 29 7b 0a 20 20 20 20 20 20 70 49 74  ext ){.      pIt
37a0: 65 72 2d 3e 70 48 61 73 68 4e 65 78 74 2d 3e 70  er->pHashNext->p
37b0: 48 61 73 68 50 72 65 76 20 3d 20 70 49 74 65 72  HashPrev = pIter
37c0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 44 62 2d  ;.    }.    pDb-
37d0: 3e 61 70 50 67 5b 69 48 61 73 68 5d 20 3d 20 70  >apPg[iHash] = p
37e0: 49 74 65 72 3b 0a 0a 20 20 20 20 2f 2a 20 54 4f  Iter;..    /* TO
37f0: 44 4f 3a 20 53 6f 6d 65 74 68 69 6e 67 20 62 65  DO: Something be
3800: 74 74 65 72 20 74 68 61 6e 20 74 68 69 73 21 20  tter than this! 
3810: 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 73 6c  */.    while( sl
3820: 6f 74 47 65 74 53 6c 6f 77 52 65 61 64 65 72 73  otGetSlowReaders
3830: 28 2a 70 53 6c 6f 74 29 3e 30 20 29 7b 0a 20 20  (*pSlot)>0 ){.  
3840: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
3850: 78 5f 6c 65 61 76 65 28 70 44 62 2d 3e 6d 75 74  x_leave(pDb->mut
3860: 65 78 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  ex);.      sqlit
3870: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70  e3_mutex_enter(p
3880: 44 62 2d 3e 6d 75 74 65 78 29 3b 0a 20 20 20 20  Db->mutex);.    
3890: 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 70 49 74  }..    /* If pIt
38a0: 65 72 20 69 73 20 74 68 65 20 6c 61 73 74 20 65  er is the last e
38b0: 6c 65 6d 65 6e 74 20 69 6e 20 74 68 65 20 6c 69  lement in the li
38c0: 73 74 2c 20 61 70 70 65 6e 64 20 74 68 65 20 6e  st, append the n
38d0: 65 77 20 6c 69 73 74 20 74 6f 0a 20 20 20 20 2a  ew list to.    *
38e0: 2a 20 74 68 65 20 53 65 72 76 65 72 44 62 2e 70  * the ServerDb.p
38f0: 50 67 46 69 72 73 74 2f 70 50 67 4c 61 73 74 20  PgFirst/pPgLast 
3900: 6c 69 73 74 20 61 74 20 74 68 69 73 20 70 6f 69  list at this poi
3910: 6e 74 2e 20 20 2a 2f 0a 20 20 20 20 69 66 28 20  nt.  */.    if( 
3920: 70 49 74 65 72 2d 3e 70 4e 65 78 74 3d 3d 30 20  pIter->pNext==0 
3930: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 44 62  ){.      if( pDb
3940: 2d 3e 70 50 67 4c 61 73 74 20 29 7b 0a 20 20 20  ->pPgLast ){.   
3950: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 44 62       assert( pDb
3960: 2d 3e 70 50 67 46 69 72 73 74 20 29 3b 0a 20 20  ->pPgFirst );.  
3970: 20 20 20 20 20 20 70 44 62 2d 3e 70 50 67 4c 61        pDb->pPgLa
3980: 73 74 2d 3e 70 4e 65 78 74 20 3d 20 70 50 67 3b  st->pNext = pPg;
3990: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
39a0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 44        assert( pD
39b0: 62 2d 3e 70 50 67 46 69 72 73 74 3d 3d 30 20 29  b->pPgFirst==0 )
39c0: 3b 0a 20 20 20 20 20 20 20 20 70 44 62 2d 3e 70  ;.        pDb->p
39d0: 50 67 46 69 72 73 74 20 3d 20 70 50 67 3b 0a 20  PgFirst = pPg;. 
39e0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 44 62       }.      pDb
39f0: 2d 3e 70 50 67 4c 61 73 74 20 3d 20 70 49 74 65  ->pPgLast = pIte
3a00: 72 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  r;.    }.  }..  
3a10: 2f 2a 20 41 64 64 20 74 68 69 73 20 63 6f 6e 6e  /* Add this conn
3a20: 65 63 74 69 6f 6e 20 74 6f 20 74 68 65 20 6c 69  ection to the li
3a30: 73 74 20 6f 66 20 63 75 72 72 65 6e 74 20 63 6f  st of current co
3a40: 6d 6d 69 74 74 65 72 73 20 2a 2f 0a 20 20 61 73  mmitters */.  as
3a50: 73 65 72 74 28 20 70 2d 3e 70 4e 65 78 74 3d 3d  sert( p->pNext==
3a60: 30 20 29 3b 0a 20 20 70 2d 3e 70 4e 65 78 74 20  0 );.  p->pNext 
3a70: 3d 20 70 44 62 2d 3e 70 43 6f 6d 6d 69 74 3b 0a  = pDb->pCommit;.
3a80: 20 20 70 44 62 2d 3e 70 43 6f 6d 6d 69 74 20 3d    pDb->pCommit =
3a90: 20 70 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d   p;..  sqlite3_m
3aa0: 75 74 65 78 5f 6c 65 61 76 65 28 70 44 62 2d 3e  utex_leave(pDb->
3ab0: 6d 75 74 65 78 29 3b 0a 20 20 72 65 74 75 72 6e  mutex);.  return
3ac0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
3ad0: 6c 65 61 73 65 20 61 6c 6c 20 77 72 69 74 65 2d  lease all write-
3ae0: 6c 6f 63 6b 73 2e 0a 2a 2f 0a 69 6e 74 20 73 71  locks..*/.int sq
3af0: 6c 69 74 65 33 53 65 72 76 65 72 52 65 6c 65 61  lite3ServerRelea
3b00: 73 65 57 72 69 74 65 4c 6f 63 6b 73 28 53 65 72  seWriteLocks(Ser
3b10: 76 65 72 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72  ver *p){.  int r
3b20: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
3b30: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
3b40: 2a 0a 2a 2a 20 4c 6f 63 6b 20 70 61 67 65 20 70  *.** Lock page p
3b50: 67 6e 6f 20 66 6f 72 20 72 65 61 64 69 6e 67 20  gno for reading 
3b60: 28 62 57 72 69 74 65 3d 3d 30 29 20 6f 72 20 77  (bWrite==0) or w
3b70: 72 69 74 69 6e 67 20 28 62 57 72 69 74 65 3d 3d  riting (bWrite==
3b80: 31 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 61 72  1)..**.** If par
3b90: 61 6d 65 74 65 72 20 62 42 6c 6f 63 6b 20 69 73  ameter bBlock is
3ba0: 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20   non-zero, then 
3bb0: 6d 61 6b 65 20 74 68 69 73 20 61 20 62 6c 6f 63  make this a bloc
3bc0: 6b 69 6e 67 20 6c 6f 63 6b 20 69 66 0a 2a 2a 20  king lock if.** 
3bd0: 70 6f 73 73 69 62 6c 65 2e 0a 2a 2f 0a 69 6e 74  possible..*/.int
3be0: 20 73 71 6c 69 74 65 33 53 65 72 76 65 72 4c 6f   sqlite3ServerLo
3bf0: 63 6b 28 53 65 72 76 65 72 20 2a 70 2c 20 50 67  ck(Server *p, Pg
3c00: 6e 6f 20 70 67 6e 6f 2c 20 69 6e 74 20 62 57 72  no pgno, int bWr
3c10: 69 74 65 2c 20 69 6e 74 20 62 42 6c 6f 63 6b 29  ite, int bBlock)
3c20: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
3c30: 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 73 73 65 72  ITE_OK;..  asser
3c40: 74 28 20 70 2d 3e 65 54 72 61 6e 73 3d 3d 53 45  t( p->eTrans==SE
3c50: 52 56 45 52 5f 54 52 41 4e 53 5f 52 45 41 44 57  RVER_TRANS_READW
3c60: 52 49 54 45 20 0a 20 20 20 20 20 20 20 7c 7c 20  RITE .       || 
3c70: 70 2d 3e 65 54 72 61 6e 73 3d 3d 53 45 52 56 45  p->eTrans==SERVE
3c80: 52 5f 54 52 41 4e 53 5f 52 45 41 44 4f 4e 4c 59  R_TRANS_READONLY
3c90: 20 0a 20 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e   .  );.  if( p->
3ca0: 65 54 72 61 6e 73 3d 3d 53 45 52 56 45 52 5f 54  eTrans==SERVER_T
3cb0: 52 41 4e 53 5f 52 45 41 44 57 52 49 54 45 20 29  RANS_READWRITE )
3cc0: 7b 0a 20 20 20 20 53 65 72 76 65 72 44 62 20 2a  {.    ServerDb *
3cd0: 70 44 62 20 3d 20 70 2d 3e 70 44 62 3b 0a 20 20  pDb = p->pDb;.  
3ce0: 20 20 69 6e 74 20 69 57 72 69 74 65 72 3b 0a 20    int iWriter;. 
3cf0: 20 20 20 69 6e 74 20 62 53 6b 69 70 20 3d 20 30     int bSkip = 0
3d00: 3b 0a 20 20 20 20 75 33 32 20 2a 70 53 6c 6f 74  ;.    u32 *pSlot
3d10: 3b 0a 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ;..    assert( p
3d20: 2d 3e 69 54 72 61 6e 73 49 64 3e 3d 30 20 29 3b  ->iTransId>=0 );
3d30: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e  .    assert( p->
3d40: 6e 4c 6f 63 6b 3c 3d 70 2d 3e 6e 41 6c 6c 6f 63  nLock<=p->nAlloc
3d50: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e   );.    if( p->n
3d60: 4c 6f 63 6b 3d 3d 70 2d 3e 6e 41 6c 6c 6f 63 20  Lock==p->nAlloc 
3d70: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  ){.      int nNe
3d80: 77 20 3d 20 70 2d 3e 6e 4c 6f 63 6b 20 3f 20 70  w = p->nLock ? p
3d90: 2d 3e 6e 4c 6f 63 6b 2a 32 20 3a 20 32 35 36 3b  ->nLock*2 : 256;
3da0: 0a 20 20 20 20 20 20 75 33 32 20 2a 61 4e 65 77  .      u32 *aNew
3db0: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c   = sqlite3_reall
3dc0: 6f 63 28 70 2d 3e 61 4c 6f 63 6b 2c 20 6e 4e 65  oc(p->aLock, nNe
3dd0: 77 2a 73 69 7a 65 6f 66 28 75 33 32 29 29 3b 0a  w*sizeof(u32));.
3de0: 20 20 20 20 20 20 69 66 28 20 61 4e 65 77 3d 3d        if( aNew==
3df0: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
3e00: 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20  E_NOMEM_BKPT;.  
3e10: 20 20 20 20 6d 65 6d 73 65 74 28 26 61 4e 65 77      memset(&aNew
3e20: 5b 70 2d 3e 6e 4c 6f 63 6b 5d 2c 20 30 2c 20 73  [p->nLock], 0, s
3e30: 69 7a 65 6f 66 28 75 33 32 29 20 2a 20 28 6e 4e  izeof(u32) * (nN
3e40: 65 77 20 2d 20 70 2d 3e 6e 4c 6f 63 6b 29 29 3b  ew - p->nLock));
3e50: 0a 20 20 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63  .      p->nAlloc
3e60: 20 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 70   = nNew;.      p
3e70: 2d 3e 61 4c 6f 63 6b 20 3d 20 61 4e 65 77 3b 0a  ->aLock = aNew;.
3e80: 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74      }..    sqlit
3e90: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70  e3_mutex_enter(p
3ea0: 44 62 2d 3e 6d 75 74 65 78 29 3b 0a 0a 20 20 20  Db->mutex);..   
3eb0: 20 70 53 6c 6f 74 20 3d 20 26 70 44 62 2d 3e 61   pSlot = &pDb->a
3ec0: 53 6c 6f 74 5b 70 67 6e 6f 20 25 20 48 4d 41 5f  Slot[pgno % HMA_
3ed0: 50 41 47 45 4c 4f 43 4b 5f 53 4c 4f 54 53 5d 3b  PAGELOCK_SLOTS];
3ee0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 73 6c 6f  .    assert( slo
3ef0: 74 47 65 74 57 72 69 74 65 72 28 2a 70 53 6c 6f  tGetWriter(*pSlo
3f00: 74 29 3c 30 20 0a 20 20 20 20 20 20 20 20 7c 7c  t)<0 .        ||
3f10: 20 73 6c 6f 74 52 65 61 64 65 72 4d 61 73 6b 28   slotReaderMask(
3f20: 2a 70 53 6c 6f 74 29 3d 3d 30 20 0a 20 20 20 20  *pSlot)==0 .    
3f30: 20 20 20 20 7c 7c 20 73 6c 6f 74 52 65 61 64 65      || slotReade
3f40: 72 4d 61 73 6b 28 2a 70 53 6c 6f 74 29 3d 3d 28  rMask(*pSlot)==(
3f50: 31 20 3c 3c 20 73 6c 6f 74 47 65 74 57 72 69 74  1 << slotGetWrit
3f60: 65 72 28 2a 70 53 6c 6f 74 29 29 0a 20 20 20 20  er(*pSlot)).    
3f70: 20 20 20 20 29 3b 0a 0a 20 20 20 20 69 57 72 69      );..    iWri
3f80: 74 65 72 20 3d 20 73 6c 6f 74 47 65 74 57 72 69  ter = slotGetWri
3f90: 74 65 72 28 2a 70 53 6c 6f 74 29 3b 0a 20 20 20  ter(*pSlot);.   
3fa0: 20 69 66 28 20 69 57 72 69 74 65 72 3d 3d 70 2d   if( iWriter==p-
3fb0: 3e 69 54 72 61 6e 73 49 64 20 7c 7c 20 28 62 57  >iTransId || (bW
3fc0: 72 69 74 65 3d 3d 30 20 26 26 20 28 2a 70 53 6c  rite==0 && (*pSl
3fd0: 6f 74 20 26 20 28 31 3c 3c 70 2d 3e 69 54 72 61  ot & (1<<p->iTra
3fe0: 6e 73 49 64 29 29 29 20 29 7b 0a 20 20 20 20 20  nsId))) ){.     
3ff0: 20 62 53 6b 69 70 20 3d 20 31 3b 0a 20 20 20 20   bSkip = 1;.    
4000: 7d 65 6c 73 65 20 69 66 28 20 69 57 72 69 74 65  }else if( iWrite
4010: 72 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63  r>=0 ){.      rc
4020: 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 5f 44   = SQLITE_BUSY_D
4030: 45 41 44 4c 4f 43 4b 3b 0a 20 20 20 20 7d 65 6c  EADLOCK;.    }el
4040: 73 65 20 69 66 28 20 62 57 72 69 74 65 20 29 7b  se if( bWrite ){
4050: 0a 20 20 20 20 20 20 69 66 28 20 28 73 6c 6f 74  .      if( (slot
4060: 52 65 61 64 65 72 4d 61 73 6b 28 2a 70 53 6c 6f  ReaderMask(*pSlo
4070: 74 29 20 26 20 7e 28 31 20 3c 3c 20 70 2d 3e 69  t) & ~(1 << p->i
4080: 54 72 61 6e 73 49 64 29 29 3d 3d 30 20 29 7b 0a  TransId))==0 ){.
4090: 20 20 20 20 20 20 20 20 2a 70 53 6c 6f 74 20 2b          *pSlot +
40a0: 3d 20 28 28 70 2d 3e 69 54 72 61 6e 73 49 64 20  = ((p->iTransId 
40b0: 2b 20 31 29 20 3c 3c 20 48 4d 41 5f 4d 41 58 5f  + 1) << HMA_MAX_
40c0: 54 52 41 4e 53 41 43 54 49 4f 4e 49 44 29 3b 0a  TRANSACTIONID);.
40d0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
40e0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
40f0: 5f 42 55 53 59 5f 44 45 41 44 4c 4f 43 4b 3b 0a  _BUSY_DEADLOCK;.
4100: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
4110: 65 7b 0a 20 20 20 20 20 20 2a 70 53 6c 6f 74 20  e{.      *pSlot 
4120: 7c 3d 20 28 31 20 3c 3c 20 70 2d 3e 69 54 72 61  |= (1 << p->iTra
4130: 6e 73 49 64 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  nsId);.    }..  
4140: 20 20 61 73 73 65 72 74 28 20 73 6c 6f 74 47 65    assert( slotGe
4150: 74 57 72 69 74 65 72 28 2a 70 53 6c 6f 74 29 3c  tWriter(*pSlot)<
4160: 30 20 0a 20 20 20 20 20 20 20 20 7c 7c 20 73 6c  0 .        || sl
4170: 6f 74 52 65 61 64 65 72 4d 61 73 6b 28 2a 70 53  otReaderMask(*pS
4180: 6c 6f 74 29 3d 3d 30 20 0a 20 20 20 20 20 20 20  lot)==0 .       
4190: 20 7c 7c 20 73 6c 6f 74 52 65 61 64 65 72 4d 61   || slotReaderMa
41a0: 73 6b 28 2a 70 53 6c 6f 74 29 3d 3d 28 31 20 3c  sk(*pSlot)==(1 <
41b0: 3c 20 73 6c 6f 74 47 65 74 57 72 69 74 65 72 28  < slotGetWriter(
41c0: 2a 70 53 6c 6f 74 29 29 0a 20 20 20 20 20 20 20  *pSlot)).       
41d0: 20 29 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33   );..    sqlite3
41e0: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 44 62  _mutex_leave(pDb
41f0: 2d 3e 6d 75 74 65 78 29 3b 0a 0a 20 20 20 20 69  ->mutex);..    i
4200: 66 28 20 62 53 6b 69 70 3d 3d 30 20 29 7b 0a 20  f( bSkip==0 ){. 
4210: 20 20 20 20 20 70 2d 3e 61 4c 6f 63 6b 5b 70 2d       p->aLock[p-
4220: 3e 6e 4c 6f 63 6b 2b 2b 5d 20 3d 20 70 67 6e 6f  >nLock++] = pgno
4230: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
4240: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74  eturn rc;.}..int
4250: 20 73 71 6c 69 74 65 33 53 65 72 76 65 72 48 61   sqlite3ServerHa
4260: 73 4c 6f 63 6b 28 53 65 72 76 65 72 20 2a 70 2c  sLock(Server *p,
4270: 20 50 67 6e 6f 20 70 67 6e 6f 2c 20 69 6e 74 20   Pgno pgno, int 
4280: 62 57 72 69 74 65 29 7b 0a 20 20 61 73 73 65 72  bWrite){.  asser
4290: 74 28 20 30 20 29 3b 0a 20 20 72 65 74 75 72 6e  t( 0 );.  return
42a0: 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f   0;.}..static vo
42b0: 69 64 20 73 65 72 76 65 72 49 6e 63 72 53 6c 6f  id serverIncrSlo
42c0: 77 52 65 61 64 65 72 28 75 33 32 20 2a 70 53 6c  wReader(u32 *pSl
42d0: 6f 74 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 61 73  ot, int n){.  as
42e0: 73 65 72 74 28 20 6e 3d 3d 31 20 7c 7c 20 6e 3d  sert( n==1 || n=
42f0: 3d 2d 31 20 29 3b 0a 20 20 2a 70 53 6c 6f 74 20  =-1 );.  *pSlot 
4300: 2b 3d 20 28 6e 20 2a 20 28 31 20 3c 3c 20 48 4d  += (n * (1 << HM
4310: 41 5f 53 4c 4f 54 5f 52 4c 57 4c 5f 42 49 54 53  A_SLOT_RLWL_BITS
4320: 29 29 3b 0a 7d 0a 0a 76 6f 69 64 20 73 71 6c 69  ));.}..void sqli
4330: 74 65 33 53 65 72 76 65 72 52 65 61 64 50 61 67  te3ServerReadPag
4340: 65 28 53 65 72 76 65 72 20 2a 70 2c 20 50 67 6e  e(Server *p, Pgn
4350: 6f 20 70 67 6e 6f 2c 20 75 38 20 2a 2a 70 70 44  o pgno, u8 **ppD
4360: 61 74 61 29 7b 0a 20 20 69 66 28 20 70 2d 3e 65  ata){.  if( p->e
4370: 54 72 61 6e 73 3d 3d 53 45 52 56 45 52 5f 54 52  Trans==SERVER_TR
4380: 41 4e 53 5f 52 45 41 44 4f 4e 4c 59 20 29 7b 0a  ANS_READONLY ){.
4390: 20 20 20 20 53 65 72 76 65 72 44 62 20 2a 70 44      ServerDb *pD
43a0: 62 20 3d 20 70 2d 3e 70 44 62 3b 0a 20 20 20 20  b = p->pDb;.    
43b0: 53 65 72 76 65 72 50 61 67 65 20 2a 70 49 74 65  ServerPage *pIte
43c0: 72 3b 0a 20 20 20 20 53 65 72 76 65 72 50 61 67  r;.    ServerPag
43d0: 65 20 2a 70 42 65 73 74 20 3d 20 30 3b 0a 20 20  e *pBest = 0;.  
43e0: 20 20 69 6e 74 20 69 48 61 73 68 20 3d 20 70 67    int iHash = pg
43f0: 6e 6f 20 25 20 48 4d 41 5f 48 41 53 48 5f 53 49  no % HMA_HASH_SI
4400: 5a 45 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33  ZE;..    sqlite3
4410: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 44 62  _mutex_enter(pDb
4420: 2d 3e 6d 75 74 65 78 29 3b 0a 0a 20 20 20 20 2f  ->mutex);..    /
4430: 2a 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73  * Search the has
4440: 68 20 74 61 62 6c 65 20 66 6f 72 20 74 68 65 20  h table for the 
4450: 6f 6c 64 65 73 74 20 76 65 72 73 69 6f 6e 20 6f  oldest version o
4460: 66 20 70 61 67 65 20 70 67 6e 6f 20 77 69 74 68  f page pgno with
4470: 0a 20 20 20 20 2a 2a 20 61 20 63 6f 6d 6d 69 74  .    ** a commit
4480: 2d 69 64 20 67 72 65 61 74 65 72 20 74 68 61 6e  -id greater than
4490: 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 53 65 72   or equal to Ser
44a0: 76 65 72 2e 69 43 6f 6d 6d 69 74 49 64 2e 20 20  ver.iCommitId.  
44b0: 2a 2f 0a 20 20 20 20 66 6f 72 28 70 49 74 65 72  */.    for(pIter
44c0: 3d 70 44 62 2d 3e 61 70 50 67 5b 69 48 61 73 68  =pDb->apPg[iHash
44d0: 5d 3b 20 70 49 74 65 72 3b 20 70 49 74 65 72 3d  ]; pIter; pIter=
44e0: 70 49 74 65 72 2d 3e 70 48 61 73 68 4e 65 78 74  pIter->pHashNext
44f0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 49 74  ){.      if( pIt
4500: 65 72 2d 3e 70 67 6e 6f 3d 3d 70 67 6e 6f 20 0a  er->pgno==pgno .
4510: 20 20 20 20 20 20 20 26 26 20 70 49 74 65 72 2d         && pIter-
4520: 3e 69 43 6f 6d 6d 69 74 49 64 3e 3d 70 2d 3e 69  >iCommitId>=p->i
4530: 43 6f 6d 6d 69 74 49 64 20 0a 20 20 20 20 20 20  CommitId .      
4540: 20 26 26 20 28 70 42 65 73 74 3d 3d 30 20 7c 7c   && (pBest==0 ||
4550: 20 70 49 74 65 72 2d 3e 69 43 6f 6d 6d 69 74 49   pIter->iCommitI
4560: 64 3c 70 42 65 73 74 2d 3e 69 43 6f 6d 6d 69 74  d<pBest->iCommit
4570: 49 64 29 20 0a 20 20 20 20 20 20 29 7b 0a 20 20  Id) .      ){.  
4580: 20 20 20 20 20 20 70 42 65 73 74 20 3d 20 70 49        pBest = pI
4590: 74 65 72 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ter;.      }.   
45a0: 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 42 65 73   }..    if( pBes
45b0: 74 20 29 7b 0a 20 20 20 20 20 20 2a 70 70 44 61  t ){.      *ppDa
45c0: 74 61 20 3d 20 70 42 65 73 74 2d 3e 61 44 61 74  ta = pBest->aDat
45d0: 61 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  a;.    }else{.  
45e0: 20 20 20 20 75 33 32 20 2a 70 53 6c 6f 74 20 3d      u32 *pSlot =
45f0: 20 26 70 44 62 2d 3e 61 53 6c 6f 74 5b 70 67 6e   &pDb->aSlot[pgn
4600: 6f 20 25 20 48 4d 41 5f 50 41 47 45 4c 4f 43 4b  o % HMA_PAGELOCK
4610: 5f 53 4c 4f 54 53 5d 3b 0a 20 20 20 20 20 20 73  _SLOTS];.      s
4620: 65 72 76 65 72 49 6e 63 72 53 6c 6f 77 52 65 61  erverIncrSlowRea
4630: 64 65 72 28 70 53 6c 6f 74 2c 20 31 29 3b 0a 20  der(pSlot, 1);. 
4640: 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65     }..    sqlite
4650: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 44  3_mutex_leave(pD
4660: 62 2d 3e 6d 75 74 65 78 29 3b 0a 20 20 7d 0a 7d  b->mutex);.  }.}
4670: 0a 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 53 65  ..void sqlite3Se
4680: 72 76 65 72 45 6e 64 52 65 61 64 50 61 67 65 28  rverEndReadPage(
4690: 53 65 72 76 65 72 20 2a 70 2c 20 50 67 6e 6f 20  Server *p, Pgno 
46a0: 70 67 6e 6f 29 7b 0a 20 20 69 66 28 20 70 2d 3e  pgno){.  if( p->
46b0: 65 54 72 61 6e 73 3d 3d 53 45 52 56 45 52 5f 54  eTrans==SERVER_T
46c0: 52 41 4e 53 5f 52 45 41 44 4f 4e 4c 59 20 29 7b  RANS_READONLY ){
46d0: 0a 20 20 20 20 53 65 72 76 65 72 44 62 20 2a 70  .    ServerDb *p
46e0: 44 62 20 3d 20 70 2d 3e 70 44 62 3b 0a 20 20 20  Db = p->pDb;.   
46f0: 20 75 33 32 20 2a 70 53 6c 6f 74 20 3d 20 26 70   u32 *pSlot = &p
4700: 44 62 2d 3e 61 53 6c 6f 74 5b 70 67 6e 6f 20 25  Db->aSlot[pgno %
4710: 20 48 4d 41 5f 50 41 47 45 4c 4f 43 4b 5f 53 4c   HMA_PAGELOCK_SL
4720: 4f 54 53 5d 3b 0a 20 20 20 20 73 71 6c 69 74 65  OTS];.    sqlite
4730: 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 44  3_mutex_enter(pD
4740: 62 2d 3e 6d 75 74 65 78 29 3b 0a 20 20 20 20 73  b->mutex);.    s
4750: 65 72 76 65 72 49 6e 63 72 53 6c 6f 77 52 65 61  erverIncrSlowRea
4760: 64 65 72 28 70 53 6c 6f 74 2c 20 2d 31 29 3b 0a  der(pSlot, -1);.
4770: 20 20 20 20 61 73 73 65 72 74 28 20 73 6c 6f 74      assert( slot
4780: 47 65 74 53 6c 6f 77 52 65 61 64 65 72 73 28 2a  GetSlowReaders(*
4790: 70 53 6c 6f 74 29 3e 3d 30 20 29 3b 0a 20 20 20  pSlot)>=0 );.   
47a0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
47b0: 65 61 76 65 28 70 44 62 2d 3e 6d 75 74 65 78 29  eave(pDb->mutex)
47c0: 3b 0a 20 20 7d 0a 7d 0a 0a 23 65 6e 64 69 66 20  ;.  }.}..#endif 
47d0: 2f 2a 20 69 66 64 65 66 20 53 51 4c 49 54 45 5f  /* ifdef SQLITE_
47e0: 53 45 52 56 45 52 5f 45 44 49 54 49 4f 4e 20 2a  SERVER_EDITION *
47f0: 2f 0a                                            /.