mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Have sqlite3_enable_setlk(-1) configure indefinite blocking locks where they are supported.
FossilOrigin-Name: 62009565d2f2a2c4d347e1da0d5b4ad43056742df47fd6ddb92e62f53a2b57f1
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
||||
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-27T11:50:03.268
|
||||
C Have\ssqlite3_enable_setlk(-1)\sconfigure\sindefinite\sblocking\slocks\swhere\sthey\sare\ssupported.
|
||||
D 2025-01-30T15:26:16.127
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
|
||||
@@ -740,7 +740,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
|
||||
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
|
||||
F src/main.c 101ea590be76fda296d12e6d8d1e9cc24f350b83cbf53e68b4f04484b90452a4
|
||||
F src/main.c a54dfdbfee90c8696e473c8fcd5ca1159aa56c096643a0983cc3f0ba4ad45baa
|
||||
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||
@@ -761,8 +761,8 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
|
||||
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
|
||||
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
|
||||
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
|
||||
F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
|
||||
F src/os_win.c 3dfb4a2464143d917d4a407c14706953a98a7ea211742a3039547df05bc3903b
|
||||
F src/os_unix.c 5d0d1788ffa3a43bfc47502e4baa36cf8507e478cd182298fc4974a7cca0954f
|
||||
F src/os_win.c 79a1b02f483ec82ab8fb1b00cc003bff8a3c44bf8d7ea074992a4e0dda9488df
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 2fdd489447aa6bb0f672973bacb801ced92225ca9a1c874ed9b856d2741dc54e
|
||||
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
|
||||
@@ -779,10 +779,10 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e
|
||||
F src/shell.c.in ee54de10e9bd5572f689a6bc0c8e6fa58a8870e1670978ded44412d2715fd908
|
||||
F src/sqlite.h.in ae301ce156765e2601695375dfc787a53b844a2f1c5d359bb667b081d1b7d2e0
|
||||
F src/sqlite.h.in 6958f27ef2f789bb724c2be8ee6edf5b2200e74bf638d2e58bdae9cfc6a55d5e
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h ff8e68e74a61b4bf676d1a9503be2e6c2bc92699ec358bb5e201b1a466f1aa8e
|
||||
F src/sqliteInt.h d718c8517bd0659e1d4239642fa4ff7e85e39bc32a2e33a18b470b362c485f63
|
||||
F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -2022,7 +2022,7 @@ F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766
|
||||
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
|
||||
F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b
|
||||
F test/walsetlk.test 9c5b92f9a20252540fedf9ffa6ee3d1b8af08ea4b80d0144d9b88e6c0c1de80d
|
||||
F test/walsetlk2.test e80cac17de166d5c8e4e0d243452798431aceb76a0abc95bfdd09d718d7c3f3f
|
||||
F test/walsetlk2.test def90f1c8cf47c5128bd3d12171ff1ed6c79f78dcb50c8c2cacf030fc78566a0
|
||||
F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3
|
||||
F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23
|
||||
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
|
||||
@@ -2203,8 +2203,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 6ab9ed8eef77781898375038ab05fc6e5f46b745e4906691393b8b1d90570eb6
|
||||
R 7026d025d771964056775817385cabe6
|
||||
P 4a7eb492797abb47b18b7dfc557aeae43a0dea5b861efc203398d5059b10d131
|
||||
R 742ff1ca774eae27b30e6d13698e33be
|
||||
U dan
|
||||
Z d459230a6d531f1d8e43a532fde898d2
|
||||
Z 0c159766f95122a144fb984bb53f46a1
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@@ -1 +1 @@
|
||||
4a7eb492797abb47b18b7dfc557aeae43a0dea5b861efc203398d5059b10d131
|
||||
62009565d2f2a2c4d347e1da0d5b4ad43056742df47fd6ddb92e62f53a2b57f1
|
||||
|
@@ -1827,12 +1827,16 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the setlk timeout value.
|
||||
*/
|
||||
int sqlite3_setlk_timeout(sqlite3 *db, int ms){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
if( ms<-1 ) return SQLITE_RANGE;
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
db->setlkTimeout = (ms>0 ? ms : 0);
|
||||
db->setlkTimeout = ms;
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
@@ -4038,8 +4038,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
case SQLITE_FCNTL_LOCK_TIMEOUT: {
|
||||
int iOld = pFile->iBusyTimeout;
|
||||
int iNew = *(int*)pArg;
|
||||
#if SQLITE_ENABLE_SETLK_TIMEOUT==1
|
||||
pFile->iBusyTimeout = *(int*)pArg;
|
||||
pFile->iBusyTimeout = iNew<0 ? 0x7FFFFFFF : (unsigned)iNew;
|
||||
#elif SQLITE_ENABLE_SETLK_TIMEOUT==2
|
||||
pFile->iBusyTimeout = !!(*(int*)pArg);
|
||||
#else
|
||||
|
27
src/os_win.c
27
src/os_win.c
@@ -288,7 +288,7 @@ struct winFile {
|
||||
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
unsigned iBusyTimeout; /* Wait this many millisec on locks */
|
||||
DWORD iBusyTimeout; /* Wait this many millisec on locks */
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -2608,7 +2608,7 @@ static int winHandleLockTimeout(
|
||||
DWORD offset,
|
||||
DWORD nByte,
|
||||
int bExcl,
|
||||
int nMs
|
||||
DWORD nMs
|
||||
){
|
||||
DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | (bExcl?LOCKFILE_EXCLUSIVE_LOCK:0);
|
||||
int rc = SQLITE_OK;
|
||||
@@ -2622,7 +2622,7 @@ static int winHandleLockTimeout(
|
||||
ovlp.Offset = offset;
|
||||
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
if( nMs>0 ){
|
||||
if( nMs!=0 ){
|
||||
flags &= ~LOCKFILE_FAIL_IMMEDIATELY;
|
||||
}
|
||||
ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
@@ -2637,9 +2637,17 @@ static int winHandleLockTimeout(
|
||||
/* If SQLITE_ENABLE_SETLK_TIMEOUT is defined, then the file-handle was
|
||||
** opened with FILE_FLAG_OVERHEAD specified. In this case, the call to
|
||||
** LockFileEx() may fail because the request is still pending. This can
|
||||
** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified. */
|
||||
** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified.
|
||||
**
|
||||
** If nMs is 0, then LOCKFILE_FAIL_IMMEDIATELY was set in the flags
|
||||
** passed to LockFileEx(). In this case, if the operation is pending,
|
||||
** block indefinitely until it is finished.
|
||||
**
|
||||
** Otherwise, wait for up to nMs ms for the operation to finish. nMs
|
||||
** may be set to INFINITE.
|
||||
*/
|
||||
if( !ret && GetLastError()==ERROR_IO_PENDING ){
|
||||
DWORD nDelay = (nMs==0 || nMs==0x7FFFFFFF ? INFINITE : nMs);
|
||||
DWORD nDelay = (nMs==0 ? INFINITE : nMs);
|
||||
DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay);
|
||||
if( res==WAIT_OBJECT_0 ){
|
||||
ret = TRUE;
|
||||
@@ -3834,10 +3842,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
case SQLITE_FCNTL_LOCK_TIMEOUT: {
|
||||
int iOld = pFile->iBusyTimeout;
|
||||
int iNew = *(int*)pArg;
|
||||
#if SQLITE_ENABLE_SETLK_TIMEOUT==1
|
||||
pFile->iBusyTimeout = *(int*)pArg;
|
||||
pFile->iBusyTimeout = (iNew < 0) ? INFINITE : (DWORD)iNew;
|
||||
#elif SQLITE_ENABLE_SETLK_TIMEOUT==2
|
||||
pFile->iBusyTimeout = !!(*(int*)pArg);
|
||||
pFile->iBusyTimeout = (DWORD)(!!iNew);
|
||||
#else
|
||||
# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2"
|
||||
#endif
|
||||
@@ -4043,7 +4052,7 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
|
||||
** pShmNode. Take the lock. Truncate the *-shm file if required.
|
||||
** Return SQLITE_OK if successful, or an SQLite error code otherwise.
|
||||
*/
|
||||
static int winLockSharedMemory(winShmNode *pShmNode, int nMs){
|
||||
static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){
|
||||
HANDLE h = pShmNode->hSharedShm;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
@@ -4407,7 +4416,7 @@ static int winShmLock(
|
||||
}
|
||||
}else{
|
||||
int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0);
|
||||
int nMs = winFileBusyTimeout(pDbFd);
|
||||
DWORD nMs = winFileBusyTimeout(pDbFd);
|
||||
rc = winHandleLockTimeout(p->hShm, ofst+WIN_SHM_BASE, n, bExcl, nMs);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( bExcl ){
|
||||
|
@@ -2909,9 +2909,10 @@ int sqlite3_busy_timeout(sqlite3*, int ms);
|
||||
** 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.
|
||||
** Passing 0 to this function disables blocking locks altogether. Passing
|
||||
** -1 to this function requests that the VFS blocks for a long time -
|
||||
** indefinitely if possible. The results of passing any other negative value
|
||||
** are undefined.
|
||||
**
|
||||
** Internally, each SQLite database handle store two timeout values - the
|
||||
** busy-timeout (used for rollback mode databases, or if the VFS does not
|
||||
|
@@ -1745,7 +1745,7 @@ struct sqlite3 {
|
||||
int nAnalysisLimit; /* Number of index rows to ANALYZE */
|
||||
int busyTimeout; /* Busy handler timeout, in msec */
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
int setlkTimeout; /* Blocking lock timeout, in msec */
|
||||
int setlkTimeout; /* Blocking lock timeout, in msec. -1 -> inf. */
|
||||
#endif
|
||||
int nSavepoint; /* Number of non-transaction savepoints */
|
||||
int nStatement; /* Number of nested statement-transactions */
|
||||
|
@@ -167,5 +167,90 @@ do_execsql_test 2.7 {
|
||||
SELECT * FROM t1
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that if sqlite3_setlk_timeout(-1) is called, blocking locks are
|
||||
# enabled and last for a few seconds at least. Difficult to test that they
|
||||
# really do block indefinitely.
|
||||
#
|
||||
reset_db
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1, 'one'), (3, 'three');
|
||||
} {wal}
|
||||
|
||||
sqlite3_setlk_timeout db -1
|
||||
|
||||
# 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, 'five');
|
||||
}
|
||||
after 2000
|
||||
db eval {
|
||||
COMMIT
|
||||
}
|
||||
}
|
||||
|
||||
after 500 {set ok 1}
|
||||
vwait ok
|
||||
|
||||
breakpoint
|
||||
do_catchsql_test 3.1 {
|
||||
INSERT INTO t1 VALUES(7, 'seven');
|
||||
} {0 {}}
|
||||
|
||||
# Launch another 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(9, 'nine');
|
||||
}
|
||||
after 2000
|
||||
db eval {
|
||||
COMMIT
|
||||
}
|
||||
}
|
||||
|
||||
after 500 {set ok 1}
|
||||
vwait ok
|
||||
|
||||
do_catchsql_test 3.2 {
|
||||
INSERT INTO t1 VALUES(9, 'ten');
|
||||
} {1 {UNIQUE constraint failed: t1.a}}
|
||||
|
||||
do_execsql_test 3.3 {
|
||||
SELECT * FROM t1
|
||||
} {1 one 3 three 5 five 7 seven 9 nine}
|
||||
|
||||
db close
|
||||
|
||||
# Launch another 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, 'eleven');
|
||||
}
|
||||
after 2000
|
||||
db eval {
|
||||
COMMIT
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3 db test.db
|
||||
sqlite3_setlk_timeout db -1
|
||||
do_catchsql_test 3.4 {
|
||||
INSERT INTO t1 VALUES(13, 'thirteen');
|
||||
} {0 {}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
Reference in New Issue
Block a user