SQLite

Check-in [56e6fca1a9]
Login

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

Overview
Comment:Fix a problem in thread005.test cause errors on osx. (CVS 6362)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 56e6fca1a9da69c3a0fe43b00db9a6d9d93f03ba
User & Date: danielk1977 2009-03-20 10:24:04.000
Context
2009-03-20
13:15
Rename the unused MEM2 static mutex to OPEN and reuse it to serialize access to the sqlite3BtreeOpen() routine to prevent a race condition on detection of sharable caches. Ticket #3735. (CVS 6363) (check-in: 19fa5a29b9 user: drh tags: trunk)
10:24
Fix a problem in thread005.test cause errors on osx. (CVS 6362) (check-in: 56e6fca1a9 user: danielk1977 tags: trunk)
09:09
Fix a problem in loadext.test causing an error on OSX. This is not a real problem, just a case of the test script expecting a slightly different error message than the one returned. (CVS 6361) (check-in: 18680989b5 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to test/thread005.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2009 March 11
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    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.2 2009/03/16 17:07:57 drh Exp $

set testdir [file dirname $argv0]

source $testdir/tester.tcl
ifcapable !mutex||!shared_cache {
  return
}













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2009 March 11
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    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
}
88
89
90
91
92
93
94

95
96
97
98
99
100
101
  execsql {
    CREATE TABLE aux.t1(a INTEGER PRIMARY KEY, b UNIQUE);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t1 VALUES(2, 2);
  }
  db close
} {}


set ThreadProgram {
  proc execsql {zSql {db {}}} {
    if {$db eq ""} {set db $::DB}

    set lRes [list]
    set rc SQLITE_OK







>







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  execsql {
    CREATE TABLE aux.t1(a INTEGER PRIMARY KEY, b UNIQUE);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t1 VALUES(2, 2);
  }
  db close
} {}


set ThreadProgram {
  proc execsql {zSql {db {}}} {
    if {$db eq ""} {set db $::DB}

    set lRes [list]
    set rc SQLITE_OK
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155

















156
157
158
159
160
161
162



163
164
165
166
167
168
169
170
171
172
173
174
  set finish [expr [clock_seconds]+5]
  while {$result eq "ok" && [clock_seconds] < $finish} {
    set rc [catch {execsql $Sql} msg]
    if {$rc} {
      if {[string match "SQLITE_LOCKED*" $msg]} {
        catch { execsql ROLLBACK }
      } else {

        error $msg
      }
    } elseif {$msg ne "0"} {
      set result "failed"
    }
  }

  sqlite3_close $::DB
  set result
}


















puts "Running thread-tests for ~20 seconds"
thread_spawn finished(0) {set isWriter 0} $ThreadProgram
thread_spawn finished(1) {set isWriter 1} $ThreadProgram
if {![info exists finished(0)]} { vwait finished(0) }
if {![info exists finished(1)]} { vwait finished(1) }




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







>










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







>
>
>












140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  set finish [expr [clock_seconds]+5]
  while {$result eq "ok" && [clock_seconds] < $finish} {
    set rc [catch {execsql $Sql} msg]
    if {$rc} {
      if {[string match "SQLITE_LOCKED*" $msg]} {
        catch { execsql ROLLBACK }
      } else {
        sqlite3_close $::DB
        error $msg
      }
    } elseif {$msg ne "0"} {
      set result "failed"
    }
  }

  sqlite3_close $::DB
  set result
}

# There is a race-condition in btree.c that means that if two threads
# attempt to open the same database at roughly the same time, and there
# does not already exist a shared-cache corresponding to that database,
# then two shared-caches can be created instead of one. Things still more
# or less work, but the two database connections do not use the same
# shared-cache.
#
# If the threads run by this test hit this race-condition, the tests
# fail (because SQLITE_BUSY may be unexpectedly returned instead of
# SQLITE_LOCKED). To prevent this from happening, open a couple of
# connections to test.db and test2.db now to make sure that there are
# already shared-caches in memory for all databases opened by the
# test threads.
#
sqlite3 db test.db
sqlite3 db test2.db

puts "Running thread-tests for ~20 seconds"
thread_spawn finished(0) {set isWriter 0} $ThreadProgram
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