1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Add the sqlite3_setlk_timeout() API. For setting the timeout used by SQLITE_ENABLE_SETLK_TIMEOUT blocking locks without also setting the regular retry-based busy-timeout.

FossilOrigin-Name: 4a7eb492797abb47b18b7dfc557aeae43a0dea5b861efc203398d5059b10d131
This commit is contained in:
dan
2025-01-27 11:50:03 +00:00
parent 2539fb2bc5
commit 43aad25b1b
8 changed files with 164 additions and 13 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sa\srace\scondition\scausing\sSQLite\sto\suse\sa\sbusy-handler\sfor\san\soperation\sthat\sshould\snot. C Add\sthe\ssqlite3_setlk_timeout()\sAPI.\sFor\ssetting\sthe\stimeout\sused\sby\sSQLITE_ENABLE_SETLK_TIMEOUT\sblocking\slocks\swithout\salso\ssetting\sthe\sregular\sretry-based\sbusy-timeout.
D 2025-01-24T15:49:47.933 D 2025-01-27T11:50:03.268
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -740,7 +740,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c a19dc8b47760ed95f3fbb255cfa8d3f7146b33c263eb4af05ab05e0115d161b9 F src/main.c 101ea590be76fda296d12e6d8d1e9cc24f350b83cbf53e68b4f04484b90452a4
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -779,16 +779,16 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e
F src/shell.c.in ee54de10e9bd5572f689a6bc0c8e6fa58a8870e1670978ded44412d2715fd908 F src/shell.c.in ee54de10e9bd5572f689a6bc0c8e6fa58a8870e1670978ded44412d2715fd908
F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite.h.in ae301ce156765e2601695375dfc787a53b844a2f1c5d359bb667b081d1b7d2e0
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 3f20dfb5ae54e787b2643edc0b5bae0cecddfb89988e28afdc3c0b05892e25cc F src/sqliteInt.h ff8e68e74a61b4bf676d1a9503be2e6c2bc92699ec358bb5e201b1a466f1aa8e
F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523 F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07 F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07
F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
F src/test1.c bed72f092f9aaebf50ee4919a02a26ab99a4f378ab334cb93d77e8adb82e4b77 F src/test1.c 64df9d5ad54521eb3c103f1253bf33ceddbc5fa931658d3701027a2ac86eb5e9
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
@@ -858,7 +858,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422 F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 97c96c4eab27a409d2c710d8977a6b4917aebced14db2d63a451e9ca7b1f69bd F src/wal.c 20550245b9a82f94736e905ee7df8f549e1301ba40e9f2cb51139e36d49c3c0f
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 9ad3dea8003a8913da6a4ca8322e2fe30773f46e88a0d4fbf9db13bdb999efa2 F src/where.c 9ad3dea8003a8913da6a4ca8322e2fe30773f46e88a0d4fbf9db13bdb999efa2
@@ -2022,7 +2022,7 @@ F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68 F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b
F test/walsetlk.test 9c5b92f9a20252540fedf9ffa6ee3d1b8af08ea4b80d0144d9b88e6c0c1de80d F test/walsetlk.test 9c5b92f9a20252540fedf9ffa6ee3d1b8af08ea4b80d0144d9b88e6c0c1de80d
F test/walsetlk2.test f32134c673e207e5af3c888448f925d1f92c250bb367f0e5a76e4bce9d56f0af F test/walsetlk2.test e80cac17de166d5c8e4e0d243452798431aceb76a0abc95bfdd09d718d7c3f3f
F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3
F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
@@ -2203,8 +2203,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P daefcafe799ad7613cbdff1fb1e9d40659892906875b28fbc112abd7679e48ea P 6ab9ed8eef77781898375038ab05fc6e5f46b745e4906691393b8b1d90570eb6
R a5b314ee32b527d33bb7a6211f7b128a R 7026d025d771964056775817385cabe6
U dan U dan
Z 09f6f131877fb88e3c0a6b91e64a67d2 Z d459230a6d531f1d8e43a532fde898d2
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
6ab9ed8eef77781898375038ab05fc6e5f46b745e4906691393b8b1d90570eb6 4a7eb492797abb47b18b7dfc557aeae43a0dea5b861efc203398d5059b10d131

View File

@@ -1766,6 +1766,9 @@ int sqlite3_busy_handler(
db->busyHandler.pBusyArg = pArg; db->busyHandler.pBusyArg = pArg;
db->busyHandler.nBusy = 0; db->busyHandler.nBusy = 0;
db->busyTimeout = 0; db->busyTimeout = 0;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
db->setlkTimeout = 0;
#endif
sqlite3_mutex_leave(db->mutex); sqlite3_mutex_leave(db->mutex);
return SQLITE_OK; return SQLITE_OK;
} }
@@ -1815,12 +1818,25 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
(void*)db); (void*)db);
db->busyTimeout = ms; db->busyTimeout = ms;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
db->setlkTimeout = ms;
#endif
}else{ }else{
sqlite3_busy_handler(db, 0, 0); sqlite3_busy_handler(db, 0, 0);
} }
return SQLITE_OK; return SQLITE_OK;
} }
int sqlite3_setlk_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
db->setlkTimeout = (ms>0 ? ms : 0);
#endif
return SQLITE_OK;
}
/* /*
** Cause any pending operation to stop at its earliest opportunity. ** Cause any pending operation to stop at its earliest opportunity.
*/ */

View File

