/ Hex Artifact Content
Login

Artifact 143a16259e3b6786e2fcc0c3321b1c495e5d4a9ac57761581a99b20d6565a619:


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 2f  "sqliteInt.h"../
0190: 2a 0a 2a 2a 20 48 4d 41 20 66 69 6c 65 20 6c 61  *.** HMA file la
01a0: 79 6f 75 74 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  yout:.**.**     
01b0: 20 34 20 62 79 74 65 73 20 2d 20 44 4d 53 20 73   4 bytes - DMS s
01c0: 6c 6f 74 2e 20 41 6c 6c 20 63 6f 6e 6e 65 63 74  lot. All connect
01d0: 69 6f 6e 73 20 72 65 61 64 2d 6c 6f 63 6b 20 74  ions read-lock t
01e0: 68 69 73 20 73 6c 6f 74 2e 0a 2a 2a 0a 2a 2a 20  his slot..**.** 
01f0: 20 20 31 36 2a 34 20 62 79 74 65 73 20 2d 20 6c    16*4 bytes - l
0200: 6f 63 6b 69 6e 67 20 73 6c 6f 74 73 2e 20 43 6f  ocking slots. Co
0210: 6e 6e 65 63 74 69 6f 6e 73 20 68 6f 6c 64 20 61  nnections hold a
0220: 20 72 65 61 64 2d 6c 6f 63 6b 20 6f 6e 20 61 20   read-lock on a 
0230: 6c 6f 63 6b 69 6e 67 20 73 6c 6f 74 0a 2a 2a 20  locking slot.** 
0240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 77                 w
0250: 68 65 6e 20 74 68 65 79 20 61 72 65 20 63 6f 6e  hen they are con
0260: 6e 65 63 74 65 64 2c 20 61 20 77 72 69 74 65 20  nected, a write 
0270: 6c 6f 63 6b 20 77 68 65 6e 20 74 68 65 79 20 68  lock when they h
0280: 61 76 65 20 61 6e 20 6f 70 65 6e 0a 2a 2a 20 20  ave an open.**  
0290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 72                tr
02a0: 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a  ansaction..**.**
02b0: 20 20 20 20 4e 2a 34 20 62 79 74 65 73 20 2d 20      N*4 bytes - 
02c0: 50 61 67 65 20 6c 6f 63 6b 69 6e 67 20 73 6c 6f  Page locking slo
02d0: 74 73 2e 20 4e 20 69 73 20 48 4d 41 5f 50 41 47  ts. N is HMA_PAG
02e0: 45 4c 4f 43 4b 5f 53 4c 4f 54 53 2e 0a 2a 2a 0a  ELOCK_SLOTS..**.
02f0: 2a 2a 20 50 61 67 65 20 6c 6f 63 6b 20 73 6c 6f  ** Page lock slo
0300: 74 20 66 6f 72 6d 61 74 3a 0a 2a 2a 0a 2a 2a 20  t format:.**.** 
0310: 20 20 20 4c 65 61 73 74 20 73 69 67 6e 69 66 69     Least signifi
0320: 63 61 6e 74 20 48 4d 41 5f 43 4c 49 45 4e 54 5f  cant HMA_CLIENT_
0330: 53 4c 4f 54 53 20 75 73 65 64 20 66 6f 72 20 72  SLOTS used for r
0340: 65 61 64 2d 6c 6f 63 6b 73 2e 20 49 66 20 62 69  ead-locks. If bi
0350: 74 20 30 20 69 73 20 73 65 74 2c 0a 2a 2a 20 20  t 0 is set,.**  
0360: 20 20 63 6c 69 65 6e 74 20 30 20 68 6f 6c 64 73    client 0 holds
0370: 20 61 20 72 65 61 64 2d 6c 6f 63 6b 2e 0a 2a 2a   a read-lock..**
0380: 0a 2a 2a 20 20 20 20 49 66 20 28 76 29 20 69 73  .**    If (v) is
0390: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68   the value of th
03a0: 65 20 6c 6f 63 6b 69 6e 67 20 73 6c 6f 74 20 61  e locking slot a
03b0: 6e 64 20 28 76 3e 3e 48 4d 41 5f 43 4c 49 45 4e  nd (v>>HMA_CLIEN
03c0: 54 5f 53 4c 4f 54 53 29 20 69 73 0a 2a 2a 20 20  T_SLOTS) is.**  
03d0: 20 20 6e 6f 74 20 7a 65 72 6f 2c 20 74 68 65 6e    not zero, then
03e0: 20 74 68 65 20 77 72 69 74 65 2d 6c 6f 63 6b 20   the write-lock 
03f0: 68 6f 6c 64 65 72 20 69 73 20 63 6c 69 65 6e 74  holder is client
0400: 20 28 28 76 3e 3e 48 4d 41 5f 43 4c 49 45 4e 54   ((v>>HMA_CLIENT
0410: 5f 53 4c 4f 54 53 29 2d 31 29 2e 0a 2a 2a 0a 2a  _SLOTS)-1)..**.*
0420: 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  /..#ifdef SQLITE
0430: 5f 53 45 52 56 45 52 5f 45 44 49 54 49 4f 4e 0a  _SERVER_EDITION.
0440: 0a 23 64 65 66 69 6e 65 20 48 4d 41 5f 43 4c 49  .#define HMA_CLI
0450: 45 4e 54 5f 53 4c 4f 54 53 20 20 20 31 36 0a 23  ENT_SLOTS   16.#
0460: 64 65 66 69 6e 65 20 48 4d 41 5f 50 41 47 45 4c  define HMA_PAGEL
0470: 4f 43 4b 5f 53 4c 4f 54 53 20 28 32 35 36 2a 31  OCK_SLOTS (256*1
0480: 30 32 34 29 0a 0a 23 64 65 66 69 6e 65 20 48 4d  024)..#define HM
0490: 41 5f 46 49 4c 45 5f 53 49 5a 45 20 28 34 20 2b  A_FILE_SIZE (4 +
04a0: 20 34 2a 48 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c   4*HMA_CLIENT_SL
04b0: 4f 54 53 20 2b 20 34 2a 48 4d 41 5f 50 41 47 45  OTS + 4*HMA_PAGE
04c0: 4c 4f 43 4b 5f 53 4c 4f 54 53 29 0a 0a 23 69 6e  LOCK_SLOTS)..#in
04d0: 63 6c 75 64 65 20 22 75 6e 69 73 74 64 2e 68 22  clude "unistd.h"
04e0: 0a 23 69 6e 63 6c 75 64 65 20 22 66 63 6e 74 6c  .#include "fcntl
04f0: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 73 79  .h".#include "sy
0500: 73 2f 6d 6d 61 6e 2e 68 22 0a 23 69 6e 63 6c 75  s/mman.h".#inclu
0510: 64 65 20 22 73 79 73 2f 74 79 70 65 73 2e 68 22  de "sys/types.h"
0520: 0a 23 69 6e 63 6c 75 64 65 20 22 73 79 73 2f 73  .#include "sys/s
0530: 74 61 74 2e 68 22 0a 0a 74 79 70 65 64 65 66 20  tat.h"..typedef 
0540: 73 74 72 75 63 74 20 53 65 72 76 65 72 48 4d 41  struct ServerHMA
0550: 20 53 65 72 76 65 72 48 4d 41 3b 0a 0a 73 74 72   ServerHMA;..str
0560: 75 63 74 20 53 65 72 76 65 72 47 6c 6f 62 61 6c  uct ServerGlobal
0570: 20 7b 0a 20 20 53 65 72 76 65 72 48 4d 41 20 2a   {.  ServerHMA *
0580: 70 48 6d 61 3b 20 20 20 20 20 20 20 20 20 20 20  pHma;           
0590: 20 20 20 20 20 2f 2a 20 4c 69 6e 6b 65 64 20 6c       /* Linked l
05a0: 69 73 74 20 6f 66 20 61 6c 6c 20 53 65 72 76 65  ist of all Serve
05b0: 72 48 4d 41 20 6f 62 6a 65 63 74 73 20 2a 2f 0a  rHMA objects */.
05c0: 7d 3b 0a 73 74 61 74 69 63 20 73 74 72 75 63 74  };.static struct
05d0: 20 53 65 72 76 65 72 47 6c 6f 62 61 6c 20 67 5f   ServerGlobal g_
05e0: 73 65 72 76 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20 54  server;../*.** T
05f0: 68 65 72 65 20 69 73 20 6f 6e 65 20 69 6e 73 74  here is one inst
0600: 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ance of the foll
0610: 6f 77 69 6e 67 20 73 74 72 75 63 74 75 72 65 20  owing structure 
0620: 66 6f 72 20 65 61 63 68 20 64 69 73 74 69 6e 63  for each distinc
0630: 74 20 0a 2a 2a 20 48 4d 41 20 66 69 6c 65 20 6f  t .** HMA file o
0640: 70 65 6e 65 64 20 62 79 20 63 6c 69 65 6e 74 73  pened by clients
0650: 20 77 69 74 68 69 6e 20 74 68 69 73 20 70 72 6f   within this pro
0660: 63 65 73 73 2e 20 0a 2a 2f 0a 73 74 72 75 63 74  cess. .*/.struct
0670: 20 53 65 72 76 65 72 48 4d 41 20 7b 0a 20 20 63   ServerHMA {.  c
0680: 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20  har *zName;     
0690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06a0: 20 20 20 20 2f 2a 20 68 6d 61 20 66 69 6c 65 20      /* hma file 
06b0: 70 61 74 68 20 2a 2f 0a 20 20 69 6e 74 20 66 64  path */.  int fd
06c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
06d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
06e0: 2a 20 46 64 20 6f 70 65 6e 20 6f 6e 20 68 6d 61  * Fd open on hma
06f0: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e   file */.  int n
0700: 43 6c 69 65 6e 74 3b 20 20 20 20 20 20 20 20 20  Client;         
0710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0720: 2f 2a 20 43 75 72 72 65 6e 74 20 6e 75 6d 62 65  /* Current numbe
0730: 72 20 6f 66 20 63 6c 69 65 6e 74 73 20 2a 2f 0a  r of clients */.
0740: 20 20 53 65 72 76 65 72 20 2a 61 43 6c 69 65 6e    Server *aClien
0750: 74 5b 48 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c 4f  t[HMA_CLIENT_SLO
0760: 54 53 5d 3b 20 20 20 2f 2a 20 4c 6f 63 61 6c 20  TS];   /* Local 
0770: 28 74 68 69 73 20 70 72 6f 63 65 73 73 29 20 63  (this process) c
0780: 6c 69 65 6e 74 73 20 2a 2f 0a 20 20 75 33 32 20  lients */.  u32 
0790: 2a 61 4d 61 70 3b 20 20 20 20 20 20 20 20 20 20  *aMap;          
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07b0: 20 2f 2a 20 4d 4d 61 70 70 65 64 20 68 6d 61 20   /* MMapped hma 
07c0: 66 69 6c 65 20 2a 2f 0a 20 20 53 65 72 76 65 72  file */.  Server
07d0: 48 4d 41 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  HMA *pNext;     
07e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
07f0: 2a 20 4e 65 78 74 20 48 4d 41 20 69 6e 20 74 68  * Next HMA in th
0800: 69 73 20 70 72 6f 63 65 73 73 20 2a 2f 0a 0a 20  is process */.. 
0810: 20 64 65 76 5f 74 20 73 74 5f 64 65 76 3b 0a 20   dev_t st_dev;. 
0820: 20 69 6e 6f 5f 74 20 73 74 5f 69 6e 6f 3b 0a 7d   ino_t st_ino;.}
0830: 3b 0a 0a 73 74 72 75 63 74 20 53 65 72 76 65 72  ;..struct Server
0840: 20 7b 0a 20 20 53 65 72 76 65 72 48 4d 41 20 2a   {.  ServerHMA *
0850: 70 48 6d 61 3b 20 20 20 20 20 20 20 20 20 20 20  pHma;           
0860: 20 20 20 20 20 2f 2a 20 48 6d 61 20 66 69 6c 65       /* Hma file
0870: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74   object */.  int
0880: 20 69 43 6c 69 65 6e 74 3b 20 20 20 20 20 20 20   iClient;       
0890: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
08a0: 43 6c 69 65 6e 74 20 69 64 20 2a 2f 0a 20 20 50  Client id */.  P
08b0: 61 67 65 72 20 2a 70 50 61 67 65 72 3b 20 20 20  ager *pPager;   
08c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
08d0: 2a 20 41 73 73 6f 63 69 61 74 65 64 20 70 61 67  * Associated pag
08e0: 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 0a 20 20  er object */..  
08f0: 69 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20 20 20 20  int nAlloc;     
0900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0910: 2f 2a 20 41 6c 6c 6f 63 61 74 65 64 20 73 69 7a  /* Allocated siz
0920: 65 20 6f 66 20 61 4c 6f 63 6b 5b 5d 20 61 72 72  e of aLock[] arr
0930: 61 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 6f 63  ay */.  int nLoc
0940: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
0950: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
0960: 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20  r of entries in 
0970: 61 4c 6f 63 6b 5b 5d 20 2a 2f 0a 20 20 75 33 32  aLock[] */.  u32
0980: 20 2a 61 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20   *aLock;        
0990: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
09a0: 4d 61 70 70 65 64 20 6c 6f 63 6b 20 66 69 6c 65  Mapped lock file
09b0: 20 2a 2f 0a 7d 3b 0a 0a 23 64 65 66 69 6e 65 20   */.};..#define 
09c0: 53 45 52 56 45 52 5f 57 52 49 54 45 5f 4c 4f 43  SERVER_WRITE_LOC
09d0: 4b 20 33 0a 23 64 65 66 69 6e 65 20 53 45 52 56  K 3.#define SERV
09e0: 45 52 5f 52 45 41 44 5f 4c 4f 43 4b 20 20 32 0a  ER_READ_LOCK  2.
09f0: 23 64 65 66 69 6e 65 20 53 45 52 56 45 52 5f 4e  #define SERVER_N
0a00: 4f 5f 4c 4f 43 4b 20 20 20 20 31 0a 0a 2f 2a 0a  O_LOCK    1../*.
0a10: 2a 2a 20 47 6c 6f 62 61 6c 20 6d 75 74 65 78 20  ** Global mutex 
0a20: 66 75 6e 63 74 69 6f 6e 73 20 75 73 65 64 20 62  functions used b
0a30: 79 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66  y code in this f
0a40: 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ile..*/.static v
0a50: 6f 69 64 20 73 65 72 76 65 72 45 6e 74 65 72 4d  oid serverEnterM
0a60: 75 74 65 78 28 76 6f 69 64 29 7b 0a 20 20 73 71  utex(void){.  sq
0a70: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
0a80: 72 28 73 71 6c 69 74 65 33 4d 75 74 65 78 41 6c  r(sqlite3MutexAl
0a90: 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58  loc(SQLITE_MUTEX
0aa0: 5f 53 54 41 54 49 43 5f 41 50 50 31 29 29 3b 0a  _STATIC_APP1));.
0ab0: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 65  }.static void se
0ac0: 72 76 65 72 4c 65 61 76 65 4d 75 74 65 78 28 76  rverLeaveMutex(v
0ad0: 6f 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  oid){.  sqlite3_
0ae0: 6d 75 74 65 78 5f 6c 65 61 76 65 28 73 71 6c 69  mutex_leave(sqli
0af0: 74 65 33 4d 75 74 65 78 41 6c 6c 6f 63 28 53 51  te3MutexAlloc(SQ
0b00: 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49  LITE_MUTEX_STATI
0b10: 43 5f 41 50 50 31 29 29 3b 0a 7d 0a 73 74 61 74  C_APP1));.}.stat
0b20: 69 63 20 76 6f 69 64 20 73 65 72 76 65 72 41 73  ic void serverAs
0b30: 73 65 72 74 4d 75 74 65 78 48 65 6c 64 28 76 6f  sertMutexHeld(vo
0b40: 69 64 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73  id){.  assert( s
0b50: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
0b60: 64 28 73 71 6c 69 74 65 33 4d 75 74 65 78 41 6c  d(sqlite3MutexAl
0b70: 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58  loc(SQLITE_MUTEX
0b80: 5f 53 54 41 54 49 43 5f 41 50 50 31 29 29 20 29  _STATIC_APP1)) )
0b90: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
0ba0: 70 6f 73 69 78 4c 6f 63 6b 28 69 6e 74 20 66 64  posixLock(int fd
0bb0: 2c 20 69 6e 74 20 69 53 6c 6f 74 2c 20 69 6e 74  , int iSlot, int
0bc0: 20 65 4c 6f 63 6b 2c 20 69 6e 74 20 62 42 6c 6f   eLock, int bBlo
0bd0: 63 6b 29 7b 0a 20 20 69 6e 74 20 72 65 73 3b 0a  ck){.  int res;.
0be0: 20 20 73 74 72 75 63 74 20 66 6c 6f 63 6b 20 6c    struct flock l
0bf0: 3b 0a 20 20 73 68 6f 72 74 20 61 54 79 70 65 5b  ;.  short aType[
0c00: 34 5d 20 3d 20 7b 30 2c 20 46 5f 55 4e 4c 43 4b  4] = {0, F_UNLCK
0c10: 2c 20 46 5f 52 44 4c 43 4b 2c 20 46 5f 57 52 4c  , F_RDLCK, F_WRL
0c20: 43 4b 7d 3b 0a 20 20 61 73 73 65 72 74 28 20 65  CK};.  assert( e
0c30: 4c 6f 63 6b 3d 3d 53 45 52 56 45 52 5f 57 52 49  Lock==SERVER_WRI
0c40: 54 45 5f 4c 4f 43 4b 20 0a 20 20 20 20 20 20 20  TE_LOCK .       
0c50: 7c 7c 20 65 4c 6f 63 6b 3d 3d 53 45 52 56 45 52  || eLock==SERVER
0c60: 5f 52 45 41 44 5f 4c 4f 43 4b 20 0a 20 20 20 20  _READ_LOCK .    
0c70: 20 20 20 7c 7c 20 65 4c 6f 63 6b 3d 3d 53 45 52     || eLock==SER
0c80: 56 45 52 5f 4e 4f 5f 4c 4f 43 4b 20 0a 20 20 29  VER_NO_LOCK .  )
0c90: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 6c 2c 20 30  ;.  memset(&l, 0
0ca0: 2c 20 73 69 7a 65 6f 66 28 6c 29 29 3b 0a 20 20  , sizeof(l));.  
0cb0: 6c 2e 6c 5f 74 79 70 65 20 3d 20 61 54 79 70 65  l.l_type = aType
0cc0: 5b 65 4c 6f 63 6b 5d 3b 0a 20 20 6c 2e 6c 5f 77  [eLock];.  l.l_w
0cd0: 68 65 6e 63 65 20 3d 20 53 45 45 4b 5f 53 45 54  hence = SEEK_SET
0ce0: 3b 0a 20 20 6c 2e 6c 5f 73 74 61 72 74 20 3d 20  ;.  l.l_start = 
0cf0: 69 53 6c 6f 74 2a 73 69 7a 65 6f 66 28 75 33 32  iSlot*sizeof(u32
0d00: 29 3b 0a 20 20 6c 2e 6c 5f 6c 65 6e 20 3d 20 31  );.  l.l_len = 1
0d10: 3b 0a 0a 20 20 72 65 73 20 3d 20 66 63 6e 74 6c  ;..  res = fcntl
0d20: 28 66 64 2c 20 28 62 42 6c 6f 63 6b 20 3f 20 46  (fd, (bBlock ? F
0d30: 5f 53 45 54 4c 4b 57 20 3a 20 46 5f 53 45 54 4c  _SETLKW : F_SETL
0d40: 4b 29 2c 20 26 6c 29 3b 0a 20 20 72 65 74 75 72  K), &l);.  retur
0d50: 6e 20 28 72 65 73 3d 3d 30 20 3f 20 53 51 4c 49  n (res==0 ? SQLI
0d60: 54 45 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f 42  TE_OK : SQLITE_B
0d70: 55 53 59 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  USY);.}..static 
0d80: 69 6e 74 20 73 65 72 76 65 72 4d 61 70 46 69 6c  int serverMapFil
0d90: 65 28 53 65 72 76 65 72 48 4d 41 20 2a 70 29 7b  e(ServerHMA *p){
0da0: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 4d  .  assert( p->aM
0db0: 61 70 3d 3d 30 20 29 3b 0a 20 20 70 2d 3e 61 4d  ap==0 );.  p->aM
0dc0: 61 70 20 3d 20 6d 6d 61 70 28 30 2c 20 48 4d 41  ap = mmap(0, HMA
0dd0: 5f 46 49 4c 45 5f 53 49 5a 45 2c 20 50 52 4f 54  _FILE_SIZE, PROT
0de0: 5f 52 45 41 44 7c 50 52 4f 54 5f 57 52 49 54 45  _READ|PROT_WRITE
0df0: 2c 20 4d 41 50 5f 53 48 41 52 45 44 2c 20 70 2d  , MAP_SHARED, p-
0e00: 3e 66 64 2c 20 30 29 3b 0a 20 20 69 66 28 20 70  >fd, 0);.  if( p
0e10: 2d 3e 61 4d 61 70 3d 3d 30 20 29 7b 0a 20 20 20  ->aMap==0 ){.   
0e20: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
0e30: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75  RROR;.  }.  retu
0e40: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
0e50: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 65  ..static void se
0e60: 72 76 65 72 44 65 63 72 48 6d 61 52 65 66 63 6f  rverDecrHmaRefco
0e70: 75 6e 74 28 53 65 72 76 65 72 48 4d 41 20 2a 70  unt(ServerHMA *p
0e80: 48 6d 61 29 7b 0a 20 20 69 66 28 20 70 48 6d 61  Hma){.  if( pHma
0e90: 20 29 7b 0a 20 20 20 20 70 48 6d 61 2d 3e 6e 43   ){.    pHma->nC
0ea0: 6c 69 65 6e 74 2d 2d 3b 0a 20 20 20 20 69 66 28  lient--;.    if(
0eb0: 20 70 48 6d 61 2d 3e 6e 43 6c 69 65 6e 74 3c 3d   pHma->nClient<=
0ec0: 30 20 29 7b 0a 20 20 20 20 20 20 53 65 72 76 65  0 ){.      Serve
0ed0: 72 48 4d 41 20 2a 2a 70 70 3b 0a 20 20 20 20 20  rHMA **pp;.     
0ee0: 20 69 66 28 20 70 48 6d 61 2d 3e 61 4d 61 70 20   if( pHma->aMap 
0ef0: 29 20 6d 75 6e 6d 61 70 28 70 48 6d 61 2d 3e 61  ) munmap(pHma->a
0f00: 4d 61 70 2c 20 48 4d 41 5f 46 49 4c 45 5f 53 49  Map, HMA_FILE_SI
0f10: 5a 45 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  ZE);.      if( p
0f20: 48 6d 61 2d 3e 66 64 3e 3d 30 20 29 20 63 6c 6f  Hma->fd>=0 ) clo
0f30: 73 65 28 70 48 6d 61 2d 3e 66 64 29 3b 0a 20 20  se(pHma->fd);.  
0f40: 20 20 20 20 66 6f 72 28 70 70 3d 26 67 5f 73 65      for(pp=&g_se
0f50: 72 76 65 72 2e 70 48 6d 61 3b 20 2a 70 70 21 3d  rver.pHma; *pp!=
0f60: 70 48 6d 61 3b 20 70 70 3d 26 28 2a 70 70 29 2d  pHma; pp=&(*pp)-
0f70: 3e 70 4e 65 78 74 29 3b 0a 20 20 20 20 20 20 2a  >pNext);.      *
0f80: 70 70 20 3d 20 70 48 6d 61 2d 3e 70 4e 65 78 74  pp = pHma->pNext
0f90: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
0fa0: 66 72 65 65 28 70 48 6d 61 29 3b 0a 20 20 20 20  free(pHma);.    
0fb0: 7d 0a 20 20 7d 0a 7d 0a 0a 0a 73 74 61 74 69 63  }.  }.}...static
0fc0: 20 69 6e 74 20 73 65 72 76 65 72 4f 70 65 6e 48   int serverOpenH
0fd0: 6d 61 28 50 61 67 65 72 20 2a 70 50 61 67 65 72  ma(Pager *pPager
0fe0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50  , const char *zP
0ff0: 61 74 68 2c 20 53 65 72 76 65 72 48 4d 41 20 2a  ath, ServerHMA *
1000: 2a 70 70 48 6d 61 29 7b 0a 20 20 73 74 72 75 63  *ppHma){.  struc
1010: 74 20 73 74 61 74 20 73 53 74 61 74 3b 20 20 20  t stat sStat;   
1020: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
1030: 72 75 63 74 75 72 65 20 70 6f 70 75 6c 61 74 65  ructure populate
1040: 64 20 62 79 20 73 74 61 74 28 29 20 2a 2f 0a 20  d by stat() */. 
1050: 20 69 6e 74 20 72 65 73 3b 20 20 20 20 20 20 20   int res;       
1060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1070: 20 2f 2a 20 72 65 73 75 6c 74 20 6f 66 20 73 74   /* result of st
1080: 61 74 28 29 20 2a 2f 0a 20 20 69 6e 74 20 72 63  at() */.  int rc
1090: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
10a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
10b0: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 53 65  urn code */.  Se
10c0: 72 76 65 72 48 4d 41 20 2a 70 48 6d 61 20 3d 20  rverHMA *pHma = 
10d0: 30 3b 0a 0a 20 20 73 65 72 76 65 72 41 73 73 65  0;..  serverAsse
10e0: 72 74 4d 75 74 65 78 48 65 6c 64 28 29 3b 0a 0a  rtMutexHeld();..
10f0: 20 20 72 65 73 20 3d 20 73 74 61 74 28 7a 50 61    res = stat(zPa
1100: 74 68 2c 20 26 73 53 74 61 74 29 3b 0a 20 20 69  th, &sStat);.  i
1110: 66 28 20 72 65 73 21 3d 30 20 29 7b 0a 20 20 20  f( res!=0 ){.   
1120: 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 53 51 4c   sqlite3_log(SQL
1130: 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2c 20 22 46  ITE_CANTOPEN, "F
1140: 61 69 6c 65 64 20 74 6f 20 73 74 61 74 28 25 73  ailed to stat(%s
1150: 29 22 2c 20 7a 50 61 74 68 29 3b 0a 20 20 20 20  )", zPath);.    
1160: 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f  rc = SQLITE_ERRO
1170: 52 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  R;.  }else{.    
1180: 66 6f 72 28 70 48 6d 61 3d 67 5f 73 65 72 76 65  for(pHma=g_serve
1190: 72 2e 70 48 6d 61 3b 20 70 48 6d 61 3b 20 70 48  r.pHma; pHma; pH
11a0: 6d 61 3d 70 48 6d 61 2d 3e 70 4e 65 78 74 29 7b  ma=pHma->pNext){
11b0: 0a 20 20 20 20 20 20 69 66 28 20 73 53 74 61 74  .      if( sStat
11c0: 2e 73 74 5f 64 65 76 3d 3d 70 48 6d 61 2d 3e 73  .st_dev==pHma->s
11d0: 74 5f 64 65 76 20 26 26 20 73 53 74 61 74 2e 73  t_dev && sStat.s
11e0: 74 5f 69 6e 6f 3d 3d 70 48 6d 61 2d 3e 73 74 5f  t_ino==pHma->st_
11f0: 69 6e 6f 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ino ) break;.   
1200: 20 7d 0a 20 20 20 20 69 66 28 20 70 48 6d 61 3d   }.    if( pHma=
1210: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  =0 ){.      int 
1220: 6e 50 61 74 68 20 3d 20 73 74 72 6c 65 6e 28 7a  nPath = strlen(z
1230: 50 61 74 68 29 3b 0a 20 20 20 20 20 20 69 6e 74  Path);.      int
1240: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
1250: 53 65 72 76 65 72 48 4d 41 29 20 2b 20 6e 50 61  ServerHMA) + nPa
1260: 74 68 2b 31 20 2b 20 34 3b 0a 0a 20 20 20 20 20  th+1 + 4;..     
1270: 20 70 48 6d 61 20 3d 20 28 53 65 72 76 65 72 48   pHma = (ServerH
1280: 4d 41 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  MA*)sqlite3_mall
1290: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 20  oc(nByte);.     
12a0: 20 69 66 28 20 70 48 6d 61 3d 3d 30 20 29 7b 0a   if( pHma==0 ){.
12b0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
12c0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
12d0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
12e0: 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 20 20 6d  int i;.        m
12f0: 65 6d 73 65 74 28 70 48 6d 61 2c 20 30 2c 20 6e  emset(pHma, 0, n
1300: 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 70  Byte);.        p
1310: 48 6d 61 2d 3e 7a 4e 61 6d 65 20 3d 20 28 63 68  Hma->zName = (ch
1320: 61 72 2a 29 26 70 48 6d 61 5b 31 5d 3b 0a 20 20  ar*)&pHma[1];.  
1330: 20 20 20 20 20 20 70 48 6d 61 2d 3e 6e 43 6c 69        pHma->nCli
1340: 65 6e 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  ent = 1;.       
1350: 20 70 48 6d 61 2d 3e 73 74 5f 64 65 76 20 3d 20   pHma->st_dev = 
1360: 73 53 74 61 74 2e 73 74 5f 64 65 76 3b 0a 20 20  sStat.st_dev;.  
1370: 20 20 20 20 20 20 70 48 6d 61 2d 3e 73 74 5f 69        pHma->st_i
1380: 6e 6f 20 3d 20 73 53 74 61 74 2e 73 74 5f 69 6e  no = sStat.st_in
1390: 6f 3b 0a 20 20 20 20 20 20 20 20 70 48 6d 61 2d  o;.        pHma-
13a0: 3e 70 4e 65 78 74 20 3d 20 67 5f 73 65 72 76 65  >pNext = g_serve
13b0: 72 2e 70 48 6d 61 3b 0a 20 20 20 20 20 20 20 20  r.pHma;.        
13c0: 67 5f 73 65 72 76 65 72 2e 70 48 6d 61 20 3d 20  g_server.pHma = 
13d0: 70 48 6d 61 3b 0a 0a 20 20 20 20 20 20 20 20 6d  pHma;..        m
13e0: 65 6d 63 70 79 28 70 48 6d 61 2d 3e 7a 4e 61 6d  emcpy(pHma->zNam
13f0: 65 2c 20 7a 50 61 74 68 2c 20 6e 50 61 74 68 29  e, zPath, nPath)
1400: 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79  ;.        memcpy
1410: 28 26 70 48 6d 61 2d 3e 7a 4e 61 6d 65 5b 6e 50  (&pHma->zName[nP
1420: 61 74 68 5d 2c 20 22 2d 68 6d 61 22 2c 20 35 29  ath], "-hma", 5)
1430: 3b 0a 0a 20 20 20 20 20 20 20 20 70 48 6d 61 2d  ;..        pHma-
1440: 3e 66 64 20 3d 20 6f 70 65 6e 28 70 48 6d 61 2d  >fd = open(pHma-
1450: 3e 7a 4e 61 6d 65 2c 20 4f 5f 52 44 57 52 7c 4f  >zName, O_RDWR|O
1460: 5f 43 52 45 41 54 2c 20 30 36 34 34 29 3b 0a 20  _CREAT, 0644);. 
1470: 20 20 20 20 20 20 20 69 66 28 20 70 48 6d 61 2d         if( pHma-
1480: 3e 66 64 3c 30 20 29 7b 0a 20 20 20 20 20 20 20  >fd<0 ){.       
1490: 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 53     sqlite3_log(S
14a0: 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2c 20  QLITE_CANTOPEN, 
14b0: 22 46 61 69 6c 65 64 20 74 6f 20 6f 70 65 6e 28  "Failed to open(
14c0: 25 73 29 22 2c 20 70 48 6d 61 2d 3e 7a 4e 61 6d  %s)", pHma->zNam
14d0: 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  e);.          rc
14e0: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
14f0: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
1500: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
1510: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
1520: 20 20 20 2f 2a 20 57 72 69 74 65 2d 6c 6f 63 6b     /* Write-lock
1530: 20 74 68 65 20 44 4d 53 20 73 6c 6f 74 2e 20 49   the DMS slot. I
1540: 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 69 6e  f successful, in
1550: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 68 6d 61  itialize the hma
1560: 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 20 20   file. */.      
1570: 20 20 20 20 72 63 20 3d 20 70 6f 73 69 78 4c 6f      rc = posixLo
1580: 63 6b 28 70 48 6d 61 2d 3e 66 64 2c 20 30 2c 20  ck(pHma->fd, 0, 
1590: 53 45 52 56 45 52 5f 57 52 49 54 45 5f 4c 4f 43  SERVER_WRITE_LOC
15a0: 4b 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 20  K, 0);.         
15b0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
15c0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OK ){.          
15d0: 20 20 72 65 73 20 3d 20 66 74 72 75 6e 63 61 74    res = ftruncat
15e0: 65 28 70 48 6d 61 2d 3e 66 64 2c 20 48 4d 41 5f  e(pHma->fd, HMA_
15f0: 46 49 4c 45 5f 53 49 5a 45 29 3b 0a 20 20 20 20  FILE_SIZE);.    
1600: 20 20 20 20 20 20 20 20 69 66 28 20 72 65 73 21          if( res!
1610: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
1620: 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28      sqlite3_log(
1630: 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2c  SQLITE_CANTOPEN,
1640: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
1650: 20 20 20 20 22 46 61 69 6c 65 64 20 74 6f 20 66      "Failed to f
1660: 74 72 75 6e 63 61 74 65 28 25 73 29 22 2c 20 70  truncate(%s)", p
1670: 48 6d 61 2d 3e 7a 4e 61 6d 65 0a 20 20 20 20 20  Hma->zName.     
1680: 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20           );.    
1690: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53            rc = S
16a0: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
16b0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
16c0: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
16d0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
16e0: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
16f0: 65 72 76 65 72 4d 61 70 46 69 6c 65 28 70 48 6d  erverMapFile(pHm
1700: 61 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  a);.            
1710: 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  }.            if
1720: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1730: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ){.             
1740: 20 6d 65 6d 73 65 74 28 70 48 6d 61 2d 3e 61 4d   memset(pHma->aM
1750: 61 70 2c 20 30 2c 20 48 4d 41 5f 46 49 4c 45 5f  ap, 0, HMA_FILE_
1760: 53 49 5a 45 29 3b 0a 20 20 20 20 20 20 20 20 20  SIZE);.         
1770: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
1780: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
1790: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  ITE_ERROR;.     
17a0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
17b0: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63       for(i=0; rc
17c0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
17d0: 3c 48 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c 4f 54  <HMA_CLIENT_SLOT
17e0: 53 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  S; i++){.       
17f0: 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
1800: 74 65 33 50 61 67 65 72 52 6f 6c 6c 62 61 63 6b  te3PagerRollback
1810: 4a 6f 75 72 6e 61 6c 28 70 50 61 67 65 72 2c 20  Journal(pPager, 
1820: 69 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  i);.            
1830: 7d 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73  }.          }els
1840: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  e{.            r
1850: 63 20 3d 20 73 65 72 76 65 72 4d 61 70 46 69 6c  c = serverMapFil
1860: 65 28 70 48 6d 61 29 3b 0a 20 20 20 20 20 20 20  e(pHma);.       
1870: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69     }.          i
1880: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
1890: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
18a0: 72 63 20 3d 20 70 6f 73 69 78 4c 6f 63 6b 28 70  rc = posixLock(p
18b0: 48 6d 61 2d 3e 66 64 2c 20 30 2c 20 53 45 52 56  Hma->fd, 0, SERV
18c0: 45 52 5f 52 45 41 44 5f 4c 4f 43 4b 2c 20 31 29  ER_READ_LOCK, 1)
18d0: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
18e0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
18f0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
1900: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OK ){.          
1910: 73 65 72 76 65 72 44 65 63 72 48 6d 61 52 65 66  serverDecrHmaRef
1920: 63 6f 75 6e 74 28 70 48 6d 61 29 3b 0a 20 20 20  count(pHma);.   
1930: 20 20 20 20 20 20 20 70 48 6d 61 20 3d 20 30 3b         pHma = 0;
1940: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
1950: 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20   }.    }else{.  
1960: 20 20 20 20 70 48 6d 61 2d 3e 6e 43 6c 69 65 6e      pHma->nClien
1970: 74 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  t++;.    }.  }..
1980: 20 20 2a 70 70 48 6d 61 20 3d 20 70 48 6d 61 3b    *ppHma = pHma;
1990: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
19a0: 0a 73 74 61 74 69 63 20 75 33 32 20 2a 73 65 72  .static u32 *ser
19b0: 76 65 72 50 61 67 65 4c 6f 63 6b 53 6c 6f 74 28  verPageLockSlot(
19c0: 53 65 72 76 65 72 20 2a 70 2c 20 50 67 6e 6f 20  Server *p, Pgno 
19d0: 70 67 6e 6f 29 7b 0a 20 20 69 6e 74 20 69 53 6c  pgno){.  int iSl
19e0: 6f 74 20 3d 20 70 67 6e 6f 20 25 20 48 4d 41 5f  ot = pgno % HMA_
19f0: 50 41 47 45 4c 4f 43 4b 5f 53 4c 4f 54 53 3b 0a  PAGELOCK_SLOTS;.
1a00: 20 20 72 65 74 75 72 6e 20 26 70 2d 3e 70 48 6d    return &p->pHm
1a10: 61 2d 3e 61 4d 61 70 5b 31 20 2b 20 48 4d 41 5f  a->aMap[1 + HMA_
1a20: 43 4c 49 45 4e 54 5f 53 4c 4f 54 53 20 2b 20 69  CLIENT_SLOTS + i
1a30: 53 6c 6f 74 5d 3b 0a 7d 0a 73 74 61 74 69 63 20  Slot];.}.static 
1a40: 75 33 32 20 2a 73 65 72 76 65 72 43 6c 69 65 6e  u32 *serverClien
1a50: 74 53 6c 6f 74 28 53 65 72 76 65 72 20 2a 70 2c  tSlot(Server *p,
1a60: 20 69 6e 74 20 69 43 6c 69 65 6e 74 29 7b 0a 20   int iClient){. 
1a70: 20 72 65 74 75 72 6e 20 26 70 2d 3e 70 48 6d 61   return &p->pHma
1a80: 2d 3e 61 4d 61 70 5b 31 20 2b 20 69 43 6c 69 65  ->aMap[1 + iClie
1a90: 6e 74 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c  nt];.}../*.** Cl
1aa0: 6f 73 65 20 74 68 65 20 22 63 6f 6e 6e 65 63 74  ose the "connect
1ab0: 69 6f 6e 22 20 61 6e 64 20 2a 2d 68 6d 61 20 66  ion" and *-hma f
1ac0: 69 6c 65 2e 20 54 68 69 73 20 64 65 6c 65 74 65  ile. This delete
1ad0: 73 20 74 68 65 20 6f 62 6a 65 63 74 20 70 61 73  s the object pas
1ae0: 73 65 64 0a 2a 2a 20 61 73 20 74 68 65 20 66 69  sed.** as the fi
1af0: 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f  rst argument..*/
1b00: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 53 65 72  .void sqlite3Ser
1b10: 76 65 72 44 69 73 63 6f 6e 6e 65 63 74 28 53 65  verDisconnect(Se
1b20: 72 76 65 72 20 2a 70 2c 20 73 71 6c 69 74 65 33  rver *p, sqlite3
1b30: 5f 66 69 6c 65 20 2a 64 62 66 64 29 7b 0a 20 20  _file *dbfd){.  
1b40: 69 66 28 20 70 2d 3e 70 48 6d 61 20 29 7b 0a 20  if( p->pHma ){. 
1b50: 20 20 20 53 65 72 76 65 72 48 4d 41 20 2a 70 48     ServerHMA *pH
1b60: 6d 61 20 3d 20 70 2d 3e 70 48 6d 61 3b 0a 20 20  ma = p->pHma;.  
1b70: 20 20 73 65 72 76 65 72 45 6e 74 65 72 4d 75 74    serverEnterMut
1b80: 65 78 28 29 3b 0a 20 20 20 20 69 66 28 20 70 2d  ex();.    if( p-
1b90: 3e 69 43 6c 69 65 6e 74 3e 3d 30 20 29 7b 0a 20  >iClient>=0 ){. 
1ba0: 20 20 20 20 20 75 33 32 20 2a 70 53 6c 6f 74 20       u32 *pSlot 
1bb0: 3d 20 73 65 72 76 65 72 43 6c 69 65 6e 74 53 6c  = serverClientSl
1bc0: 6f 74 28 70 2c 20 70 2d 3e 69 43 6c 69 65 6e 74  ot(p, p->iClient
1bd0: 29 3b 0a 20 20 20 20 20 20 2a 70 53 6c 6f 74 20  );.      *pSlot 
1be0: 3d 20 30 3b 0a 20 20 20 20 20 20 61 73 73 65 72  = 0;.      asser
1bf0: 74 28 20 70 48 6d 61 2d 3e 61 43 6c 69 65 6e 74  t( pHma->aClient
1c00: 5b 70 2d 3e 69 43 6c 69 65 6e 74 5d 3d 3d 70 20  [p->iClient]==p 
1c10: 29 3b 0a 20 20 20 20 20 20 70 48 6d 61 2d 3e 61  );.      pHma->a
1c20: 43 6c 69 65 6e 74 5b 70 2d 3e 69 43 6c 69 65 6e  Client[p->iClien
1c30: 74 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 6f  t] = 0;.      po
1c40: 73 69 78 4c 6f 63 6b 28 70 48 6d 61 2d 3e 66 64  sixLock(pHma->fd
1c50: 2c 20 70 2d 3e 69 43 6c 69 65 6e 74 2b 31 2c 20  , p->iClient+1, 
1c60: 53 45 52 56 45 52 5f 4e 4f 5f 4c 4f 43 4b 2c 20  SERVER_NO_LOCK, 
1c70: 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  0);.    }.    if
1c80: 28 20 64 62 66 64 20 0a 20 20 20 20 20 26 26 20  ( dbfd .     && 
1c90: 70 48 6d 61 2d 3e 6e 43 6c 69 65 6e 74 3d 3d 31  pHma->nClient==1
1ca0: 20 0a 20 20 20 20 20 26 26 20 53 51 4c 49 54 45   .     && SQLITE
1cb0: 5f 4f 4b 3d 3d 73 71 6c 69 74 65 33 4f 73 4c 6f  _OK==sqlite3OsLo
1cc0: 63 6b 28 64 62 66 64 2c 20 53 51 4c 49 54 45 5f  ck(dbfd, SQLITE_
1cd0: 4c 4f 43 4b 5f 45 58 43 4c 55 53 49 56 45 29 0a  LOCK_EXCLUSIVE).
1ce0: 20 20 20 20 29 7b 0a 20 20 20 20 20 20 75 6e 6c      ){.      unl
1cf0: 69 6e 6b 28 70 48 6d 61 2d 3e 7a 4e 61 6d 65 29  ink(pHma->zName)
1d00: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 65 72 76  ;.    }.    serv
1d10: 65 72 44 65 63 72 48 6d 61 52 65 66 63 6f 75 6e  erDecrHmaRefcoun
1d20: 74 28 70 48 6d 61 29 3b 0a 20 20 20 20 73 65 72  t(pHma);.    ser
1d30: 76 65 72 4c 65 61 76 65 4d 75 74 65 78 28 29 3b  verLeaveMutex();
1d40: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66  .  }.  sqlite3_f
1d50: 72 65 65 28 70 2d 3e 61 4c 6f 63 6b 29 3b 0a 20  ree(p->aLock);. 
1d60: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
1d70: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
1d80: 73 65 72 76 65 72 52 6f 6c 6c 62 61 63 6b 43 6c  serverRollbackCl
1d90: 69 65 6e 74 28 53 65 72 76 65 72 20 2a 70 2c 20  ient(Server *p, 
1da0: 69 6e 74 20 69 42 6c 6f 63 6b 29 7b 0a 20 20 69  int iBlock){.  i
1db0: 6e 74 20 72 63 3b 0a 0a 20 20 73 71 6c 69 74 65  nt rc;..  sqlite
1dc0: 33 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 4e 4f 54  3_log(SQLITE_NOT
1dd0: 49 43 45 2c 20 22 52 6f 6c 6c 69 6e 67 20 62 61  ICE, "Rolling ba
1de0: 63 6b 20 66 61 69 6c 65 64 20 63 6c 69 65 6e 74  ck failed client
1df0: 20 25 64 22 2c 20 69 42 6c 6f 63 6b 29 3b 0a 0a   %d", iBlock);..
1e00: 20 20 2f 2a 20 52 6f 6c 6c 20 62 61 63 6b 20 61    /* Roll back a
1e10: 6e 79 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20  ny journal file 
1e20: 66 6f 72 20 63 6c 69 65 6e 74 20 69 42 6c 6f 63  for client iBloc
1e30: 6b 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  k. */.  rc = sql
1e40: 69 74 65 33 50 61 67 65 72 52 6f 6c 6c 62 61 63  ite3PagerRollbac
1e50: 6b 4a 6f 75 72 6e 61 6c 28 70 2d 3e 70 50 61 67  kJournal(p->pPag
1e60: 65 72 2c 20 69 42 6c 6f 63 6b 29 3b 0a 0a 20 20  er, iBlock);..  
1e70: 2f 2a 20 43 6c 65 61 72 20 61 6e 79 20 6c 6f 63  /* Clear any loc
1e80: 6b 73 20 68 65 6c 64 20 62 79 20 63 6c 69 65 6e  ks held by clien
1e90: 74 20 69 42 6c 6f 63 6b 20 66 72 6f 6d 20 74 68  t iBlock from th
1ea0: 65 20 48 4d 41 20 66 69 6c 65 2e 20 20 2a 2f 0a  e HMA file.  */.
1eb0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1ec0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  _OK ){.    int i
1ed0: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
1ee0: 3c 48 4d 41 5f 50 41 47 45 4c 4f 43 4b 5f 53 4c  <HMA_PAGELOCK_SL
1ef0: 4f 54 53 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  OTS; i++){.     
1f00: 20 75 33 32 20 2a 70 53 6c 6f 74 20 3d 20 73 65   u32 *pSlot = se
1f10: 72 76 65 72 50 61 67 65 4c 6f 63 6b 53 6c 6f 74  rverPageLockSlot
1f20: 28 70 2c 20 28 50 67 6e 6f 29 69 29 3b 0a 20 20  (p, (Pgno)i);.  
1f30: 20 20 20 20 75 33 32 20 76 20 3d 20 2a 70 53 6c      u32 v = *pSl
1f40: 6f 74 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28  ot;.      while(
1f50: 20 31 20 29 7b 0a 20 20 20 20 20 20 20 20 75 33   1 ){.        u3
1f60: 32 20 6e 20 3d 20 76 20 26 20 7e 28 31 20 3c 3c  2 n = v & ~(1 <<
1f70: 20 69 42 6c 6f 63 6b 29 3b 0a 20 20 20 20 20 20   iBlock);.      
1f80: 20 20 69 66 28 20 28 76 3e 3e 48 4d 41 5f 43 4c    if( (v>>HMA_CL
1f90: 49 45 4e 54 5f 53 4c 4f 54 53 29 3d 3d 69 42 6c  IENT_SLOTS)==iBl
1fa0: 6f 63 6b 2b 31 20 29 7b 0a 20 20 20 20 20 20 20  ock+1 ){.       
1fb0: 20 20 20 6e 20 3d 20 6e 20 26 20 28 28 31 3c 3c     n = n & ((1<<
1fc0: 48 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c 4f 54 53  HMA_CLIENT_SLOTS
1fd0: 29 2d 31 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  )-1);.        }.
1fe0: 20 20 20 20 20 20 20 20 69 66 28 20 5f 5f 73 79          if( __sy
1ff0: 6e 63 5f 76 61 6c 5f 63 6f 6d 70 61 72 65 5f 61  nc_val_compare_a
2000: 6e 64 5f 73 77 61 70 28 70 53 6c 6f 74 2c 20 76  nd_swap(pSlot, v
2010: 2c 20 6e 29 3d 3d 76 20 29 20 62 72 65 61 6b 3b  , n)==v ) break;
2020: 0a 20 20 20 20 20 20 20 20 76 20 3d 20 2a 70 53  .        v = *pS
2030: 6c 6f 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  lot;.      }.   
2040: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
2050: 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4f   rc;.}.../*.** O
2060: 70 65 6e 20 74 68 65 20 2a 2d 68 6d 61 20 66 69  pen the *-hma fi
2070: 6c 65 20 61 6e 64 20 22 63 6f 6e 6e 65 63 74 22  le and "connect"
2080: 20 74 6f 20 74 68 65 20 73 79 73 74 65 6d 2e 0a   to the system..
2090: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 53 65  */.int sqlite3Se
20a0: 72 76 65 72 43 6f 6e 6e 65 63 74 28 0a 20 20 50  rverConnect(.  P
20b0: 61 67 65 72 20 2a 70 50 61 67 65 72 2c 20 0a 20  ager *pPager, . 
20c0: 20 53 65 72 76 65 72 20 2a 2a 70 70 4f 75 74 2c   Server **ppOut,
20d0: 20 0a 20 20 69 6e 74 20 2a 70 69 43 6c 69 65 6e   .  int *piClien
20e0: 74 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  t.){.  const cha
20f0: 72 20 2a 7a 50 61 74 68 20 3d 20 73 71 6c 69 74  r *zPath = sqlit
2100: 65 33 50 61 67 65 72 46 69 6c 65 6e 61 6d 65 28  e3PagerFilename(
2110: 70 50 61 67 65 72 2c 20 30 29 3b 0a 20 20 69 6e  pPager, 0);.  in
2120: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
2130: 3b 0a 20 20 53 65 72 76 65 72 20 2a 70 3b 0a 0a  ;.  Server *p;..
2140: 20 20 70 20 3d 20 28 53 65 72 76 65 72 2a 29 73    p = (Server*)s
2150: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
2160: 7a 65 6f 66 28 53 65 72 76 65 72 29 29 3b 0a 20  zeof(Server));. 
2170: 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20   if( p==0 ){.   
2180: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
2190: 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  EM;.  }else{.   
21a0: 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69   memset(p, 0, si
21b0: 7a 65 6f 66 28 53 65 72 76 65 72 29 29 3b 0a 20  zeof(Server));. 
21c0: 20 20 20 70 2d 3e 69 43 6c 69 65 6e 74 20 3d 20     p->iClient = 
21d0: 2d 31 3b 0a 20 20 20 20 70 2d 3e 70 50 61 67 65  -1;.    p->pPage
21e0: 72 20 3d 20 70 50 61 67 65 72 3b 0a 0a 20 20 20  r = pPager;..   
21f0: 20 73 65 72 76 65 72 45 6e 74 65 72 4d 75 74 65   serverEnterMute
2200: 78 28 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 65  x();.    rc = se
2210: 72 76 65 72 4f 70 65 6e 48 6d 61 28 70 50 61 67  rverOpenHma(pPag
2220: 65 72 2c 20 7a 50 61 74 68 2c 20 26 70 2d 3e 70  er, zPath, &p->p
2230: 48 6d 61 29 3b 0a 0a 20 20 20 20 2f 2a 20 46 69  Hma);..    /* Fi
2240: 6c 65 20 69 73 20 6e 6f 77 20 6d 61 70 70 65 64  le is now mapped
2250: 2e 20 46 69 6e 64 20 61 20 66 72 65 65 20 63 6c  . Find a free cl
2260: 69 65 6e 74 20 73 6c 6f 74 2e 20 2a 2f 0a 20 20  ient slot. */.  
2270: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2280: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  _OK ){.      int
2290: 20 69 3b 0a 20 20 20 20 20 20 53 65 72 76 65 72   i;.      Server
22a0: 20 2a 2a 61 43 6c 69 65 6e 74 20 3d 20 70 2d 3e   **aClient = p->
22b0: 70 48 6d 61 2d 3e 61 43 6c 69 65 6e 74 3b 0a 20  pHma->aClient;. 
22c0: 20 20 20 20 20 69 6e 74 20 66 64 20 3d 20 70 2d       int fd = p-
22d0: 3e 70 48 6d 61 2d 3e 66 64 3b 0a 20 20 20 20 20  >pHma->fd;.     
22e0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 4d 41 5f   for(i=0; i<HMA_
22f0: 43 4c 49 45 4e 54 5f 53 4c 4f 54 53 3b 20 69 2b  CLIENT_SLOTS; i+
2300: 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  +){.        if( 
2310: 61 43 6c 69 65 6e 74 5b 69 5d 3d 3d 30 20 29 7b  aClient[i]==0 ){
2320: 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 72  .          int r
2330: 65 73 20 3d 20 70 6f 73 69 78 4c 6f 63 6b 28 66  es = posixLock(f
2340: 64 2c 20 69 2b 31 2c 20 53 45 52 56 45 52 5f 57  d, i+1, SERVER_W
2350: 52 49 54 45 5f 4c 4f 43 4b 2c 20 30 29 3b 0a 20  RITE_LOCK, 0);. 
2360: 20 20 20 20 20 20 20 20 20 69 66 28 20 72 65 73           if( res
2370: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2380: 20 20 20 20 20 20 20 20 20 20 20 75 33 32 20 2a             u32 *
2390: 70 53 6c 6f 74 20 3d 20 73 65 72 76 65 72 43 6c  pSlot = serverCl
23a0: 69 65 6e 74 53 6c 6f 74 28 70 2c 20 69 29 3b 0a  ientSlot(p, i);.
23b0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
23c0: 2a 70 53 6c 6f 74 20 29 7b 0a 20 20 20 20 20 20  *pSlot ){.      
23d0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65 72          rc = ser
23e0: 76 65 72 52 6f 6c 6c 62 61 63 6b 43 6c 69 65 6e  verRollbackClien
23f0: 74 28 70 2c 20 69 29 3b 0a 20 20 20 20 20 20 20  t(p, i);.       
2400: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
2410: 20 20 20 70 6f 73 69 78 4c 6f 63 6b 28 66 64 2c     posixLock(fd,
2420: 20 69 2b 31 2c 20 28 21 72 63 20 3f 20 53 45 52   i+1, (!rc ? SER
2430: 56 45 52 5f 52 45 41 44 5f 4c 4f 43 4b 20 3a 20  VER_READ_LOCK : 
2440: 53 45 52 56 45 52 5f 4e 4f 5f 4c 4f 43 4b 29 2c  SERVER_NO_LOCK),
2450: 20 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20   0);.           
2460: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
2470: 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20    }.        }.  
2480: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 69 66 28      }..      if(
2490: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
24a0: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 3e  {.        if( i>
24b0: 48 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c 4f 54 53  HMA_CLIENT_SLOTS
24c0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63   ){.          rc
24d0: 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a   = SQLITE_BUSY;.
24e0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
24f0: 20 20 20 20 20 20 20 20 20 75 33 32 20 2a 70 53           u32 *pS
2500: 6c 6f 74 20 3d 20 73 65 72 76 65 72 43 6c 69 65  lot = serverClie
2510: 6e 74 53 6c 6f 74 28 70 2c 20 69 29 3b 0a 20 20  ntSlot(p, i);.  
2520: 20 20 20 20 20 20 20 20 2a 70 69 43 6c 69 65 6e          *piClien
2530: 74 20 3d 20 70 2d 3e 69 43 6c 69 65 6e 74 20 3d  t = p->iClient =
2540: 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20 61 43   i;.          aC
2550: 6c 69 65 6e 74 5b 69 5d 20 3d 20 70 3b 0a 20 20  lient[i] = p;.  
2560: 20 20 20 20 20 20 20 20 2a 70 53 6c 6f 74 20 3d          *pSlot =
2570: 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   1;.        }.  
2580: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20      }.    }..   
2590: 20 73 65 72 76 65 72 4c 65 61 76 65 4d 75 74 65   serverLeaveMute
25a0: 78 28 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  x();.  }..  if( 
25b0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
25c0: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 65 72 76  .    sqlite3Serv
25d0: 65 72 44 69 73 63 6f 6e 6e 65 63 74 28 70 2c 20  erDisconnect(p, 
25e0: 30 29 3b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20  0);.    p = 0;. 
25f0: 20 7d 0a 20 20 2a 70 70 4f 75 74 20 3d 20 70 3b   }.  *ppOut = p;
2600: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
2610: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 72 76  .static int serv
2620: 65 72 4f 76 65 72 63 6f 6d 65 4c 6f 63 6b 28 53  erOvercomeLock(S
2630: 65 72 76 65 72 20 2a 70 2c 20 69 6e 74 20 62 57  erver *p, int bW
2640: 72 69 74 65 2c 20 75 33 32 20 76 2c 20 69 6e 74  rite, u32 v, int
2650: 20 2a 70 62 52 65 74 72 79 29 7b 0a 20 20 69 6e   *pbRetry){.  in
2660: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
2670: 3b 0a 20 20 69 6e 74 20 62 4c 6f 63 61 6c 20 3d  ;.  int bLocal =
2680: 20 30 3b 0a 20 20 69 6e 74 20 69 42 6c 6f 63 6b   0;.  int iBlock
2690: 20 3d 20 28 28 69 6e 74 29 28 76 3e 3e 48 4d 41   = ((int)(v>>HMA
26a0: 5f 43 4c 49 45 4e 54 5f 53 4c 4f 54 53 29 29 2d  _CLIENT_SLOTS))-
26b0: 31 3b 0a 0a 20 20 69 66 28 20 69 42 6c 6f 63 6b  1;..  if( iBlock
26c0: 3c 30 20 29 7b 0a 20 20 20 20 66 6f 72 28 69 42  <0 ){.    for(iB
26d0: 6c 6f 63 6b 3d 30 3b 20 69 42 6c 6f 63 6b 3c 48  lock=0; iBlock<H
26e0: 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c 4f 54 53 3b  MA_CLIENT_SLOTS;
26f0: 20 69 42 6c 6f 63 6b 2b 2b 29 7b 0a 20 20 20 20   iBlock++){.    
2700: 20 20 69 66 28 20 69 42 6c 6f 63 6b 21 3d 70 2d    if( iBlock!=p-
2710: 3e 69 43 6c 69 65 6e 74 20 26 26 20 28 76 20 26  >iClient && (v &
2720: 20 28 31 3c 3c 69 42 6c 6f 63 6b 29 29 20 29 20   (1<<iBlock)) ) 
2730: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
2740: 0a 20 20 61 73 73 65 72 74 28 20 69 42 6c 6f 63  .  assert( iBloc
2750: 6b 3c 48 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c 4f  k<HMA_CLIENT_SLO
2760: 54 53 20 29 3b 0a 0a 20 20 73 65 72 76 65 72 45  TS );..  serverE
2770: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 69  nterMutex();.  i
2780: 66 28 20 70 2d 3e 70 48 6d 61 2d 3e 61 43 6c 69  f( p->pHma->aCli
2790: 65 6e 74 5b 69 42 6c 6f 63 6b 5d 20 29 7b 0a 20  ent[iBlock] ){. 
27a0: 20 20 20 62 4c 6f 63 61 6c 20 3d 20 31 3b 0a 20     bLocal = 1;. 
27b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d   }else{.    rc =
27c0: 20 70 6f 73 69 78 4c 6f 63 6b 28 70 2d 3e 70 48   posixLock(p->pH
27d0: 6d 61 2d 3e 66 64 2c 20 69 42 6c 6f 63 6b 2b 31  ma->fd, iBlock+1
27e0: 2c 20 53 45 52 56 45 52 5f 57 52 49 54 45 5f 4c  , SERVER_WRITE_L
27f0: 4f 43 4b 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20  OCK, 0);.  }..  
2800: 69 66 28 20 62 4c 6f 63 61 6c 3d 3d 30 20 26 26  if( bLocal==0 &&
2810: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
2820: 7b 0a 20 20 20 20 72 63 20 3d 20 73 65 72 76 65  {.    rc = serve
2830: 72 52 6f 6c 6c 62 61 63 6b 43 6c 69 65 6e 74 28  rRollbackClient(
2840: 70 2c 20 69 42 6c 6f 63 6b 29 3b 0a 0a 20 20 20  p, iBlock);..   
2850: 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20   /* Release the 
2860: 6c 6f 63 6b 20 6f 6e 20 73 6c 6f 74 20 69 42 6c  lock on slot iBl
2870: 6f 63 6b 20 2a 2f 0a 20 20 20 20 70 6f 73 69 78  ock */.    posix
2880: 4c 6f 63 6b 28 70 2d 3e 70 48 6d 61 2d 3e 66 64  Lock(p->pHma->fd
2890: 2c 20 69 42 6c 6f 63 6b 2b 31 2c 20 53 45 52 56  , iBlock+1, SERV
28a0: 45 52 5f 4e 4f 5f 4c 4f 43 4b 2c 20 30 29 3b 0a  ER_NO_LOCK, 0);.
28b0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
28c0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2a  TE_OK ){.      *
28d0: 70 62 52 65 74 72 79 20 3d 20 31 3b 0a 20 20 20  pbRetry = 1;.   
28e0: 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
28f0: 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49  assert( rc==SQLI
2900: 54 45 5f 4f 4b 20 7c 7c 20 72 63 3d 3d 53 51 4c  TE_OK || rc==SQL
2910: 49 54 45 5f 42 55 53 59 20 29 3b 0a 20 20 20 20  ITE_BUSY );.    
2920: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
2930: 20 20 7d 0a 20 20 73 65 72 76 65 72 4c 65 61 76    }.  serverLeav
2940: 65 4d 75 74 65 78 28 29 3b 0a 0a 20 20 72 65 74  eMutex();..  ret
2950: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
2960: 20 42 65 67 69 6e 20 61 20 74 72 61 6e 73 61 63   Begin a transac
2970: 74 69 6f 6e 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  tion..*/.int sql
2980: 69 74 65 33 53 65 72 76 65 72 42 65 67 69 6e 28  ite3ServerBegin(
2990: 53 65 72 76 65 72 20 2a 70 29 7b 0a 23 69 66 20  Server *p){.#if 
29a0: 30 0a 20 20 72 65 74 75 72 6e 20 70 6f 73 69 78  0.  return posix
29b0: 4c 6f 63 6b 28 70 2d 3e 70 48 6d 61 2d 3e 66 64  Lock(p->pHma->fd
29c0: 2c 20 70 2d 3e 69 43 6c 69 65 6e 74 2b 31 2c 20  , p->iClient+1, 
29d0: 53 45 52 56 45 52 5f 57 52 49 54 45 5f 4c 4f 43  SERVER_WRITE_LOC
29e0: 4b 2c 20 30 29 3b 0a 23 65 6e 64 69 66 0a 20 20  K, 0);.#endif.  
29f0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2a00: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 61  ;.}../*.** End a
2a10: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 28 61 6e   transaction (an
2a20: 64 20 72 65 6c 65 61 73 65 20 61 6c 6c 20 6c 6f  d release all lo
2a30: 63 6b 73 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  cks)..*/.int sql
2a40: 69 74 65 33 53 65 72 76 65 72 45 6e 64 28 53 65  ite3ServerEnd(Se
2a50: 72 76 65 72 20 2a 70 29 7b 0a 20 20 69 6e 74 20  rver *p){.  int 
2a60: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
2a70: 70 2d 3e 6e 4c 6f 63 6b 3b 20 69 2b 2b 29 7b 0a  p->nLock; i++){.
2a80: 20 20 20 20 75 33 32 20 2a 70 53 6c 6f 74 20 3d      u32 *pSlot =
2a90: 20 73 65 72 76 65 72 50 61 67 65 4c 6f 63 6b 53   serverPageLockS
2aa0: 6c 6f 74 28 70 2c 20 70 2d 3e 61 4c 6f 63 6b 5b  lot(p, p->aLock[
2ab0: 69 5d 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  i]);.    while( 
2ac0: 31 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20 76  1 ){.      u32 v
2ad0: 20 3d 20 2a 70 53 6c 6f 74 3b 0a 20 20 20 20 20   = *pSlot;.     
2ae0: 20 75 33 32 20 6e 20 3d 20 76 3b 0a 20 20 20 20   u32 n = v;.    
2af0: 20 20 69 66 28 20 28 76 3e 3e 48 4d 41 5f 43 4c    if( (v>>HMA_CL
2b00: 49 45 4e 54 5f 53 4c 4f 54 53 29 3d 3d 70 2d 3e  IENT_SLOTS)==p->
2b10: 69 43 6c 69 65 6e 74 2b 31 20 29 7b 0a 20 20 20  iClient+1 ){.   
2b20: 20 20 20 20 20 6e 20 3d 20 6e 20 26 20 28 28 31       n = n & ((1
2b30: 20 3c 3c 20 48 4d 41 5f 43 4c 49 45 4e 54 5f 53   << HMA_CLIENT_S
2b40: 4c 4f 54 53 29 2d 31 29 3b 0a 20 20 20 20 20 20  LOTS)-1);.      
2b50: 7d 0a 20 20 20 20 20 20 6e 20 3d 20 6e 20 26 20  }.      n = n & 
2b60: 7e 28 31 20 3c 3c 20 70 2d 3e 69 43 6c 69 65 6e  ~(1 << p->iClien
2b70: 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 5f 5f  t);.      if( __
2b80: 73 79 6e 63 5f 76 61 6c 5f 63 6f 6d 70 61 72 65  sync_val_compare
2b90: 5f 61 6e 64 5f 73 77 61 70 28 70 53 6c 6f 74 2c  _and_swap(pSlot,
2ba0: 20 76 2c 20 6e 29 3d 3d 76 20 29 20 62 72 65 61   v, n)==v ) brea
2bb0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70  k;.    }.  }.  p
2bc0: 2d 3e 6e 4c 6f 63 6b 20 3d 20 30 3b 0a 23 69 66  ->nLock = 0;.#if
2bd0: 20 30 0a 20 20 72 65 74 75 72 6e 20 70 6f 73 69   0.  return posi
2be0: 78 4c 6f 63 6b 28 70 2d 3e 70 48 6d 61 2d 3e 66  xLock(p->pHma->f
2bf0: 64 2c 20 70 2d 3e 69 43 6c 69 65 6e 74 2b 31 2c  d, p->iClient+1,
2c00: 20 53 45 52 56 45 52 5f 52 45 41 44 5f 4c 4f 43   SERVER_READ_LOC
2c10: 4b 2c 20 30 29 3b 0a 23 65 6e 64 69 66 0a 20 20  K, 0);.#endif.  
2c20: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2c30: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c 65 61  ;.}../*.** Relea
2c40: 73 65 20 61 6c 6c 20 77 72 69 74 65 2d 6c 6f 63  se all write-loc
2c50: 6b 73 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ks..*/.int sqlit
2c60: 65 33 53 65 72 76 65 72 52 65 6c 65 61 73 65 57  e3ServerReleaseW
2c70: 72 69 74 65 4c 6f 63 6b 73 28 53 65 72 76 65 72  riteLocks(Server
2c80: 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d   *p){.  int rc =
2c90: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 65   SQLITE_OK;.  re
2ca0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
2cb0: 2a 20 4c 6f 63 6b 20 70 61 67 65 20 70 67 6e 6f  * Lock page pgno
2cc0: 20 66 6f 72 20 72 65 61 64 69 6e 67 20 28 62 57   for reading (bW
2cd0: 72 69 74 65 3d 3d 30 29 20 6f 72 20 77 72 69 74  rite==0) or writ
2ce0: 69 6e 67 20 28 62 57 72 69 74 65 3d 3d 31 29 2e  ing (bWrite==1).
2cf0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 53  .*/.int sqlite3S
2d00: 65 72 76 65 72 4c 6f 63 6b 28 53 65 72 76 65 72  erverLock(Server
2d10: 20 2a 70 2c 20 50 67 6e 6f 20 70 67 6e 6f 2c 20   *p, Pgno pgno, 
2d20: 69 6e 74 20 62 57 72 69 74 65 29 7b 0a 20 20 69  int bWrite){.  i
2d30: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2d40: 4b 3b 0a 0a 20 20 2f 2a 20 47 72 6f 77 20 74 68  K;..  /* Grow th
2d50: 65 20 61 4c 6f 63 6b 5b 5d 20 61 72 72 61 79 2c  e aLock[] array,
2d60: 20 69 66 20 72 65 71 75 69 72 65 64 20 2a 2f 0a   if required */.
2d70: 20 20 69 66 28 20 70 2d 3e 6e 4c 6f 63 6b 3d 3d    if( p->nLock==
2d80: 70 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20  p->nAlloc ){.   
2d90: 20 69 6e 74 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e   int nNew = p->n
2da0: 41 6c 6c 6f 63 20 3f 20 70 2d 3e 6e 41 6c 6c 6f  Alloc ? p->nAllo
2db0: 63 2a 32 20 3a 20 31 32 38 3b 0a 20 20 20 20 75  c*2 : 128;.    u
2dc0: 33 32 20 2a 61 4e 65 77 3b 0a 20 20 20 20 61 4e  32 *aNew;.    aN
2dd0: 65 77 20 3d 20 28 75 33 32 2a 29 73 71 6c 69 74  ew = (u32*)sqlit
2de0: 65 33 5f 72 65 61 6c 6c 6f 63 28 70 2d 3e 61 4c  e3_realloc(p->aL
2df0: 6f 63 6b 2c 20 73 69 7a 65 6f 66 28 75 33 32 29  ock, sizeof(u32)
2e00: 2a 6e 4e 65 77 29 3b 0a 20 20 20 20 69 66 28 20  *nNew);.    if( 
2e10: 61 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20  aNew==0 ){.     
2e20: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
2e30: 45 4d 5f 42 4b 50 54 3b 0a 20 20 20 20 7d 65 6c  EM_BKPT;.    }el
2e40: 73 65 7b 0a 20 20 20 20 20 20 70 2d 3e 61 4c 6f  se{.      p->aLo
2e50: 63 6b 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20  ck = aNew;.     
2e60: 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 4e 65   p->nAlloc = nNe
2e70: 77 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  w;.    }.  }.  i
2e80: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
2e90: 20 29 7b 0a 20 20 20 20 75 33 32 20 2a 70 53 6c   ){.    u32 *pSl
2ea0: 6f 74 20 3d 20 73 65 72 76 65 72 50 61 67 65 4c  ot = serverPageL
2eb0: 6f 63 6b 53 6c 6f 74 28 70 2c 20 70 67 6e 6f 29  ockSlot(p, pgno)
2ec0: 3b 0a 20 20 20 20 75 33 32 20 76 20 3d 20 2a 70  ;.    u32 v = *p
2ed0: 53 6c 6f 74 3b 0a 0a 20 20 20 20 2f 2a 20 43 68  Slot;..    /* Ch
2ee0: 65 63 6b 20 69 66 20 74 68 65 20 72 65 71 75 69  eck if the requi
2ef0: 72 65 64 20 6c 6f 63 6b 20 69 73 20 61 6c 72 65  red lock is alre
2f00: 61 64 79 20 68 65 6c 64 2e 20 49 66 20 73 6f 2c  ady held. If so,
2f10: 20 65 78 69 74 20 74 68 69 73 20 66 75 6e 63 74   exit this funct
2f20: 69 6f 6e 0a 20 20 20 20 2a 2a 20 65 61 72 6c 79  ion.    ** early
2f30: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 64 64  . Otherwise, add
2f40: 20 61 6e 20 65 6e 74 72 79 20 74 6f 20 74 68 65   an entry to the
2f50: 20 61 4c 6f 63 6b 5b 5d 20 61 72 72 61 79 20 74   aLock[] array t
2f60: 6f 20 72 65 63 6f 72 64 20 74 68 65 20 66 61 63  o record the fac
2f70: 74 0a 20 20 20 20 2a 2a 20 74 68 61 74 20 74 68  t.    ** that th
2f80: 65 20 6c 6f 63 6b 20 6d 61 79 20 6e 65 65 64 20  e lock may need 
2f90: 74 6f 20 62 65 20 72 65 6c 65 61 73 65 64 2e 20  to be released. 
2fa0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 62 57 72 69   */.    if( bWri
2fb0: 74 65 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  te ){.      int 
2fc0: 69 4c 6f 63 6b 20 3d 20 28 28 69 6e 74 29 28 76  iLock = ((int)(v
2fd0: 3e 3e 48 4d 41 5f 43 4c 49 45 4e 54 5f 53 4c 4f  >>HMA_CLIENT_SLO
2fe0: 54 53 29 29 20 2d 20 31 3b 0a 20 20 20 20 20 20  TS)) - 1;.      
2ff0: 69 66 28 20 69 4c 6f 63 6b 3d 3d 70 2d 3e 69 43  if( iLock==p->iC
3000: 6c 69 65 6e 74 20 29 20 67 6f 74 6f 20 73 65 72  lient ) goto ser
3010: 76 65 72 5f 6c 6f 63 6b 5f 6f 75 74 3b 0a 20 20  ver_lock_out;.  
3020: 20 20 20 20 69 66 28 20 69 4c 6f 63 6b 3c 30 20      if( iLock<0 
3030: 29 7b 0a 20 20 20 20 20 20 20 20 70 2d 3e 61 4c  ){.        p->aL
3040: 6f 63 6b 5b 70 2d 3e 6e 4c 6f 63 6b 2b 2b 5d 20  ock[p->nLock++] 
3050: 3d 20 70 67 6e 6f 3b 0a 20 20 20 20 20 20 7d 0a  = pgno;.      }.
3060: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
3070: 20 69 66 28 20 76 20 26 20 28 31 3c 3c 70 2d 3e   if( v & (1<<p->
3080: 69 43 6c 69 65 6e 74 29 20 29 20 67 6f 74 6f 20  iClient) ) goto 
3090: 73 65 72 76 65 72 5f 6c 6f 63 6b 5f 6f 75 74 3b  server_lock_out;
30a0: 0a 20 20 20 20 20 20 70 2d 3e 61 4c 6f 63 6b 5b  .      p->aLock[
30b0: 70 2d 3e 6e 4c 6f 63 6b 2b 2b 5d 20 3d 20 70 67  p->nLock++] = pg
30c0: 6e 6f 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 77  no;.    }..    w
30d0: 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 20  hile( 1 ){.     
30e0: 20 75 33 32 20 6e 3b 0a 0a 20 20 20 20 20 20 77   u32 n;..      w
30f0: 68 69 6c 65 28 20 28 62 57 72 69 74 65 20 26 26  hile( (bWrite &&
3100: 20 28 76 20 26 20 7e 28 31 20 3c 3c 20 70 2d 3e   (v & ~(1 << p->
3110: 69 43 6c 69 65 6e 74 29 29 29 20 7c 7c 20 28 76  iClient))) || (v
3120: 20 3e 3e 20 48 4d 41 5f 43 4c 49 45 4e 54 5f 53   >> HMA_CLIENT_S
3130: 4c 4f 54 53 29 20 29 7b 0a 20 20 20 20 20 20 20  LOTS) ){.       
3140: 20 69 6e 74 20 62 52 65 74 72 79 20 3d 20 30 3b   int bRetry = 0;
3150: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 65  .        rc = se
3160: 72 76 65 72 4f 76 65 72 63 6f 6d 65 4c 6f 63 6b  rverOvercomeLock
3170: 28 70 2c 20 62 57 72 69 74 65 2c 20 76 2c 20 26  (p, bWrite, v, &
3180: 62 52 65 74 72 79 29 3b 0a 20 20 20 20 20 20 20  bRetry);.       
3190: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
31a0: 4f 4b 20 29 20 67 6f 74 6f 20 73 65 72 76 65 72  OK ) goto server
31b0: 5f 6c 6f 63 6b 5f 6f 75 74 3b 0a 20 20 20 20 20  _lock_out;.     
31c0: 20 20 20 69 66 28 20 62 52 65 74 72 79 3d 3d 30     if( bRetry==0
31d0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a   ){.          /*
31e0: 20 54 68 65 72 65 20 69 73 20 61 20 63 6f 6e 66   There is a conf
31f0: 6c 69 63 74 69 6e 67 20 6c 6f 63 6b 2e 20 43 61  licting lock. Ca
3200: 6e 6e 6f 74 20 6f 62 74 61 69 6e 20 74 68 69 73  nnot obtain this
3210: 20 6c 6f 63 6b 2e 20 2a 2f 0a 20 20 20 20 20 20   lock. */.      
3220: 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28      sqlite3_log(
3230: 53 51 4c 49 54 45 5f 42 55 53 59 5f 44 45 41 44  SQLITE_BUSY_DEAD
3240: 4c 4f 43 4b 2c 20 22 43 6f 6e 66 6c 69 63 74 20  LOCK, "Conflict 
3250: 61 74 20 70 61 67 65 20 25 64 22 2c 20 28 69 6e  at page %d", (in
3260: 74 29 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20 20  t)pgno);.       
3270: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42     rc = SQLITE_B
3280: 55 53 59 5f 44 45 41 44 4c 4f 43 4b 3b 0a 20 20  USY_DEADLOCK;.  
3290: 20 20 20 20 20 20 20 20 67 6f 74 6f 20 73 65 72          goto ser
32a0: 76 65 72 5f 6c 6f 63 6b 5f 6f 75 74 3b 0a 20 20  ver_lock_out;.  
32b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
32c0: 76 20 3d 20 2a 70 53 6c 6f 74 3b 0a 20 20 20 20  v = *pSlot;.    
32d0: 20 20 7d 0a 0a 20 20 20 20 20 20 6e 20 3d 20 76    }..      n = v
32e0: 20 7c 20 28 31 20 3c 3c 20 70 2d 3e 69 43 6c 69   | (1 << p->iCli
32f0: 65 6e 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ent);.      if( 
3300: 62 57 72 69 74 65 20 29 7b 0a 20 20 20 20 20 20  bWrite ){.      
3310: 20 20 6e 20 3d 20 6e 20 7c 20 28 28 70 2d 3e 69    n = n | ((p->i
3320: 43 6c 69 65 6e 74 2b 31 29 20 3c 3c 20 48 4d 41  Client+1) << HMA
3330: 5f 43 4c 49 45 4e 54 5f 53 4c 4f 54 53 29 3b 0a  _CLIENT_SLOTS);.
3340: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
3350: 28 20 5f 5f 73 79 6e 63 5f 76 61 6c 5f 63 6f 6d  ( __sync_val_com
3360: 70 61 72 65 5f 61 6e 64 5f 73 77 61 70 28 70 53  pare_and_swap(pS
3370: 6c 6f 74 2c 20 76 2c 20 6e 29 3d 3d 76 20 29 20  lot, v, n)==v ) 
3380: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 76 20 3d  break;.      v =
3390: 20 2a 70 53 6c 6f 74 3b 0a 20 20 20 20 7d 0a 20   *pSlot;.    }. 
33a0: 20 7d 0a 0a 73 65 72 76 65 72 5f 6c 6f 63 6b 5f   }..server_lock_
33b0: 6f 75 74 3a 0a 20 20 72 65 74 75 72 6e 20 72 63  out:.  return rc
33c0: 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 69  ;.}..#endif /* i
33d0: 66 64 65 66 20 53 51 4c 49 54 45 5f 53 45 52 56  fdef SQLITE_SERV
33e0: 45 52 5f 45 44 49 54 49 4f 4e 20 2a 2f 0a        ER_EDITION */.