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:
10
Makefile.msc
10
Makefile.msc
@@ -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 ################################
|
||||
###############################################################################
|
||||
|
||||
54
manifest
54
manifest
@@ -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.
|
||||
|
||||
@@ -1 +1 @@
|
||||
742827f049768c4f69ccdfaadfad339aaad3bc126d3a68b90cfea01d825bf7ce
|
||||
e88212b10a7829ff42ef51a02863d788c929e54161faf492f9ef2ad90fd7074e
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
34
src/main.c
34
src/main.c
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 || (
|
||||
|
||||
941
src/os_win.c
941
src/os_win.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
88
src/test1.c
88
src/test1.c
@@ -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 },
|
||||
|
||||
@@ -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), \
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -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;
|
||||
|
||||
25
src/wal.c
25
src/wal.c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {}}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
260
test/walsetlk2.test
Normal 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
135
test/walsetlk3.test
Normal 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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user