@@ -2899,6 +2899,30 @@ int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
*/ */
int sqlite3_busy_timeout(sqlite3*, int ms); int sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Set the Setlk Timeout
** METHOD: sqlite3
**
** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If
** the VFS supports blocking locks, it sets the timeout in ms used by
** eligible locks taken on wal mode databases by the specified database
** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does
** not support blocking locks, this function is a no-op.
**
** Passing 0x7FFFFFFF to this function is interpreted by some VFS as "block
** indefinitely". Passing zero or less than zero disables blocking locks
** altogether.
**
** Internally, each SQLite database handle store two timeout values - the
** busy-timeout (used for rollback mode databases, or if the VFS does not
** support blocking locks) and the setlk-timeout (used for blocking locks
** on wal-mode databases). The sqlite3_busy_timeout() method sets both
** values, this function sets only the setlk-timeout value. Therefore,
** to configure separate busy-timeout and setlk-timeout values for a single
** database handle, call sqlite3_busy_timeout() followed by this function.
*/
int sqlite3_setlk_timeout(sqlite3*, int ms);
/* /*
** CAPI3REF: Convenience Routines For Running Queries ** CAPI3REF: Convenience Routines For Running Queries
** METHOD: sqlite3 ** METHOD: sqlite3

View File

@@ -1744,6 +1744,9 @@ struct sqlite3 {
Savepoint *pSavepoint; /* List of active savepoints */ Savepoint *pSavepoint; /* List of active savepoints */
int nAnalysisLimit; /* Number of index rows to ANALYZE */ int nAnalysisLimit; /* Number of index rows to ANALYZE */
int busyTimeout; /* Busy handler timeout, in msec */ int busyTimeout; /* Busy handler timeout, in msec */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int setlkTimeout; /* Blocking lock timeout, in msec */
#endif
int nSavepoint; /* Number of non-transaction savepoints */ int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */ int nStatement; /* Number of nested statement-transactions */
i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredCons; /* Net deferred constraints this transaction. */

View File

@@ -5939,6 +5939,31 @@ static int SQLITE_TCLAPI test_busy_timeout(
return TCL_OK; return TCL_OK;
} }
/*
** Usage: sqlite3_setlk_timeout DB MS
**
** Set the setlk timeout.
*/
static int SQLITE_TCLAPI test_setlk_timeout(
void * clientData,
Tcl_Interp *interp,
int argc,
char **argv
){
int rc, ms;
sqlite3 *db;
if( argc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" DB", 0);
return TCL_ERROR;
}
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[2], &ms) ) return TCL_ERROR;
rc = sqlite3_setlk_timeout(db, ms);
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
return TCL_OK;
}
/* /*
** Usage: tcl_variable_type VARIABLENAME ** Usage: tcl_variable_type VARIABLENAME
** **
@@ -8862,6 +8887,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation },
{ "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit }, { "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit },
{ "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout }, { "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout },
{ "sqlite3_setlk_timeout", (Tcl_CmdProc*)test_setlk_timeout },
{ "printf", (Tcl_CmdProc*)test_printf }, { "printf", (Tcl_CmdProc*)test_printf },
{ "sqlite3IoTrace", (Tcl_CmdProc*)test_io_trace }, { "sqlite3IoTrace", (Tcl_CmdProc*)test_io_trace },
{ "clang_sanitize_address", (Tcl_CmdProc*)clang_sanitize_address }, { "clang_sanitize_address", (Tcl_CmdProc*)clang_sanitize_address },

View File

@@ -2027,7 +2027,7 @@ static int walEnableBlockingMs(Wal *pWal, int nMs){
static int walEnableBlocking(Wal *pWal){ static int walEnableBlocking(Wal *pWal){
int res = 0; int res = 0;
if( pWal->db ){ if( pWal->db ){
int tmout = pWal->db->busyTimeout; int tmout = pWal->db->setlkTimeout;
if( tmout ){ if( tmout ){
res = walEnableBlockingMs(pWal, tmout); res = walEnableBlockingMs(pWal, tmout);
} }

View File

@@ -85,5 +85,87 @@ do_test 1.5.3 {
db close db close
tvfs delete tvfs delete
#-------------------------------------------------------------------------
# Check that if sqlite3_setlk_timeout() is used, blocking locks timeout
# but other operations do not use the retry mechanism.
#
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2), (3, 4);
}
sqlite3_setlk_timeout db 2000
# Launch a non-blocking testfixture process to write-lock the
# database for 2000 ms.
testfixture_nb done {
sqlite3 db test.db
db eval {
BEGIN EXCLUSIVE;
INSERT INTO t1 VALUES(5, 6);
}
after 2000
db eval {
COMMIT
}
}
after 500 {set ok 1}
vwait ok
do_catchsql_test 2.1 {
INSERT INTO t1 VALUES(7, 8);
} {1 {database is locked}}
sqlite3_busy_timeout db 2000
do_catchsql_test 2.2 {
INSERT INTO t1 VALUES(7, 8);
} {0 {}}
do_execsql_test 2.3 {
SELECT * FROM t1
} {1 2 3 4 5 6 7 8}
do_execsql_test 2.4 {
PRAGMA journal_mode = wal;
} {wal}
db close
sqlite3 db test.db
do_execsql_test 2.5 {
INSERT INTO t1 VALUES(9, 10);
}
sqlite3_setlk_timeout db 2000
# Launch a non-blocking testfixture process to write-lock the
# database for 2000 ms.
testfixture_nb done {
sqlite3 db test.db
db eval {
BEGIN EXCLUSIVE;
INSERT INTO t1 VALUES(11, 12);
}
after 2000
db eval {
COMMIT
}
}
after 500 {set ok 1}
vwait ok
do_catchsql_test 2.6 {
INSERT INTO t1 VALUES(13, 14);
} {0 {}}
do_execsql_test 2.7 {
SELECT * FROM t1
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14}
finish_test finish_test