Hi, If I send signals to a process that is running an sqlite query on a DB in WAL mode I get an SQLITE_BUSY error. I did set a busy handler, and the timeout hasn't elapsed yet, so it appears that EINTR is treated as an error and not retried, although I haven't tracked down exactly where. I noticed that unixFileLock doesn't handle EINTR though.
Testcase for SQLite 3.8.2 on Linux amd64: $ gcc eintr.c -lsqlite3 -o eintr && ./eintr Query 'INSERT INTO tbl(x) VALUES(3)' failed: database is locked [after 0.025 sec] ^^^ expected to see >20s here. #include <stdio.h> #include <sqlite3.h> #include <unistd.h> #include <stdlib.h> #include <sys/time.h> #include <sys/signal.h> static int run(sqlite3 *db, const char *sql) { struct timeval tv0, tv1; char *errmsg = NULL; gettimeofday(&tv0, NULL); /* should use prepared statements for speed, but this is just for a testcase */ if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) { gettimeofday(&tv1, NULL); double dt = tv1.tv_sec - tv0.tv_sec + (tv1.tv_usec - tv0.tv_usec)/1000000.0; fprintf(stderr,"Query '%s' failed: %s [after %.3f sec]\n", sql, errmsg, dt); sqlite3_free(errmsg); return -1; } return 0; } static void handler(int sig) { } int main(int argc, char *argv[]) { sqlite3 *db = NULL; char *errmsg = NULL; int ret = 1; pid_t parent, pid; struct timeval tv0, tv1; signal(SIGUSR2, handler); parent = getpid(); pid = fork(); if (pid < 0) { perror("fork failed"); return 2; } if (!pid) { gettimeofday(&tv0, NULL); /* child */ for(;;) { /* if you comment out the kill() line, then the queries fail showing >20s wait times */ kill(parent, SIGUSR2); usleep(50); gettimeofday(&tv1, NULL); if ((tv1.tv_sec - tv0.tv_sec) * 1000 + (tv1.tv_usec - tv0.tv_usec)/1000 > 5000) break; } exit(0); } pid = fork(); do { int i; if (sqlite3_open_v2("test.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) { fprintf(stderr,"failed to open DB: %s", sqlite3_errmsg(db)); break; } sqlite3_busy_timeout(db, 20000); if (run(db, "CREATE TABLE IF NOT EXISTS tbl(x INTEGER)")) break; if (run(db, "PRAGMA journal_mode=WAL")) break; if (run(db, "PRAGMA synchronous=normal")) break; for (i=0;i<1000;i++) { if (run(db, "INSERT INTO tbl(x) VALUES(3)")) break; if (run(db, "UPDATE tbl set x = x+1")) break; } if (i == 1000) ret = 0; } while(0); if (sqlite3_close(db)) { fprintf(stderr,"Failed to close DB"); ret = 1; } return ret; } P.S: thank you for the quick fix for sqlite3_randomness! _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users