1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-01-06 08:01:16 +03:00

Support SQLITE_ENABLE_SETLK_TIMEOUT on windows.

FossilOrigin-Name: e88212b10a7829ff42ef51a02863d788c929e54161faf492f9ef2ad90fd7074e
This commit is contained in:
dan
2025-02-24 21:27:16 +00:00
24 changed files with 1448 additions and 406 deletions

View File

@@ -294,6 +294,12 @@ SESSION = 0
RBU = 0
!ENDIF
# Set this to non-0 to enable support for blocking locks.
#
!IFNDEF SETLK_TIMEOUT
SETLK_TIMEOUT = 0
!ENDIF
# Set the source code file to be used by executables and libraries when
# they need the amalgamation.
#
@@ -450,6 +456,10 @@ EXT_FEATURE_FLAGS =
!ENDIF
!ENDIF
!IF $(SETLK_TIMEOUT)!=0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SETLK_TIMEOUT
!ENDIF
###############################################################################
############################### END OF OPTIONS ################################
###############################################################################

View File

@@ -1,11 +1,11 @@
C Tamp\sdown\svarious\sharmless\scompiler\swarnings.\s\sUse\s"int"\sin\splaces\sinstead\nof\s"u16"\sor\s"i16"\ssince\sthe\scompiler\scomplains\sless\sand\sgenerates\sfaster\ncode.
D 2025-02-22T16:44:14.174
C Support\sSQLITE_ENABLE_SETLK_TIMEOUT\son\swindows.
D 2025-02-24T21:27:16.284
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
F Makefile.in 80be2e281d4647ac15a5bac15d5d20fc76d1cfb3f3f6dc01d1a26e3346a5042a
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
F Makefile.msc 50c656e096ae49ccf9e5e88b4995f0a155f231ebae5b6d185cc64ce99d728a83
F Makefile.msc ef04498c7e227a0f459b105bb4952f26cc985d1d6340a367e62d5a79c4689dfb
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
F VERSION 001dea55eb8304ec9130b6b44a32d3fc349f279d45a7e224fc0730c3cb8e2372
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
@@ -717,7 +717,7 @@ F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03
F src/alter.c 0d2122ade76617b7cca383428d0881a9821ef8ddaf9cce6ff91d69a215614b95
F src/analyze.c 13895d4da6ac857d95d3291dc607d492eba3ea1cbc3bc04baaa0383fbc1bb3d4
F src/attach.c c36d9d82811e2274bd06bf3b34459e36d8ae8a7f32efa5cbf3f890eef08a9987
F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d
F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c 782cc29b42b47e7ec6348eb0aaf9ffe60063f498387e7249f458d445af4b53e9
@@ -745,7 +745,7 @@ F src/insert.c a5f0366266be993ebf533808f22cb7a788624805b55bc45424ceed3f48c54a16
F src/json.c 5abb5cb782e74451a8882f6b7ee4d5e629246642262660bd1980a5e1b796258d
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c 2650f54f7c2aa2c53cc61b571bad9c7c32d60400e3f6a270bd444f5d76e03eb8
F src/main.c 9584f789e573f7fb9b5bdc90b35eb16eeea5126419dd3d7166df532f6e121fd8
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -766,8 +766,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 4c73f89479d90412cb736a180e9ef89ac1495a158753a7f5de1260c197bc8e1f
F src/os_win.c 2423a45e70c2cda01bfc84106f7e9f34feb1add42121ab2e35a67ba24589ac52
F src/os_unix.c 1e887f1f926a76a65ebcef79aa6da76e369ad7f899fa211c6ee56ff953c098a2
F src/os_win.c ab9912a2c1cb39a6429b8de919a5b63ad1c7775e511d748391c57bf9ad03bd29
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 8d73e7a0ebbecd8bb4996ff285cc055cec56b7e3edb5a4609d0748e0fa39d28a
F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
@@ -783,16 +783,16 @@ F src/resolve.c 626c24b258b111f75c22107aa5614ad89810df3026f5ca071116d3fe75925c75
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c a076f7db3a0fcbd9f710d7746cfc07e0b3baadee45eb3136bedc29c598ef8f1c
F src/shell.c.in bf997e43faaa1ef0ff78d4d7b9be6a9430cf1edda9a47a14e7fef646fcb459af
F src/sqlite.h.in 8d4486fb28a90de818ac1e8c6206ea458e7de6bd8e0dfa3d554494f155be8c01
F src/sqlite.h.in 95c01911006f42019ee4dacd62101740a75fdfaeeca9b1c5fd7a70cfac3bb6f8
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h e74f0ea0bc4d3c16afd5004557b264137d6f1d61d2a1ff2a49877b0589945462
F src/sqliteInt.h c997c67257778a3a866424adea36d4f2b4439742a978c0ddc11e694c1e9ea3ca
F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b
F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 5c1e367e26711044730c93d4b81312170918a8d1fe811f45be740ab48f7de8c1
F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
F src/test1.c 9d2da51b4c33633e7370e4068af6d16d2c52b22a5810ec012ac32e77f8397b64
F src/test1.c ba7b93478a6a7a3f48ec5507f28bc662636ac5d9f9791700d3648a8e788f0bb2
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
@@ -805,7 +805,7 @@ F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d97
F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
F src/test_config.c bff5e1625c007f14a9ea4d346b6a741149b5e1f885c1c7ae69bb28a8ddade151
F src/test_config.c 7f412406592794636d6226268e26d413850a9f799bc5f3c01afc2820b165fca8
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
@@ -825,7 +825,7 @@ F src/test_mutex.c f10fcbc2086b19c7b0ddf2752caf2095e42be74d8d7f6093619445b43b1f7
F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4
F src/test_osinst.c 7aa3feaa3a1da1b5f75bde2ce958dbfe14ec484f065bb2b5b9727d8851fa089b
F src/test_pcache.c 496da3f7e2ca66aefbc36bbf22138b1eff43ba0dff175c228b760fa020a37bd0
F src/test_quota.c 07369655d24c3f3fbdbd8fd8f42e856a054a7497846ca1c83ed4be68152a251f
F src/test_quota.c 744552848d9c5c5de3920d1c44b03d425a4123a223310567a199c7e0d3fe80bf
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
F src/test_rtree.c d844d746a3cc027247318b970025a927f14772339c991f40e7911583ea5ed0d9
F src/test_schema.c b06d3ddc3edc173c143878f3edb869dd200d57d918ae2f38820534f9a5e3d7d9
@@ -836,7 +836,7 @@ F src/test_tclsh.c c01706ac60bd3176754d3ccd37da74c6ad97c2e14489f8ed71b497c1c0ac0
F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e048424
F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb
F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3
F src/test_vfs.c f298475e468c7e14945b20af885917181090c265aa3c4ade897849c9fbd396f2
F src/test_vfs.c a19728c5930b5f5f415c664c57b029cba98c459fe70639aefcbfc4f70d544335
F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb775ebc50
F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72
@@ -862,7 +862,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c cefdffc112c767c79596d9c0d15cb4de27071132e9b8a0fce323b140cd4af683
F src/wal.c 2c69a5f92270429db72d853691b0640c76c671d5b2465396dadb9d9873e1efce
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 12cca5dfbe96e2589f951c43c0720fc58e52611787c37d85a0d9c10376202e8b
@@ -1145,7 +1145,7 @@ F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
F test/external_reader.test c7d34694f1b25c32d866f56ac80c1e29edddc42b4ef90cad589263ffac2cde0c
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
F test/fallocate.test 37a62e396a68eeede8f8d2ecf23573a80faceb630788d314d0a073d862616717
F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3
F test/filectrl.test 7e6788759997139632eb700765d5f73d53fc5ff5d9d778e773911750ab134321
F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4
F test/filter1.test 590f8ba9a0cd0823b80d89ac75c5ce72276189cef9225d2436adaf1ee87f3727
F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8
@@ -1417,7 +1417,7 @@ F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37
F test/lock5.test 583cae05992af0f66607286917f7d5f8aed3b6053c52df5994efb98f2a8fdbaf
F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413
F test/lock_common.tcl f33b7fbc275be25a6f2863b4cc8af35278e24d127a3f734825477bf223b05ffe
F test/lookaside.test 5a828e7256f1ee4da8e1bdaa03373a3ccdb0f1ff98dfa82e9b76cb41a45b1083
F test/main.test e8752d76233b1c8906cd2c98ad920dba868bd63c87d51d8a2ea5e9cba55dd496
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
@@ -1638,7 +1638,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test 5d84e415adf7cc4edd5913c4f23c761104ff135b9c190fcf7b430a4cbca6cb65
F test/shell1.test ccb26a0cb17a73406b5e4fe3c3260988a22f5c63680d8474b4d35e9bc195f3cb
F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24
F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8
F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
@@ -1728,9 +1728,9 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59
F test/tester.tcl 2f900e8c912fbbaf381e69a92258fa6023ad0b4c8907e426bebbb4585da23c61
F test/testrunner.tcl 90ed8b6c2b26dc1f6af08aeb04670a5df86172f3d9828d8af000f972afa50061 x
F test/testrunner_data.tcl 63ff9eba1d11a3b0a6fc8446d5fa32da21aabda55b994e8fcbd4a8ce81f48378
F test/testrunner_data.tcl f64589ddd05abc2be4d6ab7573fb1cebb27a1034a092d95da684187dd455cd41
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -2027,7 +2027,9 @@ F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c
F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766cdc
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b
F test/walsetlk.test 34c901443b31ab720afc463f5b236c86ca5c4134402573dce91aa0761de8db5a
F test/walsetlk.test 9c5b92f9a20252540fedf9ffa6ee3d1b8af08ea4b80d0144d9b88e6c0c1de80d
F test/walsetlk2.test 5ae8662a28c013e8df2ce975f9e3577a7f239aeb4622bb8d4d0ca8e16c0c132e
F test/walsetlk3.test 1b82bd92dea7e58f498b4399b0b3d26773dd8ac5c74205ce4a23c207cb8e85fe
F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3
F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
@@ -2063,7 +2065,7 @@ F test/wherelimit3.test 22d73e046870cf8bbe15573eda6b432b07ebe64a88711f9f849c6b36
F test/widetab1.test c296a98e123762de79917350e45fa33fdf88577a2571eb3a64c8bf7e44ef74d1
F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
F test/win32longpath.test 304006024ca47104bf5a7415ef31ca83ecfc29351af202baf8588b880cffc116
F test/win32longpath.test c5d149ab60a3052fa84b3df12ff655d703bfdfd48eed9854b14945d4d0bf3ddd
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 79dc3b9a2226f622d7e104a1fc750d1c4c3c08d6147b59085bdbe05352947ffa
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
@@ -2147,7 +2149,7 @@ F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a19
F tool/mkamalzip.tcl 8aa5ebe7973c8b8774062d34e15fea9815c4cc2ceea3a9b184695f005910876a
F tool/mkautoconfamal.sh c5e65fa1c922f2e3b3e4f6cd0331ec7d84bdef085f32cb1c46673cdf95ec8090
F tool/mkccode.tcl 210159febe0ef0ecbc53c79833500663ceaba0115b2b374405818dc835b5f84b x
F tool/mkctimec.tcl b57ab5c43cf6a46ba4030027da1cc73d7839e7b78da3b328545bc941bb62360b x
F tool/mkctimec.tcl 809e42c417ca46f585991c832d7672364c3b0b47807d8b488a13dd1ff54bdd39 x
F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
@@ -2210,8 +2212,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 eeea11278bdebe336f0c30fbad79e30e3456ab67dae46abdd5f9951ea1b61bed
R 8078ee78be0e4d7d18ee35dbad7406fe
U drh
Z 2ee0c7ad1f2d8a9853a04c1df0464ab5
P 742827f049768c4f69ccdfaadfad339aaad3bc126d3a68b90cfea01d825bf7ce 55324d1c862c42b95251a398c40930d9fa94debb1aec7d3d0ae734d6b17b4a59
R 2117afef50ba03929efd8c7065744408
U dan
Z f60d38f782589947a9438a2ed64b4320
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
742827f049768c4f69ccdfaadfad339aaad3bc126d3a68b90cfea01d825bf7ce
e88212b10a7829ff42ef51a02863d788c929e54161faf492f9ef2ad90fd7074e

