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 sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users