SQLite version 3.7.4 with TEA. gcc was run like this:
gcc -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\"
-DPACKAGE_VERSION=\"3.7.4\" -DPACKAGE_STRING=\"sqlite\ 3.7.4\"
-DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1
-DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1
-DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1
-DHAVE_LIMITS_H=1 -DHAVE_SYS_PARAM_H=1 -DUSE_THREAD_ALLOC=1 -D_REENTRANT=1
-D_THREAD_SAFE=1 -DTCL_THREADS=1 -DSQLITE_THREADSAFE=1 -DMODULE_SCOPE=extern\
__attribute__\(\(__visibility__\(\"hidden\"\)\)\) -D_LARGEFILE64_SOURCE=1
-DTCL_WIDE_INT_TYPE=long\ long -DHAVE_STRUCT_STAT64=1 -DHAVE_OPEN64=1
-DHAVE_LSEEK64=1 -DHAVE_TYPE_OFF64_T=1 -DUSE_TCL_STUBS=1 -DSQLITE_ENABLE_FTS3=1
-I"./generic" -I"/home/eas/tcl8.5.9/generic" -pipe -O0 -g -Wall -fPIC -c
`echo ./generic/tclsqlite3.c` -o tclsqlite3.o
(All those parameters were auto-generated by 'configure' except -O0,
which I changed from the default -O2.)
$ uname -a
Linux hudson 2.6.32.26-175.fc12.i686 #1 SMP Wed Dec 1 21:52:04 UTC 2010 i686
athlon i386 GNU/Linux
I register a Tcl busy handler that fails to be called when a connection
attempts to escalate its lock status. This may also indicate a bug
in the C API as well.
Steps to reproduce:
1. Write the following script into a file named 'foo.tcl':
===
#!/usr/bin/tclsh
load sqlite-tea-3070400/libsqlite3.7.4.so
proc ::busy {ntries} {
puts stderr "[pid] finds the db busy, ntries=$ntries. try again."
after 1
return 0
}
if {[catch {
puts stderr "[pid] hello, world"
sqlite3 db /tmp/foo.db
db busy ::busy
db eval begin
db eval {create table if not exists t(a)}
db eval commit
db eval begin
db eval {select count(*) from t}
db eval {insert into t values(100)}
after 1000
db eval commit
puts stderr "[pid] exits successfully"
}]} {
puts stderr "[pid] error in script: $::errorInfo"
}
===
2. Make sure that the 'load' command above will work by changing the path
name as appropriate.
3. Make sure /tmp is a normal filesystem and the file 'foo.db' does not
exist there, e.g. as the remnant of some previous debugging exercise.
4. Make the script executable:
$ chmod +x ./foo.tcl
5. Run the script twice in parallel:
$ ./foo.tcl & ./foo.tcl
Expected result:
Both scripts indicate that they have completed successfully by
printing "<PID> exits successfully". This is because we expect
for the busy handler to be called when the database is locked,
and the busy handler always return 0, indicating that SQLite
should keep retrying until successful.
Actual result:
In almost every test run, neither instance never enters ::busy.
Instead, I get the following output:
[hudson:~] $ ./foo.tcl & ./foo.tcl
[1] 15308
15309 hello, world
15308 hello, world
15308 error in script: database is locked
while executing
"db eval {insert into t values(100)}"
15309 exits successfully
I say "almost almost every test run" because if I remove that
'after 1000' line, sometimes the script fails like this and sometimes
it doesn't. Adding the 'after' line increases the failure frequency to
nearly 100%, probably because the "winning" process is holding a certain
flavor of lock for longer.
Please let me know if you need more information.
Eric
--
Eric A. Smith
Electricity is actually made up of extremely tiny particles
called electrons, that you cannot see with the naked eye unless
you have been drinking.
-- Dave Barry
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users