View File

@@ -227,6 +227,13 @@ static void attachFunc(
sqlite3BtreeEnterAll(db);
db->init.iDb = 0;
db->mDbFlags &= ~(DBFLAG_SchemaKnownOk);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( db->setlkFlags & SQLITE_SETLK_BLOCK_ON_CONNECT ){
int val = 1;
sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pNew->pBt));
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, &val);
}
#endif
if( !REOPEN_AS_MEMDB(db) ){
rc = sqlite3Init(db, &zErrDyn);
}

View File

@@ -1779,6 +1779,9 @@ int sqlite3_busy_handler(
db->busyHandler.pBusyArg = pArg;
db->busyHandler.nBusy = 0;
db->busyTimeout = 0;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
db->setlkTimeout = 0;
#endif
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
@@ -1828,12 +1831,43 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
(void*)db);
db->busyTimeout = ms;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
db->setlkTimeout = ms;
#endif
}else{
sqlite3_busy_handler(db, 0, 0);
}
return SQLITE_OK;
}
/*
** Set the setlk timeout value.
*/
int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int iDb;
int bBOC = ((flags & SQLITE_SETLK_BLOCK_ON_CONNECT) ? 1 : 0);
#endif
#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;
db->setlkFlags = flags;
sqlite3BtreeEnterAll(db);
for(iDb=0; iDb<db->nDb; iDb++){
Btree *pBt = db->aDb[iDb].pBt;
if( pBt ){
sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt));
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC);
}
}
sqlite3BtreeLeaveAll(db);
#endif
return SQLITE_OK;
}
/*
** Cause any pending operation to stop at its earliest opportunity.
*/

