/ Check-in [4310411f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add a test to try to hit the race-condition fixed by (6363). (CVS 6366)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4310411f5027dba18e017023e21cb09982e26752
User & Date: danielk1977 2009-03-20 15:16:06
Context
2009-03-21
14:41
On unix, always use fdatasync() instead of fsync() when available, even if the file size changes, since (we are told) fdatasync() will automatically flush the inode when the file size changes. (CVS 6367) check-in: 0d6b11bc user: drh tags: trunk
2009-03-20
15:16
Add a test to try to hit the race-condition fixed by (6363). (CVS 6366) check-in: 4310411f user: danielk1977 tags: trunk
14:42
Fix an assert failure introduced by (6355). (CVS 6365) check-in: a08324d1 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to test/thread005.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

















































26
27
28
29
30
31
32
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test a race-condition that shows up in shared-cache mode.
#
# $Id: thread005.test,v 1.3 2009/03/20 10:24:04 danielk1977 Exp $

set testdir [file dirname $argv0]

source $testdir/tester.tcl
ifcapable !mutex||!shared_cache {
  return
}
source $testdir/thread_common.tcl
if {[info commands sqlthread] eq ""} {
  return
}


















































#-------------------------------------------------------------------------
# This test tries to exercise a race-condition that existed in shared-cache
# mode at one point. The test uses two threads; each has a database connection
# open on the same shared cache. The schema of the database is:
#
#    CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
................................................................................
# when using an ATTACHed database. There doesn't seem to be any reason
# for this, other than that operating on an ATTACHed database means there
# are a few more mutex grabs and releases during the window of time open
# for the race-condition. Maybe this encourages the scheduler to context
# switch or something...
#

# Use shared-cache mode for this test.
# 
db close
set ::enable_shared_cache [sqlite3_enable_shared_cache]
sqlite3_enable_shared_cache 1

file delete -force test.db test2.db
unset -nocomplain finished

do_test thread005-1.1 {
  sqlite3 db test.db
  execsql { ATTACH 'test2.db' AS aux }
  execsql {
    CREATE TABLE aux.t1(a INTEGER PRIMARY KEY, b UNIQUE);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t1 VALUES(2, 2);
  }
................................................................................
thread_spawn finished(1) {set isWriter 1} $ThreadProgram
if {![info exists finished(0)]} { vwait finished(0) }
if {![info exists finished(1)]} { vwait finished(1) }

catch { db close }
catch { db2 close }

do_test thread005-1.2 {
  list $finished(0) $finished(1)
} {ok ok}

do_test thread005-1.3 {
  sqlite3 db test.db
  execsql { ATTACH 'test2.db' AS aux }
  execsql { SELECT count(*) FROM t1 WHERE b IS NULL }
} {0}

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test







|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<



|







 







|



|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
...
118
119
120
121
122
123
124






125
126
127
128
129
130
131
132
133
134
135
...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test a race-condition that shows up in shared-cache mode.
#
# $Id: thread005.test,v 1.4 2009/03/20 15:16:06 danielk1977 Exp $

set testdir [file dirname $argv0]

source $testdir/tester.tcl
ifcapable !mutex||!shared_cache {
  return
}
source $testdir/thread_common.tcl
if {[info commands sqlthread] eq ""} {
  return
}
db close

# Use shared-cache mode for these tests.
# 
set ::enable_shared_cache [sqlite3_enable_shared_cache]
sqlite3_enable_shared_cache 1

#-------------------------------------------------------------------------
# This test attempts to hit the race condition fixed by commit [6363].
#
proc runsql {zSql {db {}}} {
  set rc SQLITE_OK
  while {$rc=="SQLITE_OK" && $zSql ne ""} {
    set STMT [sqlite3_prepare_v2 $db $zSql -1 zSql]
    while {[set rc [sqlite3_step $STMT]] eq "SQLITE_ROW"} { }
    set rc [sqlite3_finalize $STMT]
  }
  return $rc
}
do_test thread005-1.1 {
  sqlite3 db test.db
  db eval { CREATE TABLE t1(a, b) }
  db close
} {}
for {set ii 2} {$ii < 500} {incr ii} {
  unset -nocomplain finished
  thread_spawn finished(0) {sqlite3_open test.db}
  thread_spawn finished(1) {sqlite3_open test.db}
  if {![info exists finished(0)]} { vwait finished(0) }
  if {![info exists finished(1)]} { vwait finished(1) }

  do_test thread005-1.$ii {
    runsql { BEGIN }                       $finished(0)
    runsql { INSERT INTO t1 VALUES(1, 2) } $finished(0)

    # If the race-condition was hit, then $finished(0 and $finished(1)
    # will not use the same pager cache. In this case the next statement
    # can be executed succesfully. However, if the race-condition is not
    # hit, then $finished(1) will be blocked by the write-lock held by 
    # $finished(0) on the shared-cache table t1 and the statement will
    # return SQLITE_LOCKED.
    #
    runsql { SELECT * FROM t1 }            $finished(1)
  } {SQLITE_LOCKED}

  sqlite3_close $finished(0)
  sqlite3_close $finished(1)
}


#-------------------------------------------------------------------------
# This test tries to exercise a race-condition that existed in shared-cache
# mode at one point. The test uses two threads; each has a database connection
# open on the same shared cache. The schema of the database is:
#
#    CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
................................................................................
# when using an ATTACHed database. There doesn't seem to be any reason
# for this, other than that operating on an ATTACHed database means there
# are a few more mutex grabs and releases during the window of time open
# for the race-condition. Maybe this encourages the scheduler to context
# switch or something...
#







file delete -force test.db test2.db
unset -nocomplain finished

do_test thread005-2.1 {
  sqlite3 db test.db
  execsql { ATTACH 'test2.db' AS aux }
  execsql {
    CREATE TABLE aux.t1(a INTEGER PRIMARY KEY, b UNIQUE);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t1 VALUES(2, 2);
  }
................................................................................
thread_spawn finished(1) {set isWriter 1} $ThreadProgram
if {![info exists finished(0)]} { vwait finished(0) }
if {![info exists finished(1)]} { vwait finished(1) }

catch { db close }
catch { db2 close }

do_test thread005-2.2 {
  list $finished(0) $finished(1)
} {ok ok}

do_test thread005-2.3 {
  sqlite3 db test.db
  execsql { ATTACH 'test2.db' AS aux }
  execsql { SELECT count(*) FROM t1 WHERE b IS NULL }
} {0}

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test