Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Make sure mutexes are fully enabled for thread001.test. Take steps to ensure that the thread tests run during regression testing. (CVS 6193) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6242f113eb40d472b78685c296fecf9f |
User & Date: | drh 2009-01-19 17:40:12 |
Context
2009-01-19
| ||
18:18 | Fix the --enable-tempstore option on the configure script. Ticket #3599 (CVS 6194) check-in: c2eabb99 user: drh tags: trunk | |
17:40 | Make sure mutexes are fully enabled for thread001.test. Take steps to ensure that the thread tests run during regression testing. (CVS 6193) check-in: 6242f113 user: drh tags: trunk | |
2009-01-17
| ||
16:59 | Fix a bug that was preventing SQLite from releasing locks properly under obscure circumstances. (CVS 6192) check-in: 502c66df user: danielk1977 tags: trunk | |
Changes
Changes to src/test1.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.342 2009/01/10 13:24:51 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* ................................................................................ #define StmtToDb(X) sqlite3_db_handle(X) /* ** Check a return value to make sure it agrees with the results ** from sqlite3_errcode. */ int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){ char zBuf[200]; int r2 = sqlite3_errcode(db); sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", t1ErrorName(rc), rc, t1ErrorName(r2), r2); Tcl_ResetResult(interp); Tcl_AppendResult(interp, zBuf, 0); return 1; |
|
>
|
|
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.343 2009/01/19 17:40:12 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* ................................................................................ #define StmtToDb(X) sqlite3_db_handle(X) /* ** Check a return value to make sure it agrees with the results ** from sqlite3_errcode. */ int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ if( sqlite3_threadsafe()==0 && rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){ char zBuf[200]; int r2 = sqlite3_errcode(db); sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", t1ErrorName(rc), rc, t1ErrorName(r2), r2); Tcl_ResetResult(interp); Tcl_AppendResult(interp, zBuf, 0); return 1; |
Changes to src/test_mutex.c.
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
** ** 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. ** ************************************************************************* ** ** $Id: test_mutex.c,v 1.12 2008/11/04 14:55:47 danielk1977 Exp $ */ #include "tcl.h" #include "sqlite3.h" #include "sqliteInt.h" #include <stdlib.h> #include <assert.h> ................................................................................ return TCL_OK; } static sqlite3 *getDbPointer(Tcl_Interp *pInterp, Tcl_Obj *pObj){ sqlite3 *db; Tcl_CmdInfo info; char *zCmd = Tcl_GetString(pObj); if( 1!=Tcl_GetCommandInfo(pInterp, zCmd, &info) ){ Tcl_AppendResult(pInterp, "No such db-handle: \"", zCmd, "\"", 0); return 0; } db = *((sqlite3 **)info.objClientData); assert( db ); return db; } static int test_enter_db_mutex( void * clientData, Tcl_Interp *interp, |
|
|
|
|
>
<
|
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
** ** 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. ** ************************************************************************* ** ** $Id: test_mutex.c,v 1.13 2009/01/19 17:40:12 drh Exp $ */ #include "tcl.h" #include "sqlite3.h" #include "sqliteInt.h" #include <stdlib.h> #include <assert.h> ................................................................................ return TCL_OK; } static sqlite3 *getDbPointer(Tcl_Interp *pInterp, Tcl_Obj *pObj){ sqlite3 *db; Tcl_CmdInfo info; char *zCmd = Tcl_GetString(pObj); if( Tcl_GetCommandInfo(pInterp, zCmd, &info) ){ db = *((sqlite3 **)info.objClientData); }else{ db = (sqlite3*)sqlite3TestTextToPtr(zCmd); } assert( db ); return db; } static int test_enter_db_mutex( void * clientData, Tcl_Interp *interp, |
Changes to src/test_thread.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
** ************************************************************************* ** ** This file contains the implementation of some Tcl commands used to ** test that sqlite3 database handles may be concurrently accessed by ** multiple threads. Right now this only works on unix. ** ** $Id: test_thread.c,v 1.8 2008/08/28 13:55:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include <tcl.h> #if SQLITE_THREADSAFE && defined(TCL_THREADS) #include <errno.h> #include <unistd.h> /* ** One of these is allocated for each thread created by [sqlthread spawn]. */ ................................................................................ ** The main function for threads created with [sqlthread spawn]. */ static Tcl_ThreadCreateType tclScriptThread(ClientData pSqlThread){ Tcl_Interp *interp; Tcl_Obj *pRes; Tcl_Obj *pList; int rc; SqlThread *p = (SqlThread *)pSqlThread; interp = Tcl_CreateInterp(); Tcl_CreateObjCommand(interp, "clock_seconds", clock_seconds_proc, 0, 0); Tcl_CreateObjCommand(interp, "sqlthread", sqlthread_proc, pSqlThread, 0); Sqlitetest1_Init(interp); rc = Tcl_Eval(interp, p->zScript); pRes = Tcl_GetObjResult(interp); pList = Tcl_NewObj(); Tcl_IncrRefCount(pList); Tcl_IncrRefCount(pRes); |
|
|
<
>
>
|
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
** ************************************************************************* ** ** This file contains the implementation of some Tcl commands used to ** test that sqlite3 database handles may be concurrently accessed by ** multiple threads. Right now this only works on unix. ** ** $Id: test_thread.c,v 1.9 2009/01/19 17:40:12 drh Exp $ */ #include "sqliteInt.h" #include <tcl.h> #if SQLITE_THREADSAFE #include <errno.h> #include <unistd.h> /* ** One of these is allocated for each thread created by [sqlthread spawn]. */ ................................................................................ ** The main function for threads created with [sqlthread spawn]. */ static Tcl_ThreadCreateType tclScriptThread(ClientData pSqlThread){ Tcl_Interp *interp; Tcl_Obj *pRes; Tcl_Obj *pList; int rc; SqlThread *p = (SqlThread *)pSqlThread; extern int Sqlitetest_mutex_Init(Tcl_Interp*); interp = Tcl_CreateInterp(); Tcl_CreateObjCommand(interp, "clock_seconds", clock_seconds_proc, 0, 0); Tcl_CreateObjCommand(interp, "sqlthread", sqlthread_proc, pSqlThread, 0); Sqlitetest1_Init(interp); Sqlitetest_mutex_Init(interp); rc = Tcl_Eval(interp, p->zScript); pRes = Tcl_GetObjResult(interp); pList = Tcl_NewObj(); Tcl_IncrRefCount(pList); Tcl_IncrRefCount(pRes); |
Changes to test/thread001.test.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 25 26 27 28 29 30 31 32 33 34 35 36 37 38 .. 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 .. 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 .. 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# # 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. # #*********************************************************************** # # $Id: thread001.test,v 1.6 2008/10/07 15:25:49 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !mutex { return } ................................................................................ set ::NTHREAD 10 # Run this test three times: # # 1) All threads use the same database handle. # 2) All threads use their own database handles. # 3) All threads use their own database handles, shared-cache is enabled. # foreach {tn same_db shared_cache} [list \ 1 1 0 \ 2 0 0 \ 3 0 1 \ ] { # Empty the database. ................................................................................ catchsql { DROP TABLE ab; } do_test thread001.$tn.0 { db close sqlite3_enable_shared_cache $shared_cache sqlite3_enable_shared_cache $shared_cache } $shared_cache sqlite3 db test.db set dbconfig "" if {$same_db} { set dbconfig [list set ::DB [sqlite3_connection_pointer db]] } # Set up a database and a schema. The database contains a single ................................................................................ (SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) == (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab)) } } {1} do_test thread001.$tn.3 { execsql { PRAGMA integrity_check } } {ok} set thread_program { set needToClose 0 if {![info exists ::DB]} { set ::DB [sqlthread open test.db] set needToClose 1 } for {set i 0} {$i < 100} {incr i} { # Test that the invariant is true. do_test t1 { execsql { ................................................................................ } {1} # Add another row to the database. execsql { INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab } } if {$needToClose} { sqlite3_close $::DB } list OK } # Kick off $::NTHREAD threads: # array unset finished |
| > > | | > > > > |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 .. 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 .. 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 .. 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# # 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. # #*********************************************************************** # # $Id: thread001.test,v 1.7 2009/01/19 17:40:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !mutex { return } ................................................................................ set ::NTHREAD 10 # Run this test three times: # # 1) All threads use the same database handle. # 2) All threads use their own database handles. # 3) All threads use their own database handles, shared-cache is enabled. # # # foreach {tn same_db shared_cache} [list \ 1 1 0 \ 2 0 0 \ 3 0 1 \ ] { # Empty the database. ................................................................................ catchsql { DROP TABLE ab; } do_test thread001.$tn.0 { db close sqlite3_enable_shared_cache $shared_cache sqlite3_enable_shared_cache $shared_cache } $shared_cache sqlite3 db test.db -fullmutex 1 set dbconfig "" if {$same_db} { set dbconfig [list set ::DB [sqlite3_connection_pointer db]] } # Set up a database and a schema. The database contains a single ................................................................................ (SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) == (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab)) } } {1} do_test thread001.$tn.3 { execsql { PRAGMA integrity_check } } {ok} set thread_program { #sqlthread parent {puts STARTING..} set needToClose 0 if {![info exists ::DB]} { set ::DB [sqlthread open test.db] #sqlthread parent "puts \"OPEN $::DB\"" set needToClose 1 } for {set i 0} {$i < 100} {incr i} { # Test that the invariant is true. do_test t1 { execsql { ................................................................................ } {1} # Add another row to the database. execsql { INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab } } if {$needToClose} { #sqlthread parent "puts \"CLOSE $::DB\"" sqlite3_close $::DB } #sqlthread parent "puts \"DONE\"" list OK } # Kick off $::NTHREAD threads: # array unset finished |
Changes to test/thread_common.tcl.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 33 34 35 36 37 38 39 40 41 42 43 44 45 46 .. 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# # 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. # #*********************************************************************** # # $Id: thread_common.tcl,v 1.2 2007/09/10 10:53:02 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {[info commands sqlthread] eq ""} { puts -nonewline "Skipping thread-safety tests - " puts " not running a threadsafe sqlite/tcl build" ................................................................................ set rc SQLITE_LOCKED while {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY" || $rc eq "SQLITE_SCHEMA"} { set res [list] set err [catch { set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 dummy_tail] } msg] if {$err == 0} { while {[set rc [sqlite3_step $::STMT]] eq "SQLITE_ROW"} { for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} { ................................................................................ set rc SQLITE_ERROR } } if {[string first locked [sqlite3_errmsg $::DB]]>=0} { set rc SQLITE_LOCKED } if {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY"} { #puts -nonewline "([sqlthread id] $rc)" #flush stdout after 20 } } if {$rc ne "SQLITE_OK"} { error "$rc - [sqlite3_errmsg $::DB]" } set res } proc do_test {name script result} { set res [eval $script] if {$res ne $result} { |
| > > > | > > < < > | > > | |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .. 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 .. 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 82 83 84 |
# # 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. # #*********************************************************************** # # $Id: thread_common.tcl,v 1.3 2009/01/19 17:40:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {[info commands sqlthread] eq ""} { puts -nonewline "Skipping thread-safety tests - " puts " not running a threadsafe sqlite/tcl build" ................................................................................ set rc SQLITE_LOCKED while {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY" || $rc eq "SQLITE_SCHEMA"} { set res [list] enter_db_mutex $::DB set err [catch { set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 dummy_tail] } msg] if {$err == 0} { while {[set rc [sqlite3_step $::STMT]] eq "SQLITE_ROW"} { for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} { ................................................................................ set rc SQLITE_ERROR } } if {[string first locked [sqlite3_errmsg $::DB]]>=0} { set rc SQLITE_LOCKED } if {$rc ne "SQLITE_OK"} { set errtxt "$rc - [sqlite3_errmsg $::DB] (debug1)" } leave_db_mutex $::DB if {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY"} { #sqlthread parent "puts \"thread [sqlthread id] is busy. rc=$rc\"" after 200 } else { #sqlthread parent "puts \"thread [sqlthread id] ran $sql\"" } } if {$rc ne "SQLITE_OK"} { error $errtxt } set res } proc do_test {name script result} { set res [eval $script] if {$res ne $result} { |