View File

@@ -284,6 +284,7 @@ struct unixFile {
#endif
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
unsigned iBusyTimeout; /* Wait this many millisec on locks */
int bBlockOnConnect; /* True to block for SHARED locks */
#endif
#if OS_VXWORKS
struct vxworksFileId *pId; /* Unique file ID */
@@ -1677,6 +1678,13 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
rc = 0;
}
}else{
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( pFile->bBlockOnConnect && pLock->l_type==F_RDLCK
&& pLock->l_start==SHARED_FIRST && pLock->l_len==SHARED_SIZE
){
rc = osFcntl(pFile->h, F_SETLKW, pLock);
}else
#endif
rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
}
return rc;
@@ -4038,8 +4046,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
@@ -4048,7 +4057,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(int*)pArg = iOld;
return SQLITE_OK;
}
#endif
case SQLITE_FCNTL_BLOCK_ON_CONNECT: {
int iNew = *(int*)pArg;
pFile->bBlockOnConnect = iNew;
return SQLITE_OK;
}
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
i64 newLimit = *(i64*)pArg;
@@ -5031,7 +5045,7 @@ static int unixShmLock(
**
** It is not permitted to block on the RECOVER lock.
*/
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG)
{
u16 lockMask = (p->exclMask|p->sharedMask);
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (

File diff suppressed because it is too large Load Diff

View File

@@ -1163,6 +1163,12 @@ struct sqlite3_io_methods {
** the value that M is to be set to. Before returning, the 32-bit signed
** integer is overwritten with the previous value of M.
**
** <li>[[SQLITE_FCNTL_BLOCK_ON_CONNECT]]
** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the
** VFS to block when taking a SHARED lock to connect to a wal mode database.
** This is used to implement the functionality associated with
** SQLITE_SETLK_BLOCK_ON_CONNECT.
**
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
** a database file. The argument is a pointer to a 32-bit unsigned integer.
@@ -1259,6 +1265,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_CKSM_FILE 41
#define SQLITE_FCNTL_RESET_CACHE 42
#define SQLITE_FCNTL_NULL_IO 43
#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -3015,6 +3022,44 @@ int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
*/
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 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
** 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.
**
** Whenever the number of connections to a wal mode database falls from
** 1 to 0, the last connection takes an exclusive lock on the database,
** then checkpoints and deletes the wal file. While it is doing this, any
** new connection that tries to read from the database fails with an
** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is
** passed to this API, the new connection blocks until the exclusive lock
** has been released.
*/
int sqlite3_setlk_timeout(sqlite3*, int ms, int flags);
/*
** CAPI3REF: Flags for sqlite3_setlk_timeout()
*/
#define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01
/*
** CAPI3REF: Convenience Routines For Running Queries
** METHOD: sqlite3

View File

@@ -1761,6 +1761,10 @@ struct sqlite3 {
Savepoint *pSavepoint; /* List of active savepoints */
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. -1 -> inf. */
int setlkFlags; /* Flags passed to setlk_timeout() */
#endif
int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */
i64 nDeferredCons; /* Net deferred constraints this transaction. */

View File

@@ -5946,6 +5946,42 @@ static int SQLITE_TCLAPI test_busy_timeout(
return TCL_OK;
}
/*
** Usage: sqlite3_setlk_timeout ?-blockonconnect? 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;
int bBlockOnConnect = 0;
if( argc==4 ){
const char *zArg = argv[1];
int nArg = strlen(zArg);
if( nArg>=2 && nArg<=15 && memcmp(zArg, "-blockonconnect", nArg)==0 ){
bBlockOnConnect = 1;
}
}
if( argc!=(3+bBlockOnConnect) ){
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" ?-blockonconnect? DB MS", 0);
return TCL_ERROR;
}
if( getDbPointer(interp, argv[argc-2], &db) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[argc-1], &ms) ) return TCL_ERROR;
rc = sqlite3_setlk_timeout(
db, ms, (bBlockOnConnect ? SQLITE_SETLK_BLOCK_ON_CONNECT : 0)
);
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
return TCL_OK;
}
/*
** Usage: tcl_variable_type VARIABLENAME
**
@@ -7939,7 +7975,7 @@ static int SQLITE_TCLAPI test_getrusage(
*/
struct win32FileLocker {
char *evName; /* Name of event to signal thread startup */
HANDLE h; /* Handle of the file to be locked */
sqlite3_file *pFd; /* Handle of the file to be locked */
int delay1; /* Delay before locking */
int delay2; /* Delay before unlocking */
int ok; /* Finished ok */
@@ -7955,6 +7991,8 @@ struct win32FileLocker {
*/
static void SQLITE_CDECL win32_file_locker(void *pAppData){
struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
sqlite3_file *pFd = p->pFd;
HANDLE h = INVALID_HANDLE_VALUE;
if( p->evName ){
HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName);
if ( ev ){
@@ -7963,15 +8001,17 @@ static void SQLITE_CDECL win32_file_locker(void *pAppData){
}
}
if( p->delay1 ) Sleep(p->delay1);
if( LockFile(p->h, 0, 0, 100000000, 0) ){
pFd->pMethods->xFileControl(pFd, SQLITE_FCNTL_WIN32_GET_HANDLE, (void*)&h);
if( LockFile(h, 0, 0, 100000000, 0) ){
Sleep(p->delay2);
UnlockFile(p->h, 0, 0, 100000000, 0);
UnlockFile(h, 0, 0, 100000000, 0);
p->ok = 1;
}else{
p->err = 1;
}
CloseHandle(p->h);
p->h = 0;
pFd->pMethods->xClose(pFd);
sqlite3_free(pFd);
p->pFd = 0;
p->delay1 = 0;
p->delay2 = 0;
}
@@ -7991,37 +8031,56 @@ static int SQLITE_TCLAPI win32_file_lock(
Tcl_Obj *CONST objv[]
){
static struct win32FileLocker x = { "win32_file_lock", 0, 0, 0, 0, 0 };
const char *zFilename;
const char *zFilename = 0;
Tcl_Size nFilename = 0;
char *zTerm = 0;
char zBuf[200];
int retry = 0;
HANDLE ev;
DWORD wResult;
sqlite3_vfs *pVfs = 0;
int flags = SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE;
int rc = SQLITE_OK;
if( objc!=4 && objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "FILENAME DELAY1 DELAY2");
return TCL_ERROR;
}
if( objc==1 ){
HANDLE h = INVALID_HANDLE_VALUE;
if( x.pFd ){
x.pFd->pMethods->xFileControl(
x.pFd, SQLITE_FCNTL_WIN32_GET_HANDLE, (void*)&h
);
}
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d %d %d %d %d",
x.ok, x.err, x.delay1, x.delay2, x.h);
x.ok, x.err, x.delay1, x.delay2, h);
Tcl_AppendResult(interp, zBuf, (char*)0);
return TCL_OK;
}
while( x.h && retry<30 ){
while( x.pFd && retry<30 ){
retry++;
Sleep(100);
}
if( x.h ){
if( x.pFd ){
Tcl_AppendResult(interp, "busy", (char*)0);
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[2], &x.delay1) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[3], &x.delay2) ) return TCL_ERROR;
zFilename = Tcl_GetString(objv[1]);
x.h = CreateFile(zFilename, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
if( !x.h ){
pVfs = sqlite3_vfs_find(0);
x.pFd = (sqlite3_file*)sqlite3_malloc(pVfs->szOsFile);
/* xOpen() must be passed a dual-nul-terminated string preceded in memory
** by 4 0x00 bytes. */
zFilename = Tcl_GetStringFromObj(objv[1], &nFilename);
zTerm = (char*)sqlite3_malloc(nFilename+6);
memset(zTerm, 0, nFilename+6);
memcpy(&zTerm[4], zFilename, nFilename);
rc = pVfs->xOpen(pVfs, &zTerm[4], x.pFd, flags, &flags);
sqlite3_free(zTerm);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, "cannot open file: ", zFilename, (char*)0);
return TCL_ERROR;
}
@@ -8848,6 +8907,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation },
{ "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit },
{ "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout },
{ "sqlite3_setlk_timeout", (Tcl_CmdProc*)test_setlk_timeout },
{ "printf", (Tcl_CmdProc*)test_printf },
{ "sqlite3IoTrace", (Tcl_CmdProc*)test_io_trace },
{ "clang_sanitize_address", (Tcl_CmdProc*)clang_sanitize_address },

View File

@@ -88,6 +88,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "win32malloc", "0", TCL_GLOBAL_ONLY);
#endif
#if defined(SQLITE_OS_WINRT) && SQLITE_OS_WINRT
Tcl_SetVar2(interp, "sqlite_options", "winrt", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "winrt", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_DEBUG
Tcl_SetVar2(interp, "sqlite_options", "debug", "1", TCL_GLOBAL_ONLY);
#else
@@ -781,6 +787,13 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "1", TCL_GLOBAL_ONLY);
#endif
#if !defined(SQLITE_ENABLE_SETLK_TIMEOUT)
Tcl_SetVar2(interp, "sqlite_options", "setlk_timeout", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "setlk_timeout",
STRINGVALUE(SQLITE_ENABLE_SETLK_TIMEOUT), TCL_GLOBAL_ONLY);
#endif
#define LINKVAR(x) { \
static const int cv_ ## x = SQLITE_ ## x; \
Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \

View File

@@ -389,7 +389,11 @@ static char *quota_utf8_to_mbcs(const char *zUtf8){
zTmpWide = (LPWSTR)sqlite3_malloc( (nWide+1)*sizeof(zTmpWide[0]) );
if( zTmpWide==0 ) return 0;
MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zTmpWide, nWide);
#ifdef SQLITE_OS_WINRT
codepage = CP_ACP;
#else
codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif
nMbcs = WideCharToMultiByte(codepage, 0, zTmpWide, nWide, 0, 0, 0, 0);
zMbcs = nMbcs ? (char*)sqlite3_malloc( nMbcs+1 ) : 0;
if( zMbcs ){

View File

@@ -130,8 +130,9 @@ struct Testvfs {
#define TESTVFS_LOCK_MASK 0x00040000
#define TESTVFS_CKLOCK_MASK 0x00080000
#define TESTVFS_FCNTL_MASK 0x00100000
#define TESTVFS_SLEEP_MASK 0x00200000
#define TESTVFS_ALL_MASK 0x001FFFFF
#define TESTVFS_ALL_MASK 0x003FFFFF
#define TESTVFS_MAX_PAGES 1024
@@ -813,6 +814,10 @@ static int tvfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
** actually slept.
*/
static int tvfsSleep(sqlite3_vfs *pVfs, int nMicro){
Testvfs *p = (Testvfs *)pVfs->pAppData;
if( p->pScript && (p->mask&TESTVFS_SLEEP_MASK) ){
tvfsExecTcl(p, "xSleep", Tcl_NewIntObj(nMicro), 0, 0, 0);
}
return sqlite3OsSleep(PARENTVFS(pVfs), nMicro);
}
@@ -1197,6 +1202,7 @@ static int SQLITE_TCLAPI testvfs_obj_cmd(
{ "xLock", TESTVFS_LOCK_MASK },
{ "xCheckReservedLock", TESTVFS_CKLOCK_MASK },
{ "xFileControl", TESTVFS_FCNTL_MASK },
{ "xSleep", TESTVFS_SLEEP_MASK },
};
Tcl_Obj **apElem = 0;
Tcl_Size nElem = 0;

View File

@@ -502,6 +502,11 @@ struct WalCkptInfo {
/*
** An open write-ahead log file is represented by an instance of the
** following object.
**
** writeLock:
** This is usually set to 1 whenever the WRITER lock is held. However,
** if it is set to 2, then the WRITER lock is held but must be released
** by walHandleException() if a SEH exception is thrown.
*/
struct Wal {
sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */
@@ -2027,7 +2032,7 @@ static int walEnableBlockingMs(Wal *pWal, int nMs){
static int walEnableBlocking(Wal *pWal){
int res = 0;
if( pWal->db ){
int tmout = pWal->db->busyTimeout;
int tmout = pWal->db->setlkTimeout;
if( tmout ){
res = walEnableBlockingMs(pWal, tmout);
}
@@ -2413,7 +2418,9 @@ static int walHandleException(Wal *pWal){
static const int S = 1;
static const int E = (1<<SQLITE_SHM_NLOCK);
int ii;
u32 mUnlock = pWal->lockMask & ~(
u32 mUnlock;
if( pWal->writeLock==2 ) pWal->writeLock = 0;
mUnlock = pWal->lockMask & ~(
(pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock)))
| (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0)
| (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0)
@@ -2685,7 +2692,12 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
if( bWriteLock
|| SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1))
){
pWal->writeLock = 1;
/* If the write-lock was just obtained, set writeLock to 2 instead of
** the usual 1. This causes walIndexPage() to behave as if the
** write-lock were held (so that it allocates new pages as required),
** and walHandleException() to unlock the write-lock if a SEH exception
** is thrown. */
if( !bWriteLock ) pWal->writeLock = 2;
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
badHdr = walIndexTryHdr(pWal, pChanged);
if( badHdr ){
@@ -3470,8 +3482,11 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
** read-lock.
*/
void sqlite3WalEndReadTransaction(Wal *pWal){
sqlite3WalEndWriteTransaction(pWal);
#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
assert( pWal->writeLock==0 || pWal->readLock<0 );
#endif
if( pWal->readLock>=0 ){
sqlite3WalEndWriteTransaction(pWal);
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
pWal->readLock = -1;
}
@@ -3664,7 +3679,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
** read-transaction was even opened, making this call a no-op.
** Return early. */
if( pWal->writeLock ){
assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
assert( !memcmp(&pWal->hdr,(void*)pWal->apWiData[0],sizeof(WalIndexHdr)) );
return SQLITE_OK;
}
#endif

View File

@@ -36,11 +36,13 @@ do_test filectrl-1.5 {
sqlite3 db test_control_lockproxy.db
file_control_lockproxy_test db [get_pwd]
} {}
do_test filectrl-1.6 {
sqlite3 db test.db
set fn [file_control_tempfilename db]
set fn
} {/etilqs_/}
ifcapable !winrt {
do_test filectrl-1.6 {
sqlite3 db test.db
set fn [file_control_tempfilename db]
set fn
} {/etilqs_/}
}
db close
forcedelete .test_control_lockproxy.db-conch test.proxy
forcedelete test.db test2.db

View File

@@ -145,6 +145,7 @@ proc testfixture_nb_cb {varname chan} {
}
if { $line == "OVER" } {
global $varname
set $varname [lindex $::tfnb($chan) 1]
unset ::tfnb($chan)
close $chan

View File

@@ -296,7 +296,9 @@ do_test shell1-3.2.4 {
catchcmd "test.db" ".bail OFF BAD"
} {1 {Usage: .bail on|off}}
ifcapable vtab {
# This test will not work on winrt, as winrt has no concept of the absolute
# paths that the test expects in the result. It uses relative paths only.
ifcapable vtab&&!winrt {
# .databases List names and files of attached databases
do_test shell1-3.3.1 {
catchcmd "-csv test.db" ".databases"
@@ -744,9 +746,12 @@ do_test shell1-3.26.6 {
do_test shell1-3.27.1 {
catchcmd "test.db" ".timer"
} {1 {Usage: .timer on|off}}
do_test shell1-3.27.2 {
catchcmd "test.db" ".timer ON"
} {0 {}}
ifcapable !winrt {
# No timer support on winrt.
do_test shell1-3.27.2 {
catchcmd "test.db" ".timer ON"
} {0 {}}
}
do_test shell1-3.27.3 {
catchcmd "test.db" ".timer OFF"
} {0 {}}

View File

@@ -1776,6 +1776,11 @@ proc crashsql {args} {
# cfSync(), which can be different then what TCL uses by
# default, so here we force it to the "nativename" format.
set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]
ifcapable winrt {
# Except on winrt. Winrt has no way to transform a relative path into
# an absolute one, so it just uses the relative paths.
set cfile $crashfile
}
set f [open crash.tcl w]
puts $f "sqlite3_initialize ; sqlite3_shutdown"

View File

@@ -37,6 +37,7 @@ namespace eval trd {
set tcltest(win.Windows-Memdebug) veryquick
set tcltest(win.Windows-Win32Heap) veryquick
set tcltest(win.Windows-Sanitize) veryquick
set tcltest(win.Windows-WinRT) veryquick
set tcltest(win.Default) full
# Extra [make xyz] tests that should be run for various builds.
@@ -358,11 +359,17 @@ namespace eval trd {
set build(Windows-Win32Heap) {
WIN32HEAP=1
DEBUG=4
ENABLE_SETLK=1
}
set build(Windows-Sanitize) {
ASAN=1
}
set build(Windows-WinRT) {
FOR_WINRT=1
ENABLE_SETLK=1
-DSQLITE_TEMP_STORE=3
}
}

View File

@@ -80,6 +80,19 @@ db2 close
#-------------------------------------------------------------------------
do_multiclient_test tn {
testvfs tvfs -fullshm 1
db close
sqlite3 db test.db -vfs tvfs
tvfs script xSleep_callback
tvfs filter xSleep
set ::sleep_count 0
proc xSleep_callback {xSleep nMs} {
after [expr $nMs / 1000]
incr ::sleep_count
}
do_test 2.$tn.1 {
sql1 {
PRAGMA journal_mode = wal;
@@ -132,7 +145,6 @@ do_multiclient_test tn {
set us [lindex [time { catch {db eval "PRAGMA wal_checkpoint=RESTART"} }] 0]
expr $us>1000000 && $us<4000000
} {1}
do_test 2.$tn.9 {
sql3 {
INSERT INTO t1 VALUES(11, 12);
@@ -178,13 +190,50 @@ do_multiclient_test tn {
set us [lindex [time { catch {db eval "PRAGMA wal_checkpoint=RESTART"} }] 0]
expr $us>1000000 && $us<4000000
} {1}
db close
tvfs delete
# Set bSleep to true if it is expected that the above used xSleep() to
# wait for locks. bSleep is true unless SQLITE_ENABLE_SETLK_TIMEOUT is
# set to 1 and either:
#
# * the OS is windows, or
# * the OS is unix and the tests were run with each connection
# in a separate process.
#
set bSleep 1
if {$::sqlite_options(setlk_timeout)==1} {
if {$::tcl_platform(platform)=="windows"} {
set bSleep 0
}
if {$::tcl_platform(platform)=="unix"} {
set bSleep [expr $tn==2]
}
}
do_test 2.$tn.15.$bSleep {
expr $::sleep_count > 0
} $bSleep
}
#-------------------------------------------------------------------------
reset_db
sqlite3 db2 test.db
testvfs tvfs -fullshm 1
tvfs script xSleep_callback
tvfs filter xSleep
set ::sleep_count 0
proc xSleep_callback {xSleep nMs} {
after [expr $nMs / 1000]
incr ::sleep_count
breakpoint
}
sqlite3 db2 test.db -vfs tvfs
db2 timeout 1000
do_execsql_test 3.0 {
PRAGMA journal_mode = wal;
CREATE TABLE x1(x, y);
@@ -192,8 +241,109 @@ do_execsql_test 3.0 {
INSERT INTO x1 VALUES(1, 2);
} {wal}
do_test 3.1 {
do_execsql_test -db db2 3.1a {
SELECT * FROM x1
} {}
do_test 3.1b {
list [catch { db2 eval {BEGIN EXCLUSIVE} } msg] $msg
} {1 {database is locked}}
# Set bExpect to true if calls to xSleep() are expected. Such calls are
# expected unless this is an SQLITE_ENABLE_SETLK_TIMEOUT=1 build.
set bExpect 1
if {$tcl_platform(platform)=="windows" && $::sqlite_options(setlk_timeout)==1} {
set bExpect 0
}
do_test 3.2 {
expr {$::sleep_count > 0}
} $bExpect
set ::sleep_count 0
do_execsql_test 3.3 {
COMMIT;
}
# 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 x1 VALUES(3, 4);
}
after 2000
db eval {
COMMIT
}
}
after 500 {set ok 1}
vwait ok
db2 timeout 5000
do_test 3.4 {
set t [lindex [time { db2 eval { BEGIN EXCLUSIVE } }] 0]
expr ($t>1000000)
} {1}
# Set bExpect to true if calls to xSleep() are expected. Such calls are
# expected unless this is an SQLITE_ENABLE_SETLK_TIMEOUT=1 build.
set bExpect 1
if {$::sqlite_options(setlk_timeout)==1} {
set bExpect 0
}
do_test 3.5 {
expr {$::sleep_count > 0}
} $bExpect
do_execsql_test -db db2 3.6 {
INSERT INTO x1 VALUES(5, 6);
COMMIT;
SELECT * FROM x1;
} {1 2 3 4 5 6}
# 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 x1 VALUES(7, 8);
}
after 2000
db eval {
COMMIT
}
}
after 500 {set ok 1}
vwait ok
db2 timeout 0x7FFFFFFF
do_test 3.7 {
set t [lindex [time { db2 eval { BEGIN EXCLUSIVE } }] 0]
expr ($t>1000000)
} {1}
# Set bExpect to true if calls to xSleep() are expected. Such calls are
# expected unless this is an SQLITE_ENABLE_SETLK_TIMEOUT=1 build.
set bExpect 1
if {$::sqlite_options(setlk_timeout)==1} {
set bExpect 0
}
do_test 3.8 {
expr {$::sleep_count > 0}
} $bExpect
do_execsql_test -db db2 3.9 {
INSERT INTO x1 VALUES(9, 10);
COMMIT;
SELECT * FROM x1;
} {1 2 3 4 5 6 7 8 9 10}
db2 close
tvfs delete
finish_test

260
test/walsetlk2.test Normal file
View File

@@ -0,0 +1,260 @@
# 2025 Jan 24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# TESTRUNNER: slow
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set testprefix walsetlk2
ifcapable !wal {finish_test ; return }
ifcapable !setlk_timeout {finish_test ; return }
#-------------------------------------------------------------------------
# Check that xShmLock calls are as expected for write transactions in
# setlk mode.
#
reset_db
do_execsql_test 1.0 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
} {wal}
db close
testvfs tvfs
tvfs script xShmLock_callback
tvfs filter xShmLock
set ::xshmlock [list]
proc xShmLock_callback {method path name detail} {
lappend ::xshmlock $detail
}
sqlite3 db test.db -vfs tvfs
db timeout 1000
do_execsql_test 1.1 {
SELECT * FROM t1
} {1 2 3}
do_execsql_test 1.2 {
INSERT INTO t1 VALUES(4, 5, 6);
}
set ::xshmlock [list]
do_execsql_test 1.3 {
INSERT INTO t1 VALUES(7, 8, 9);
}
do_test 1.4 {
set ::xshmlock
} [list \
{0 1 lock exclusive} \
{4 1 lock exclusive} {4 1 unlock exclusive} \
{4 1 lock shared} \
{0 1 unlock exclusive} \
{4 1 unlock shared}
]
do_execsql_test 1.5.1 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8 9}
set ::xshmlock [list]
do_execsql_test 1.5.2 {
INSERT INTO t1 VALUES(10, 11, 12);
}
do_test 1.5.3 {
set ::xshmlock
} [list \
{0 1 lock exclusive} \
{4 1 lock shared} \
{0 1 unlock exclusive} \
{4 1 unlock shared}
]
db close
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
}
db close
}
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
}
db close
}
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}
#-------------------------------------------------------------------------
# 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
}
db close
}
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
}
db close
}
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

135
test/walsetlk3.test Normal file
View File

@@ -0,0 +1,135 @@
# 2020 May 06
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# TESTRUNNER: slow
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set testprefix walsetlk3
ifcapable !wal {finish_test ; return }
ifcapable !setlk_timeout {finish_test ; return }
do_execsql_test 1.0 {
CREATE TABLE t1(x, y);
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
} {wal}
db close
proc sql_block_on_close {sql} {
testfixture_nb done [string map [list %SQL% $sql] {
testvfs tvfs
tvfs script xWrite
tvfs filter xWrite
set ::delay_done 0
proc xWrite {method fname args} {
if {[file tail $fname]=="test.db" && $::delay_done==0} {
after 3000
set ::delay_done 1
}
return 0
}
sqlite3 db test.db -vfs tvfs
db eval {%SQL%}
db close
}]
}
# Start a second process that writes to the db, then blocks within the
# [db close] holding an EXCLUSIVE on the db in order to checkpoint and
# delete the wal file. Then try to read the db.
#
# Without the SQLITE_SETLK_BLOCK_ON_CONNECT flag, this should fail with
# SQLITE_BUSY.
#
sql_block_on_close {
INSERT INTO t1 VALUES(5, 6);
INSERT INTO t1 VALUES(7, 8);
}
after 500 {set ok 1}
vwait ok
sqlite3 db test.db
sqlite3_setlk_timeout db 2000
do_catchsql_test 1.1 {
SELECT * FROM t1
} {1 {database is locked}}
vwait ::done
# But with SQLITE_SETLK_BLOCK_ON_CONNECT flag, it should succeed.
#
sql_block_on_close {
INSERT INTO t1 VALUES(9, 10);
INSERT INTO t1 VALUES(11, 12);
}
after 500 {set ok 1}
vwait ok
sqlite3 db test.db
sqlite3_setlk_timeout -block db 2000
do_catchsql_test 1.2 {
SELECT * FROM t1
} {0 {1 2 3 4 5 6 7 8 9 10 11 12}}
vwait ::done
#-------------------------------------------------------------------------
# Check that the SQLITE_SETLK_BLOCK_ON_CONNECT does not cause connections
# to block when taking a SHARED lock on a rollback mode database.
#
reset_db
do_execsql_test 2.1 {
CREATE TABLE x1(a);
INSERT INTO x1 VALUES(1), (2), (3);
}
proc sql_block_on_write {sql} {
testfixture_nb done [string map [list %SQL% $sql] {
sqlite3 db test.db
db eval "BEGIN EXCLUSIVE"
db eval {%SQL%}
after 3000
db eval COMMIT
db close
}]
}
db close
sql_block_on_write {
INSERT INTO x1 VALUES(4);
}
after 500 {set ok 1}
vwait ok
sqlite3 db test.db
sqlite3_setlk_timeout -block db 2000
do_catchsql_test 2.2 {
SELECT * FROM x1
} {1 {database is locked}}
vwait ::done
after 500 {set ok 1}
vwait ok
do_catchsql_test 2.3 {
SELECT * FROM x1
} {0 {1 2 3 4}}
finish_test

View File

@@ -115,7 +115,12 @@ do_test 1.6 {
db3 close
foreach tn {1a 1b 1c 1d 1e 1f} {
# winrt platforms do not handle paths with unix-style '/' directory separators.
#
set lUri [list 1a 1b 1c 1d 1e 1f]
ifcapable winrt { set lUri [list 1a 1c 1e] }
foreach tn $lUri {
sqlite3 db3 $uri($tn) -vfs win32-longpath -uri 1 -translatefilename 0
do_test 1.7.$tn {

View File

@@ -167,6 +167,7 @@ set boolean_defnil_options {
SQLITE_ENABLE_RBU
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_SESSION
SQLITE_ENABLE_SETLK_TIMEOUT
SQLITE_ENABLE_SNAPSHOT
SQLITE_ENABLE_SORTER_REFERENCES
SQLITE_ENABLE_SQLLOG