/ Hex Artifact Content
Login

Artifact 50d10b5684399676174bd96c94ad4250b1a2c8b6:


0000: 23 20 32 30 30 39 20 4d 61 72 63 68 20 31 31 0a  # 2009 March 11.
0010: 23 0a 23 20 54 68 65 20 61 75 74 68 6f 72 20 64  #.# The author d
0020: 69 73 63 6c 61 69 6d 73 20 63 6f 70 79 72 69 67  isclaims copyrig
0030: 68 74 20 74 6f 20 74 68 69 73 20 73 6f 75 72 63  ht to this sourc
0040: 65 20 63 6f 64 65 2e 20 20 49 6e 20 70 6c 61 63  e code.  In plac
0050: 65 20 6f 66 0a 23 20 61 20 6c 65 67 61 6c 20 6e  e of.# a legal n
0060: 6f 74 69 63 65 2c 20 68 65 72 65 20 69 73 20 61  otice, here is a
0070: 20 62 6c 65 73 73 69 6e 67 3a 0a 23 0a 23 20 20   blessing:.#.#  
0080: 20 20 4d 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f    May you do goo
0090: 64 20 61 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a  d and not evil..
00a0: 23 20 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e  #    May you fin
00b0: 64 20 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f  d forgiveness fo
00c0: 72 20 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66  r yourself and f
00d0: 6f 72 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 23  orgive others..#
00e0: 20 20 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72      May you shar
00f0: 65 20 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20  e freely, never 
0100: 74 61 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e  taking more than
0110: 20 79 6f 75 20 67 69 76 65 2e 0a 23 0a 23 2a 2a   you give..#.#**
0120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 0a 23 0a 23 20 54 65 73 74 20 61  *****.#.# Test a
0170: 20 72 61 63 65 2d 63 6f 6e 64 69 74 69 6f 6e 20   race-condition 
0180: 74 68 61 74 20 73 68 6f 77 73 20 75 70 20 69 6e  that shows up in
0190: 20 73 68 61 72 65 64 2d 63 61 63 68 65 20 6d 6f   shared-cache mo
01a0: 64 65 2e 0a 23 0a 23 20 24 49 64 3a 20 74 68 72  de..#.# $Id: thr
01b0: 65 61 64 30 30 35 2e 74 65 73 74 2c 76 20 31 2e  ead005.test,v 1.
01c0: 35 20 32 30 30 39 2f 30 33 2f 32 36 20 31 34 3a  5 2009/03/26 14:
01d0: 34 38 3a 30 37 20 64 61 6e 69 65 6c 6b 31 39 37  48:07 danielk197
01e0: 37 20 45 78 70 20 24 0a 0a 73 65 74 20 74 65 73  7 Exp $..set tes
01f0: 74 64 69 72 20 5b 66 69 6c 65 20 64 69 72 6e 61  tdir [file dirna
0200: 6d 65 20 24 61 72 67 76 30 5d 0a 0a 73 6f 75 72  me $argv0]..sour
0210: 63 65 20 24 74 65 73 74 64 69 72 2f 74 65 73 74  ce $testdir/test
0220: 65 72 2e 74 63 6c 0a 69 66 20 7b 5b 72 75 6e 5f  er.tcl.if {[run_
0230: 74 68 72 65 61 64 5f 74 65 73 74 73 5d 3d 3d 30  thread_tests]==0
0240: 7d 20 7b 20 66 69 6e 69 73 68 5f 74 65 73 74 20  } { finish_test 
0250: 3b 20 72 65 74 75 72 6e 20 7d 0a 69 66 63 61 70  ; return }.ifcap
0260: 61 62 6c 65 20 21 73 68 61 72 65 64 5f 63 61 63  able !shared_cac
0270: 68 65 20 7b 0a 20 20 66 69 6e 69 73 68 5f 74 65  he {.  finish_te
0280: 73 74 0a 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 64  st.  return.}..d
0290: 62 20 63 6c 6f 73 65 0a 0a 23 20 55 73 65 20 73  b close..# Use s
02a0: 68 61 72 65 64 2d 63 61 63 68 65 20 6d 6f 64 65  hared-cache mode
02b0: 20 66 6f 72 20 74 68 65 73 65 20 74 65 73 74 73   for these tests
02c0: 2e 0a 23 20 0a 73 65 74 20 3a 3a 65 6e 61 62 6c  ..# .set ::enabl
02d0: 65 5f 73 68 61 72 65 64 5f 63 61 63 68 65 20 5b  e_shared_cache [
02e0: 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 73  sqlite3_enable_s
02f0: 68 61 72 65 64 5f 63 61 63 68 65 5d 0a 73 71 6c  hared_cache].sql
0300: 69 74 65 33 5f 65 6e 61 62 6c 65 5f 73 68 61 72  ite3_enable_shar
0310: 65 64 5f 63 61 63 68 65 20 31 0a 0a 23 2d 2d 2d  ed_cache 1..#---
0320: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0330: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0340: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0350: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0360: 2d 2d 2d 2d 2d 2d 0a 23 20 54 68 69 73 20 74 65  ------.# This te
0370: 73 74 20 61 74 74 65 6d 70 74 73 20 74 6f 20 68  st attempts to h
0380: 69 74 20 74 68 65 20 72 61 63 65 20 63 6f 6e 64  it the race cond
0390: 69 74 69 6f 6e 20 66 69 78 65 64 20 62 79 20 63  ition fixed by c
03a0: 6f 6d 6d 69 74 20 5b 36 33 36 33 5d 2e 0a 23 0a  ommit [6363]..#.
03b0: 70 72 6f 63 20 72 75 6e 73 71 6c 20 7b 7a 53 71  proc runsql {zSq
03c0: 6c 20 7b 64 62 20 7b 7d 7d 7d 20 7b 0a 20 20 73  l {db {}}} {.  s
03d0: 65 74 20 72 63 20 53 51 4c 49 54 45 5f 4f 4b 0a  et rc SQLITE_OK.
03e0: 20 20 77 68 69 6c 65 20 7b 24 72 63 3d 3d 22 53    while {$rc=="S
03f0: 51 4c 49 54 45 5f 4f 4b 22 20 26 26 20 24 7a 53  QLITE_OK" && $zS
0400: 71 6c 20 6e 65 20 22 22 7d 20 7b 0a 20 20 20 20  ql ne ""} {.    
0410: 73 65 74 20 53 54 4d 54 20 5b 73 71 6c 69 74 65  set STMT [sqlite
0420: 33 5f 70 72 65 70 61 72 65 5f 76 32 20 24 64 62  3_prepare_v2 $db
0430: 20 24 7a 53 71 6c 20 2d 31 20 7a 53 71 6c 5d 0a   $zSql -1 zSql].
0440: 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 65 74 20      while {[set 
0450: 72 63 20 5b 73 71 6c 69 74 65 33 5f 73 74 65 70  rc [sqlite3_step
0460: 20 24 53 54 4d 54 5d 5d 20 65 71 20 22 53 51 4c   $STMT]] eq "SQL
0470: 49 54 45 5f 52 4f 57 22 7d 20 7b 20 7d 0a 20 20  ITE_ROW"} { }.  
0480: 20 20 73 65 74 20 72 63 20 5b 73 71 6c 69 74 65    set rc [sqlite
0490: 33 5f 66 69 6e 61 6c 69 7a 65 20 24 53 54 4d 54  3_finalize $STMT
04a0: 5d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 24  ].  }.  return $
04b0: 72 63 0a 7d 0a 64 6f 5f 74 65 73 74 20 74 68 72  rc.}.do_test thr
04c0: 65 61 64 30 30 35 2d 31 2e 31 20 7b 0a 20 20 73  ead005-1.1 {.  s
04d0: 71 6c 69 74 65 33 20 64 62 20 74 65 73 74 2e 64  qlite3 db test.d
04e0: 62 0a 20 20 64 62 20 65 76 61 6c 20 7b 20 43 52  b.  db eval { CR
04f0: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c  EATE TABLE t1(a,
0500: 20 62 29 20 7d 0a 20 20 64 62 20 63 6c 6f 73 65   b) }.  db close
0510: 0a 7d 20 7b 7d 0a 66 6f 72 20 7b 73 65 74 20 69  .} {}.for {set i
0520: 69 20 32 7d 20 7b 24 69 69 20 3c 20 35 30 30 7d  i 2} {$ii < 500}
0530: 20 7b 69 6e 63 72 20 69 69 7d 20 7b 0a 20 20 75   {incr ii} {.  u
0540: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  nset -nocomplain
0550: 20 66 69 6e 69 73 68 65 64 0a 20 20 74 68 72 65   finished.  thre
0560: 61 64 5f 73 70 61 77 6e 20 66 69 6e 69 73 68 65  ad_spawn finishe
0570: 64 28 30 29 20 7b 73 71 6c 69 74 65 33 5f 6f 70  d(0) {sqlite3_op
0580: 65 6e 20 74 65 73 74 2e 64 62 7d 0a 20 20 74 68  en test.db}.  th
0590: 72 65 61 64 5f 73 70 61 77 6e 20 66 69 6e 69 73  read_spawn finis
05a0: 68 65 64 28 31 29 20 7b 73 71 6c 69 74 65 33 5f  hed(1) {sqlite3_
05b0: 6f 70 65 6e 20 74 65 73 74 2e 64 62 7d 0a 20 20  open test.db}.  
05c0: 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74  if {![info exist
05d0: 73 20 66 69 6e 69 73 68 65 64 28 30 29 5d 7d 20  s finished(0)]} 
05e0: 7b 20 76 77 61 69 74 20 66 69 6e 69 73 68 65 64  { vwait finished
05f0: 28 30 29 20 7d 0a 20 20 69 66 20 7b 21 5b 69 6e  (0) }.  if {![in
0600: 66 6f 20 65 78 69 73 74 73 20 66 69 6e 69 73 68  fo exists finish
0610: 65 64 28 31 29 5d 7d 20 7b 20 76 77 61 69 74 20  ed(1)]} { vwait 
0620: 66 69 6e 69 73 68 65 64 28 31 29 20 7d 0a 0a 20  finished(1) }.. 
0630: 20 64 6f 5f 74 65 73 74 20 74 68 72 65 61 64 30   do_test thread0
0640: 30 35 2d 31 2e 24 69 69 20 7b 0a 20 20 20 20 72  05-1.$ii {.    r
0650: 75 6e 73 71 6c 20 7b 20 42 45 47 49 4e 20 7d 20  unsql { BEGIN } 
0660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0670: 20 20 20 20 20 20 24 66 69 6e 69 73 68 65 64 28        $finished(
0680: 30 29 0a 20 20 20 20 72 75 6e 73 71 6c 20 7b 20  0).    runsql { 
0690: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 20 56  INSERT INTO t1 V
06a0: 41 4c 55 45 53 28 31 2c 20 32 29 20 7d 20 24 66  ALUES(1, 2) } $f
06b0: 69 6e 69 73 68 65 64 28 30 29 0a 0a 20 20 20 20  inished(0)..    
06c0: 23 20 49 66 20 74 68 65 20 72 61 63 65 2d 63 6f  # If the race-co
06d0: 6e 64 69 74 69 6f 6e 20 77 61 73 20 68 69 74 2c  ndition was hit,
06e0: 20 74 68 65 6e 20 24 66 69 6e 69 73 68 65 64 28   then $finished(
06f0: 30 20 61 6e 64 20 24 66 69 6e 69 73 68 65 64 28  0 and $finished(
0700: 31 29 0a 20 20 20 20 23 20 77 69 6c 6c 20 6e 6f  1).    # will no
0710: 74 20 75 73 65 20 74 68 65 20 73 61 6d 65 20 70  t use the same p
0720: 61 67 65 72 20 63 61 63 68 65 2e 20 49 6e 20 74  ager cache. In t
0730: 68 69 73 20 63 61 73 65 20 74 68 65 20 6e 65 78  his case the nex
0740: 74 20 73 74 61 74 65 6d 65 6e 74 0a 20 20 20 20  t statement.    
0750: 23 20 63 61 6e 20 62 65 20 65 78 65 63 75 74 65  # can be execute
0760: 64 20 73 75 63 63 65 73 66 75 6c 6c 79 2e 20 48  d succesfully. H
0770: 6f 77 65 76 65 72 2c 20 69 66 20 74 68 65 20 72  owever, if the r
0780: 61 63 65 2d 63 6f 6e 64 69 74 69 6f 6e 20 69 73  ace-condition is
0790: 20 6e 6f 74 0a 20 20 20 20 23 20 68 69 74 2c 20   not.    # hit, 
07a0: 74 68 65 6e 20 24 66 69 6e 69 73 68 65 64 28 31  then $finished(1
07b0: 29 20 77 69 6c 6c 20 62 65 20 62 6c 6f 63 6b 65  ) will be blocke
07c0: 64 20 62 79 20 74 68 65 20 77 72 69 74 65 2d 6c  d by the write-l
07d0: 6f 63 6b 20 68 65 6c 64 20 62 79 20 0a 20 20 20  ock held by .   
07e0: 20 23 20 24 66 69 6e 69 73 68 65 64 28 30 29 20   # $finished(0) 
07f0: 6f 6e 20 74 68 65 20 73 68 61 72 65 64 2d 63 61  on the shared-ca
0800: 63 68 65 20 74 61 62 6c 65 20 74 31 20 61 6e 64  che table t1 and
0810: 20 74 68 65 20 73 74 61 74 65 6d 65 6e 74 20 77   the statement w
0820: 69 6c 6c 0a 20 20 20 20 23 20 72 65 74 75 72 6e  ill.    # return
0830: 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 45 44 2e 0a   SQLITE_LOCKED..
0840: 20 20 20 20 23 0a 20 20 20 20 72 75 6e 73 71 6c      #.    runsql
0850: 20 7b 20 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d   { SELECT * FROM
0860: 20 74 31 20 7d 20 20 20 20 20 20 20 20 20 20 20   t1 }           
0870: 20 24 66 69 6e 69 73 68 65 64 28 31 29 0a 20 20   $finished(1).  
0880: 7d 20 7b 53 51 4c 49 54 45 5f 4c 4f 43 4b 45 44  } {SQLITE_LOCKED
0890: 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 63 6c 6f  }..  sqlite3_clo
08a0: 73 65 20 24 66 69 6e 69 73 68 65 64 28 30 29 0a  se $finished(0).
08b0: 20 20 73 71 6c 69 74 65 33 5f 63 6c 6f 73 65 20    sqlite3_close 
08c0: 24 66 69 6e 69 73 68 65 64 28 31 29 0a 7d 0a 0a  $finished(1).}..
08d0: 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#--------------
08e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
08f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0900: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0910: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 54 68  -----------.# Th
0920: 69 73 20 74 65 73 74 20 74 72 69 65 73 20 74 6f  is test tries to
0930: 20 65 78 65 72 63 69 73 65 20 61 20 72 61 63 65   exercise a race
0940: 2d 63 6f 6e 64 69 74 69 6f 6e 20 74 68 61 74 20  -condition that 
0950: 65 78 69 73 74 65 64 20 69 6e 20 73 68 61 72 65  existed in share
0960: 64 2d 63 61 63 68 65 0a 23 20 6d 6f 64 65 20 61  d-cache.# mode a
0970: 74 20 6f 6e 65 20 70 6f 69 6e 74 2e 20 54 68 65  t one point. The
0980: 20 74 65 73 74 20 75 73 65 73 20 74 77 6f 20 74   test uses two t
0990: 68 72 65 61 64 73 3b 20 65 61 63 68 20 68 61 73  hreads; each has
09a0: 20 61 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e   a database conn
09b0: 65 63 74 69 6f 6e 0a 23 20 6f 70 65 6e 20 6f 6e  ection.# open on
09c0: 20 74 68 65 20 73 61 6d 65 20 73 68 61 72 65 64   the same shared
09d0: 20 63 61 63 68 65 2e 20 54 68 65 20 73 63 68 65   cache. The sche
09e0: 6d 61 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ma of the databa
09f0: 73 65 20 69 73 3a 0a 23 0a 23 20 20 20 20 43 52  se is:.#.#    CR
0a00: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20  EATE TABLE t1(a 
0a10: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20  INTEGER PRIMARY 
0a20: 4b 45 59 2c 20 62 20 55 4e 49 51 55 45 29 3b 0a  KEY, b UNIQUE);.
0a30: 23 0a 23 20 4f 6e 65 20 74 68 72 65 61 64 20 69  #.# One thread i
0a40: 73 20 61 20 72 65 61 64 65 72 20 61 6e 64 20 74  s a reader and t
0a50: 68 65 20 6f 74 68 65 72 20 74 68 72 65 61 64 20  he other thread 
0a60: 61 20 72 65 61 64 65 72 20 61 6e 64 20 61 20 77  a reader and a w
0a70: 72 69 74 65 72 2e 20 54 68 65 20 0a 23 20 77 72  riter. The .# wr
0a80: 69 74 65 72 20 74 68 72 65 61 64 20 72 65 70 65  iter thread repe
0a90: 61 74 73 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e  ats the followin
0aa0: 67 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 61 73  g transaction as
0ab0: 20 66 61 73 74 20 61 73 20 70 6f 73 73 69 62 6c   fast as possibl
0ac0: 65 3a 0a 23 20 0a 23 20 20 20 20 20 20 42 45 47  e:.# .#      BEG
0ad0: 49 4e 3b 0a 23 20 20 20 20 20 20 20 20 44 45 4c  IN;.#        DEL
0ae0: 45 54 45 20 46 52 4f 4d 20 74 31 20 57 48 45 52  ETE FROM t1 WHER
0af0: 45 20 61 20 3d 20 28 53 45 4c 45 43 54 20 6d 61  E a = (SELECT ma
0b00: 78 28 61 29 20 46 52 4f 4d 20 74 31 29 3b 0a 23  x(a) FROM t1);.#
0b10: 20 20 20 20 20 20 20 20 49 4e 53 45 52 54 20 49          INSERT I
0b20: 4e 54 4f 20 74 31 20 56 41 4c 55 45 53 28 4e 55  NTO t1 VALUES(NU
0b30: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 23 20 20 20 20  LL, NULL);.#    
0b40: 20 20 20 20 55 50 44 41 54 45 20 74 31 20 53 45      UPDATE t1 SE
0b50: 54 20 62 20 3d 20 61 20 57 48 45 52 45 20 61 20  T b = a WHERE a 
0b60: 3d 20 28 53 45 4c 45 43 54 20 6d 61 78 28 61 29  = (SELECT max(a)
0b70: 20 46 52 4f 4d 20 74 31 29 3b 0a 23 20 20 20 20   FROM t1);.#    
0b80: 20 20 20 20 53 45 4c 45 43 54 20 63 6f 75 6e 74      SELECT count
0b90: 28 2a 29 20 46 52 4f 4d 20 74 31 20 57 48 45 52  (*) FROM t1 WHER
0ba0: 45 20 62 20 49 53 20 4e 55 4c 4c 3b 0a 23 20 20  E b IS NULL;.#  
0bb0: 20 20 20 20 43 4f 4d 4d 49 54 3b 0a 23 0a 23 20      COMMIT;.#.# 
0bc0: 54 68 65 20 72 65 61 64 65 72 20 74 68 72 65 61  The reader threa
0bd0: 64 20 64 6f 65 73 20 74 68 65 20 66 6f 6c 6c 6f  d does the follo
0be0: 77 69 6e 67 20 6f 76 65 72 20 61 6e 64 20 6f 76  wing over and ov
0bf0: 65 72 20 61 73 20 66 61 73 74 20 61 73 20 70 6f  er as fast as po
0c00: 73 73 69 62 6c 65 3a 0a 23 0a 23 20 20 20 20 20  ssible:.#.#     
0c10: 20 42 45 47 49 4e 3b 0a 23 20 20 20 20 20 20 20   BEGIN;.#       
0c20: 20 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29   SELECT count(*)
0c30: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 62   FROM t1 WHERE b
0c40: 20 49 53 20 4e 55 4c 4c 3b 0a 23 20 20 20 20 20   IS NULL;.#     
0c50: 20 43 4f 4d 4d 49 54 3b 0a 23 0a 23 20 54 68 65   COMMIT;.#.# The
0c60: 20 74 65 73 74 20 72 75 6e 73 20 66 6f 72 20 32   test runs for 2
0c70: 30 20 73 65 63 6f 6e 64 73 20 6f 72 20 75 6e 74  0 seconds or unt
0c80: 69 6c 20 6f 6e 65 20 6f 66 20 74 68 65 20 22 53  il one of the "S
0c90: 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 22 20  ELECT count(*)" 
0ca0: 0a 23 20 73 74 61 74 65 6d 65 6e 74 73 20 72 65  .# statements re
0cb0: 74 75 72 6e 73 20 61 20 6e 6f 6e 2d 7a 65 72 6f  turns a non-zero
0cc0: 20 76 61 6c 75 65 2e 20 49 66 20 61 6e 20 53 51   value. If an SQ
0cd0: 4c 49 54 45 5f 4c 4f 43 4b 45 44 20 65 72 72 6f  LITE_LOCKED erro
0ce0: 72 20 6f 63 63 75 72 73 2c 0a 23 20 74 68 65 20  r occurs,.# the 
0cf0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 73 75 65  connection issue
0d00: 73 20 61 20 52 4f 4c 4c 42 41 43 4b 20 69 6d 6d  s a ROLLBACK imm
0d10: 65 64 69 61 74 65 6c 79 20 74 6f 20 61 62 61 6e  ediately to aban
0d20: 64 6f 6e 20 74 68 65 20 63 75 72 72 65 6e 74 0a  don the current.
0d30: 23 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 23  # transaction..#
0d40: 0a 23 20 49 66 20 65 76 65 72 79 74 68 69 6e 67  .# If everything
0d50: 20 69 73 20 77 6f 72 6b 69 6e 67 20 63 6f 72 72   is working corr
0d60: 65 63 74 6c 79 2c 20 74 68 65 20 22 53 45 4c 45  ectly, the "SELE
0d70: 43 54 20 63 6f 75 6e 74 28 2a 29 22 20 73 74 61  CT count(*)" sta
0d80: 74 65 6d 65 6e 74 73 20 0a 23 20 73 68 6f 75 6c  tements .# shoul
0d90: 64 20 6e 65 76 65 72 20 72 65 74 75 72 6e 20 61  d never return a
0da0: 20 76 61 6c 75 65 20 6f 74 68 65 72 20 74 68 61   value other tha
0db0: 6e 20 30 2e 20 54 68 65 20 22 49 4e 53 45 52 54  n 0. The "INSERT
0dc0: 22 20 73 74 61 74 65 6d 65 6e 74 20 0a 23 20 65  " statement .# e
0dd0: 78 65 63 75 74 65 64 20 62 79 20 74 68 65 20 77  xecuted by the w
0de0: 72 69 74 65 72 20 61 64 64 73 20 61 20 72 6f 77  riter adds a row
0df0: 20 77 69 74 68 20 22 62 20 49 53 20 4e 55 4c 4c   with "b IS NULL
0e00: 22 20 74 6f 20 74 68 65 20 74 61 62 6c 65 2c 20  " to the table, 
0e10: 62 75 74 0a 23 20 74 68 65 20 73 75 62 73 65 71  but.# the subseq
0e20: 75 65 6e 74 20 55 50 44 41 54 45 20 73 74 61 74  uent UPDATE stat
0e30: 65 6d 65 6e 74 20 73 65 74 73 20 69 74 73 20 22  ement sets its "
0e40: 62 22 20 76 61 6c 75 65 20 74 6f 20 61 6e 20 69  b" value to an i
0e50: 6e 74 65 67 65 72 0a 23 20 69 6d 6d 65 64 69 61  nteger.# immedia
0e60: 74 65 6c 79 20 61 66 74 65 72 77 61 72 64 73 2e  tely afterwards.
0e70: 0a 23 0a 23 20 48 6f 77 65 76 65 72 2c 20 62 65  .#.# However, be
0e80: 66 6f 72 65 20 74 68 65 20 72 61 63 65 2d 63 6f  fore the race-co
0e90: 6e 64 69 74 69 6f 6e 20 77 61 73 20 66 69 78 65  ndition was fixe
0ea0: 64 2c 20 69 66 20 74 68 65 20 72 65 61 64 65 72  d, if the reader
0eb0: 27 73 20 53 45 4c 45 43 54 0a 23 20 73 74 61 74  's SELECT.# stat
0ec0: 65 6d 65 6e 74 20 68 69 74 20 61 6e 20 65 72 72  ement hit an err
0ed0: 6f 72 20 28 73 61 79 20 61 6e 20 53 51 4c 49 54  or (say an SQLIT
0ee0: 45 5f 4c 4f 43 4b 45 44 29 20 61 74 20 74 68 65  E_LOCKED) at the
0ef0: 20 73 61 6d 65 20 74 69 6d 65 20 61 73 20 74 68   same time as th
0f00: 65 0a 23 20 77 72 69 74 65 72 20 77 61 73 20 65  e.# writer was e
0f10: 78 65 63 75 74 69 6e 67 20 74 68 65 20 55 50 44  xecuting the UPD
0f20: 41 54 45 20 73 74 61 74 65 6d 65 6e 74 2c 20 74  ATE statement, t
0f30: 68 65 6e 20 69 74 20 63 6f 75 6c 64 20 69 6e 63  hen it could inc
0f40: 6f 72 72 65 63 74 6c 79 0a 23 20 72 6f 6c 6c 62  orrectly.# rollb
0f50: 61 63 6b 20 74 68 65 20 73 74 61 74 65 6d 65 6e  ack the statemen
0f60: 74 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20 62 65  t-transaction be
0f70: 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68 65 20 55  longing to the U
0f80: 50 44 41 54 45 20 73 74 61 74 65 6d 65 6e 74 2e  PDATE statement.
0f90: 0a 23 20 54 68 65 20 55 50 44 41 54 45 20 73 74  .# The UPDATE st
0fa0: 61 74 65 6d 65 6e 74 20 77 6f 75 6c 64 20 73 74  atement would st
0fb0: 69 6c 6c 20 62 65 20 72 65 70 6f 72 74 65 64 20  ill be reported 
0fc0: 61 73 20 73 75 63 63 65 73 73 66 75 6c 20 74 6f  as successful to
0fd0: 20 74 68 65 20 75 73 65 72 2c 0a 23 20 62 75 74   the user,.# but
0fe0: 20 69 74 20 77 6f 75 6c 64 20 68 61 76 65 20 6e   it would have n
0ff0: 6f 20 65 66 66 65 63 74 20 6f 6e 20 74 68 65 20  o effect on the 
1000: 64 61 74 61 62 61 73 65 20 63 6f 6e 74 65 6e 74  database content
1010: 73 2e 0a 23 20 0a 23 20 4e 6f 74 65 20 74 68 61  s..# .# Note tha
1020: 74 20 69 74 20 68 61 73 20 73 6f 20 66 61 72 20  t it has so far 
1030: 6f 6e 6c 79 20 70 72 6f 76 65 64 20 70 6f 73 73  only proved poss
1040: 69 62 6c 65 20 74 6f 20 68 69 74 20 74 68 69 73  ible to hit this
1050: 20 72 61 63 65 2d 63 6f 6e 64 69 74 69 6f 6e 0a   race-condition.
1060: 23 20 77 68 65 6e 20 75 73 69 6e 67 20 61 6e 20  # when using an 
1070: 41 54 54 41 43 48 65 64 20 64 61 74 61 62 61 73  ATTACHed databas
1080: 65 2e 20 54 68 65 72 65 20 64 6f 65 73 6e 27 74  e. There doesn't
1090: 20 73 65 65 6d 20 74 6f 20 62 65 20 61 6e 79 20   seem to be any 
10a0: 72 65 61 73 6f 6e 0a 23 20 66 6f 72 20 74 68 69  reason.# for thi
10b0: 73 2c 20 6f 74 68 65 72 20 74 68 61 6e 20 74 68  s, other than th
10c0: 61 74 20 6f 70 65 72 61 74 69 6e 67 20 6f 6e 20  at operating on 
10d0: 61 6e 20 41 54 54 41 43 48 65 64 20 64 61 74 61  an ATTACHed data
10e0: 62 61 73 65 20 6d 65 61 6e 73 20 74 68 65 72 65  base means there
10f0: 0a 23 20 61 72 65 20 61 20 66 65 77 20 6d 6f 72  .# are a few mor
1100: 65 20 6d 75 74 65 78 20 67 72 61 62 73 20 61 6e  e mutex grabs an
1110: 64 20 72 65 6c 65 61 73 65 73 20 64 75 72 69 6e  d releases durin
1120: 67 20 74 68 65 20 77 69 6e 64 6f 77 20 6f 66 20  g the window of 
1130: 74 69 6d 65 20 6f 70 65 6e 0a 23 20 66 6f 72 20  time open.# for 
1140: 74 68 65 20 72 61 63 65 2d 63 6f 6e 64 69 74 69  the race-conditi
1150: 6f 6e 2e 20 4d 61 79 62 65 20 74 68 69 73 20 65  on. Maybe this e
1160: 6e 63 6f 75 72 61 67 65 73 20 74 68 65 20 73 63  ncourages the sc
1170: 68 65 64 75 6c 65 72 20 74 6f 20 63 6f 6e 74 65  heduler to conte
1180: 78 74 0a 23 20 73 77 69 74 63 68 20 6f 72 20 73  xt.# switch or s
1190: 6f 6d 65 74 68 69 6e 67 2e 2e 2e 0a 23 0a 0a 66  omething....#..f
11a0: 6f 72 63 65 64 65 6c 65 74 65 20 74 65 73 74 2e  orcedelete test.
11b0: 64 62 20 74 65 73 74 32 2e 64 62 0a 75 6e 73 65  db test2.db.unse
11c0: 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 66 69  t -nocomplain fi
11d0: 6e 69 73 68 65 64 0a 0a 64 6f 5f 74 65 73 74 20  nished..do_test 
11e0: 74 68 72 65 61 64 30 30 35 2d 32 2e 31 20 7b 0a  thread005-2.1 {.
11f0: 20 20 73 71 6c 69 74 65 33 20 64 62 20 74 65 73    sqlite3 db tes
1200: 74 2e 64 62 0a 20 20 65 78 65 63 73 71 6c 20 7b  t.db.  execsql {
1210: 20 41 54 54 41 43 48 20 27 74 65 73 74 32 2e 64   ATTACH 'test2.d
1220: 62 27 20 41 53 20 61 75 78 20 7d 0a 20 20 65 78  b' AS aux }.  ex
1230: 65 63 73 71 6c 20 7b 0a 20 20 20 20 43 52 45 41  ecsql {.    CREA
1240: 54 45 20 54 41 42 4c 45 20 61 75 78 2e 74 31 28  TE TABLE aux.t1(
1250: 61 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52  a INTEGER PRIMAR
1260: 59 20 4b 45 59 2c 20 62 20 55 4e 49 51 55 45 29  Y KEY, b UNIQUE)
1270: 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54  ;.    INSERT INT
1280: 4f 20 74 31 20 56 41 4c 55 45 53 28 31 2c 20 31  O t1 VALUES(1, 1
1290: 29 3b 0a 20 20 20 20 49 4e 53 45 52 54 20 49 4e  );.    INSERT IN
12a0: 54 4f 20 74 31 20 56 41 4c 55 45 53 28 32 2c 20  TO t1 VALUES(2, 
12b0: 32 29 3b 0a 20 20 7d 0a 20 20 64 62 20 63 6c 6f  2);.  }.  db clo
12c0: 73 65 0a 7d 20 7b 7d 0a 0a 0a 73 65 74 20 54 68  se.} {}...set Th
12d0: 72 65 61 64 50 72 6f 67 72 61 6d 20 7b 0a 20 20  readProgram {.  
12e0: 70 72 6f 63 20 65 78 65 63 73 71 6c 20 7b 7a 53  proc execsql {zS
12f0: 71 6c 20 7b 64 62 20 7b 7d 7d 7d 20 7b 0a 20 20  ql {db {}}} {.  
1300: 20 20 69 66 20 7b 24 64 62 20 65 71 20 22 22 7d    if {$db eq ""}
1310: 20 7b 73 65 74 20 64 62 20 24 3a 3a 44 42 7d 0a   {set db $::DB}.
1320: 0a 20 20 20 20 73 65 74 20 6c 52 65 73 20 5b 6c  .    set lRes [l
1330: 69 73 74 5d 0a 20 20 20 20 73 65 74 20 72 63 20  ist].    set rc 
1340: 53 51 4c 49 54 45 5f 4f 4b 0a 0a 20 20 20 20 77  SQLITE_OK..    w
1350: 68 69 6c 65 20 7b 24 72 63 3d 3d 22 53 51 4c 49  hile {$rc=="SQLI
1360: 54 45 5f 4f 4b 22 20 26 26 20 24 7a 53 71 6c 20  TE_OK" && $zSql 
1370: 6e 65 20 22 22 7d 20 7b 0a 20 20 20 20 20 20 73  ne ""} {.      s
1380: 65 74 20 53 54 4d 54 20 5b 73 71 6c 69 74 65 33  et STMT [sqlite3
1390: 5f 70 72 65 70 61 72 65 5f 76 32 20 24 64 62 20  _prepare_v2 $db 
13a0: 24 7a 53 71 6c 20 2d 31 20 7a 53 71 6c 5d 0a 20  $zSql -1 zSql]. 
13b0: 20 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 65 74       while {[set
13c0: 20 72 63 20 5b 73 71 6c 69 74 65 33 5f 73 74 65   rc [sqlite3_ste
13d0: 70 20 24 53 54 4d 54 5d 5d 20 65 71 20 22 53 51  p $STMT]] eq "SQ
13e0: 4c 49 54 45 5f 52 4f 57 22 7d 20 7b 0a 20 20 20  LITE_ROW"} {.   
13f0: 20 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20       for {set i 
1400: 30 7d 20 7b 24 69 20 3c 20 5b 73 71 6c 69 74 65  0} {$i < [sqlite
1410: 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 20 24  3_column_count $
1420: 53 54 4d 54 5d 7d 20 7b 69 6e 63 72 20 69 7d 20  STMT]} {incr i} 
1430: 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 61 70 70  {.          lapp
1440: 65 6e 64 20 6c 52 65 73 20 5b 73 71 6c 69 74 65  end lRes [sqlite
1450: 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 20 24 53  3_column_text $S
1460: 54 4d 54 20 30 5d 0a 20 20 20 20 20 20 20 20 7d  TMT 0].        }
1470: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73  .      }.      s
1480: 65 74 20 72 63 20 5b 73 71 6c 69 74 65 33 5f 66  et rc [sqlite3_f
1490: 69 6e 61 6c 69 7a 65 20 24 53 54 4d 54 5d 0a 20  inalize $STMT]. 
14a0: 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 72     }..    if {$r
14b0: 63 20 21 3d 20 22 53 51 4c 49 54 45 5f 4f 4b 22  c != "SQLITE_OK"
14c0: 7d 20 7b 20 65 72 72 6f 72 20 22 24 72 63 20 5b  } { error "$rc [
14d0: 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 20 24  sqlite3_errmsg $
14e0: 64 62 5d 22 20 7d 0a 20 20 20 20 72 65 74 75 72  db]" }.    retur
14f0: 6e 20 24 6c 52 65 73 0a 20 20 7d 0a 0a 20 20 69  n $lRes.  }..  i
1500: 66 20 7b 24 69 73 57 72 69 74 65 72 7d 20 7b 0a  f {$isWriter} {.
1510: 20 20 20 20 73 65 74 20 53 71 6c 20 7b 0a 20 20      set Sql {.  
1520: 20 20 20 20 42 45 47 49 4e 3b 0a 20 20 20 20 20      BEGIN;.     
1530: 20 20 20 44 45 4c 45 54 45 20 46 52 4f 4d 20 74     DELETE FROM t
1540: 31 20 57 48 45 52 45 20 61 20 3d 20 28 53 45 4c  1 WHERE a = (SEL
1550: 45 43 54 20 6d 61 78 28 61 29 20 46 52 4f 4d 20  ECT max(a) FROM 
1560: 74 31 29 3b 0a 20 20 20 20 20 20 20 20 49 4e 53  t1);.        INS
1570: 45 52 54 20 49 4e 54 4f 20 74 31 20 56 41 4c 55  ERT INTO t1 VALU
1580: 45 53 28 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  ES(NULL, NULL);.
1590: 20 20 20 20 20 20 20 20 55 50 44 41 54 45 20 74          UPDATE t
15a0: 31 20 53 45 54 20 62 20 3d 20 61 20 57 48 45 52  1 SET b = a WHER
15b0: 45 20 61 20 3d 20 28 53 45 4c 45 43 54 20 6d 61  E a = (SELECT ma
15c0: 78 28 61 29 20 46 52 4f 4d 20 74 31 29 3b 0a 20  x(a) FROM t1);. 
15d0: 20 20 20 20 20 20 20 53 45 4c 45 43 54 20 63 6f         SELECT co
15e0: 75 6e 74 28 2a 29 20 46 52 4f 4d 20 74 31 20 57  unt(*) FROM t1 W
15f0: 48 45 52 45 20 62 20 49 53 20 4e 55 4c 4c 3b 0a  HERE b IS NULL;.
1600: 20 20 20 20 20 20 43 4f 4d 4d 49 54 3b 0a 20 20        COMMIT;.  
1610: 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20    }.  } else {. 
1620: 20 20 20 73 65 74 20 53 71 6c 20 7b 0a 20 20 20     set Sql {.   
1630: 20 20 20 42 45 47 49 4e 3b 0a 20 20 20 20 20 20     BEGIN;.      
1640: 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20  SELECT count(*) 
1650: 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 62 20  FROM t1 WHERE b 
1660: 49 53 20 4e 55 4c 4c 3b 0a 20 20 20 20 20 20 43  IS NULL;.      C
1670: 4f 4d 4d 49 54 3b 0a 20 20 20 20 7d 0a 20 20 7d  OMMIT;.    }.  }
1680: 0a 0a 20 20 73 65 74 20 3a 3a 44 42 20 5b 73 71  ..  set ::DB [sq
1690: 6c 69 74 65 33 5f 6f 70 65 6e 20 74 65 73 74 2e  lite3_open test.
16a0: 64 62 5d 0a 0a 20 20 65 78 65 63 73 71 6c 20 7b  db]..  execsql {
16b0: 20 41 54 54 41 43 48 20 27 74 65 73 74 32 2e 64   ATTACH 'test2.d
16c0: 62 27 20 41 53 20 61 75 78 20 7d 0a 0a 20 20 73  b' AS aux }..  s
16d0: 65 74 20 72 65 73 75 6c 74 20 22 6f 6b 22 0a 20  et result "ok". 
16e0: 20 73 65 74 20 66 69 6e 69 73 68 20 5b 65 78 70   set finish [exp
16f0: 72 20 5b 63 6c 6f 63 6b 5f 73 65 63 6f 6e 64 73  r [clock_seconds
1700: 5d 2b 35 5d 0a 20 20 77 68 69 6c 65 20 7b 24 72  ]+5].  while {$r
1710: 65 73 75 6c 74 20 65 71 20 22 6f 6b 22 20 26 26  esult eq "ok" &&
1720: 20 5b 63 6c 6f 63 6b 5f 73 65 63 6f 6e 64 73 5d   [clock_seconds]
1730: 20 3c 20 24 66 69 6e 69 73 68 7d 20 7b 0a 20 20   < $finish} {.  
1740: 20 20 73 65 74 20 72 63 20 5b 63 61 74 63 68 20    set rc [catch 
1750: 7b 65 78 65 63 73 71 6c 20 24 53 71 6c 7d 20 6d  {execsql $Sql} m
1760: 73 67 5d 0a 20 20 20 20 69 66 20 7b 24 72 63 7d  sg].    if {$rc}
1770: 20 7b 0a 20 20 20 20 20 20 69 66 20 7b 5b 73 74   {.      if {[st
1780: 72 69 6e 67 20 6d 61 74 63 68 20 22 53 51 4c 49  ring match "SQLI
1790: 54 45 5f 4c 4f 43 4b 45 44 2a 22 20 24 6d 73 67  TE_LOCKED*" $msg
17a0: 5d 7d 20 7b 0a 20 20 20 20 20 20 20 20 63 61 74  ]} {.        cat
17b0: 63 68 20 7b 20 65 78 65 63 73 71 6c 20 52 4f 4c  ch { execsql ROL
17c0: 4c 42 41 43 4b 20 7d 0a 20 20 20 20 20 20 7d 20  LBACK }.      } 
17d0: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 73  else {.        s
17e0: 71 6c 69 74 65 33 5f 63 6c 6f 73 65 20 24 3a 3a  qlite3_close $::
17f0: 44 42 0a 20 20 20 20 20 20 20 20 65 72 72 6f 72  DB.        error
1800: 20 24 6d 73 67 0a 20 20 20 20 20 20 7d 0a 20 20   $msg.      }.  
1810: 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 6d 73 67    } elseif {$msg
1820: 20 6e 65 20 22 30 22 7d 20 7b 0a 20 20 20 20 20   ne "0"} {.     
1830: 20 73 65 74 20 72 65 73 75 6c 74 20 22 66 61 69   set result "fai
1840: 6c 65 64 22 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  led".    }.  }..
1850: 20 20 73 71 6c 69 74 65 33 5f 63 6c 6f 73 65 20    sqlite3_close 
1860: 24 3a 3a 44 42 0a 20 20 73 65 74 20 72 65 73 75  $::DB.  set resu
1870: 6c 74 0a 7d 0a 0a 23 20 54 68 65 72 65 20 69 73  lt.}..# There is
1880: 20 61 20 72 61 63 65 2d 63 6f 6e 64 69 74 69 6f   a race-conditio
1890: 6e 20 69 6e 20 62 74 72 65 65 2e 63 20 74 68 61  n in btree.c tha
18a0: 74 20 6d 65 61 6e 73 20 74 68 61 74 20 69 66 20  t means that if 
18b0: 74 77 6f 20 74 68 72 65 61 64 73 0a 23 20 61 74  two threads.# at
18c0: 74 65 6d 70 74 20 74 6f 20 6f 70 65 6e 20 74 68  tempt to open th
18d0: 65 20 73 61 6d 65 20 64 61 74 61 62 61 73 65 20  e same database 
18e0: 61 74 20 72 6f 75 67 68 6c 79 20 74 68 65 20 73  at roughly the s
18f0: 61 6d 65 20 74 69 6d 65 2c 20 61 6e 64 20 74 68  ame time, and th
1900: 65 72 65 0a 23 20 64 6f 65 73 20 6e 6f 74 20 61  ere.# does not a
1910: 6c 72 65 61 64 79 20 65 78 69 73 74 20 61 20 73  lready exist a s
1920: 68 61 72 65 64 2d 63 61 63 68 65 20 63 6f 72 72  hared-cache corr
1930: 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 74 68 61  esponding to tha
1940: 74 20 64 61 74 61 62 61 73 65 2c 0a 23 20 74 68  t database,.# th
1950: 65 6e 20 74 77 6f 20 73 68 61 72 65 64 2d 63 61  en two shared-ca
1960: 63 68 65 73 20 63 61 6e 20 62 65 20 63 72 65 61  ches can be crea
1970: 74 65 64 20 69 6e 73 74 65 61 64 20 6f 66 20 6f  ted instead of o
1980: 6e 65 2e 20 54 68 69 6e 67 73 20 73 74 69 6c 6c  ne. Things still
1990: 20 6d 6f 72 65 0a 23 20 6f 72 20 6c 65 73 73 20   more.# or less 
19a0: 77 6f 72 6b 2c 20 62 75 74 20 74 68 65 20 74 77  work, but the tw
19b0: 6f 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e 65  o database conne
19c0: 63 74 69 6f 6e 73 20 64 6f 20 6e 6f 74 20 75 73  ctions do not us
19d0: 65 20 74 68 65 20 73 61 6d 65 0a 23 20 73 68 61  e the same.# sha
19e0: 72 65 64 2d 63 61 63 68 65 2e 0a 23 0a 23 20 49  red-cache..#.# I
19f0: 66 20 74 68 65 20 74 68 72 65 61 64 73 20 72 75  f the threads ru
1a00: 6e 20 62 79 20 74 68 69 73 20 74 65 73 74 20 68  n by this test h
1a10: 69 74 20 74 68 69 73 20 72 61 63 65 2d 63 6f 6e  it this race-con
1a20: 64 69 74 69 6f 6e 2c 20 74 68 65 20 74 65 73 74  dition, the test
1a30: 73 0a 23 20 66 61 69 6c 20 28 62 65 63 61 75 73  s.# fail (becaus
1a40: 65 20 53 51 4c 49 54 45 5f 42 55 53 59 20 6d 61  e SQLITE_BUSY ma
1a50: 79 20 62 65 20 75 6e 65 78 70 65 63 74 65 64 6c  y be unexpectedl
1a60: 79 20 72 65 74 75 72 6e 65 64 20 69 6e 73 74 65  y returned inste
1a70: 61 64 20 6f 66 0a 23 20 53 51 4c 49 54 45 5f 4c  ad of.# SQLITE_L
1a80: 4f 43 4b 45 44 29 2e 20 54 6f 20 70 72 65 76 65  OCKED). To preve
1a90: 6e 74 20 74 68 69 73 20 66 72 6f 6d 20 68 61 70  nt this from hap
1aa0: 70 65 6e 69 6e 67 2c 20 6f 70 65 6e 20 61 20 63  pening, open a c
1ab0: 6f 75 70 6c 65 20 6f 66 0a 23 20 63 6f 6e 6e 65  ouple of.# conne
1ac0: 63 74 69 6f 6e 73 20 74 6f 20 74 65 73 74 2e 64  ctions to test.d
1ad0: 62 20 61 6e 64 20 74 65 73 74 32 2e 64 62 20 6e  b and test2.db n
1ae0: 6f 77 20 74 6f 20 6d 61 6b 65 20 73 75 72 65 20  ow to make sure 
1af0: 74 68 61 74 20 74 68 65 72 65 20 61 72 65 0a 23  that there are.#
1b00: 20 61 6c 72 65 61 64 79 20 73 68 61 72 65 64 2d   already shared-
1b10: 63 61 63 68 65 73 20 69 6e 20 6d 65 6d 6f 72 79  caches in memory
1b20: 20 66 6f 72 20 61 6c 6c 20 64 61 74 61 62 61 73   for all databas
1b30: 65 73 20 6f 70 65 6e 65 64 20 62 79 20 74 68 65  es opened by the
1b40: 0a 23 20 74 65 73 74 20 74 68 72 65 61 64 73 2e  .# test threads.
1b50: 0a 23 0a 73 71 6c 69 74 65 33 20 64 62 20 74 65  .#.sqlite3 db te
1b60: 73 74 2e 64 62 0a 73 71 6c 69 74 65 33 20 64 62  st.db.sqlite3 db
1b70: 20 74 65 73 74 32 2e 64 62 0a 0a 70 75 74 73 20   test2.db..puts 
1b80: 22 52 75 6e 6e 69 6e 67 20 74 68 72 65 61 64 2d  "Running thread-
1b90: 74 65 73 74 73 20 66 6f 72 20 7e 32 30 20 73 65  tests for ~20 se
1ba0: 63 6f 6e 64 73 22 0a 74 68 72 65 61 64 5f 73 70  conds".thread_sp
1bb0: 61 77 6e 20 66 69 6e 69 73 68 65 64 28 30 29 20  awn finished(0) 
1bc0: 7b 73 65 74 20 69 73 57 72 69 74 65 72 20 30 7d  {set isWriter 0}
1bd0: 20 24 54 68 72 65 61 64 50 72 6f 67 72 61 6d 0a   $ThreadProgram.
1be0: 74 68 72 65 61 64 5f 73 70 61 77 6e 20 66 69 6e  thread_spawn fin
1bf0: 69 73 68 65 64 28 31 29 20 7b 73 65 74 20 69 73  ished(1) {set is
1c00: 57 72 69 74 65 72 20 31 7d 20 24 54 68 72 65 61  Writer 1} $Threa
1c10: 64 50 72 6f 67 72 61 6d 0a 69 66 20 7b 21 5b 69  dProgram.if {![i
1c20: 6e 66 6f 20 65 78 69 73 74 73 20 66 69 6e 69 73  nfo exists finis
1c30: 68 65 64 28 30 29 5d 7d 20 7b 20 76 77 61 69 74  hed(0)]} { vwait
1c40: 20 66 69 6e 69 73 68 65 64 28 30 29 20 7d 0a 69   finished(0) }.i
1c50: 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74 73  f {![info exists
1c60: 20 66 69 6e 69 73 68 65 64 28 31 29 5d 7d 20 7b   finished(1)]} {
1c70: 20 76 77 61 69 74 20 66 69 6e 69 73 68 65 64 28   vwait finished(
1c80: 31 29 20 7d 0a 0a 63 61 74 63 68 20 7b 20 64 62  1) }..catch { db
1c90: 20 63 6c 6f 73 65 20 7d 0a 63 61 74 63 68 20 7b   close }.catch {
1ca0: 20 64 62 32 20 63 6c 6f 73 65 20 7d 0a 0a 64 6f   db2 close }..do
1cb0: 5f 74 65 73 74 20 74 68 72 65 61 64 30 30 35 2d  _test thread005-
1cc0: 32 2e 32 20 7b 0a 20 20 6c 69 73 74 20 24 66 69  2.2 {.  list $fi
1cd0: 6e 69 73 68 65 64 28 30 29 20 24 66 69 6e 69 73  nished(0) $finis
1ce0: 68 65 64 28 31 29 0a 7d 20 7b 6f 6b 20 6f 6b 7d  hed(1).} {ok ok}
1cf0: 0a 0a 64 6f 5f 74 65 73 74 20 74 68 72 65 61 64  ..do_test thread
1d00: 30 30 35 2d 32 2e 33 20 7b 0a 20 20 73 71 6c 69  005-2.3 {.  sqli
1d10: 74 65 33 20 64 62 20 74 65 73 74 2e 64 62 0a 20  te3 db test.db. 
1d20: 20 65 78 65 63 73 71 6c 20 7b 20 41 54 54 41 43   execsql { ATTAC
1d30: 48 20 27 74 65 73 74 32 2e 64 62 27 20 41 53 20  H 'test2.db' AS 
1d40: 61 75 78 20 7d 0a 20 20 65 78 65 63 73 71 6c 20  aux }.  execsql 
1d50: 7b 20 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a  { SELECT count(*
1d60: 29 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20  ) FROM t1 WHERE 
1d70: 62 20 49 53 20 4e 55 4c 4c 20 7d 0a 7d 20 7b 30  b IS NULL }.} {0
1d80: 7d 0a 0a 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c  }..sqlite3_enabl
1d90: 65 5f 73 68 61 72 65 64 5f 63 61 63 68 65 20 24  e_shared_cache $
1da0: 3a 3a 65 6e 61 62 6c 65 5f 73 68 61 72 65 64 5f  ::enable_shared_
1db0: 63 61 63 68 65 0a 66 69 6e 69 73 68 5f 74 65 73  cache.finish_tes
1dc0: 74 0a                                            t.