rugged 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -0
- data/README.md +3 -3
- data/ext/rugged/rugged.c +7 -4
- data/ext/rugged/rugged_commit.c +1 -1
- data/ext/rugged/rugged_config.c +1 -1
- data/ext/rugged/rugged_object.c +1 -1
- data/ext/rugged/rugged_remote.c +32 -2
- data/ext/rugged/rugged_repo.c +13 -3
- data/lib/rugged/commit.rb +17 -4
- data/lib/rugged/repository.rb +7 -8
- data/lib/rugged/submodule_collection.rb +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +41 -74
- data/vendor/libgit2/COPYING +109 -1
- data/vendor/libgit2/cmake/{Modules/AddCFlagIfSupported.cmake → AddCFlagIfSupported.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/EnableWarnings.cmake → EnableWarnings.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindCoreFoundation.cmake → FindCoreFoundation.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindGSSAPI.cmake → FindGSSAPI.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindGSSFramework.cmake → FindGSSFramework.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindHTTP_Parser.cmake → FindHTTP_Parser.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindIconv.cmake → FindIconv.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPCRE.cmake → FindPCRE.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPCRE2.cmake → FindPCRE2.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPkgLibraries.cmake → FindPkgLibraries.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindSecurity.cmake → FindSecurity.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindStatNsec.cmake → FindStatNsec.cmake} +0 -0
- data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
- data/vendor/libgit2/cmake/{Modules/FindmbedTLS.cmake → FindmbedTLS.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/IdeSplitSources.cmake → IdeSplitSources.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/PkgBuildConfig.cmake → PkgBuildConfig.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/SanitizeBool.cmake → SanitizeBool.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/SelectGSSAPI.cmake → SelectGSSAPI.cmake} +18 -26
- data/vendor/libgit2/cmake/{Modules/SelectHTTPSBackend.cmake → SelectHTTPSBackend.cmake} +29 -32
- data/vendor/libgit2/cmake/{Modules/SelectHashes.cmake → SelectHashes.cmake} +21 -28
- data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +4 -3
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +24 -10
- data/vendor/libgit2/deps/ntlmclient/compat.h +0 -27
- data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
- data/vendor/libgit2/deps/ntlmclient/ntlm.c +164 -135
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +13 -9
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +16 -3
- data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
- data/vendor/libgit2/deps/ntlmclient/util.c +15 -1
- data/vendor/libgit2/deps/ntlmclient/util.h +2 -1
- data/vendor/libgit2/deps/pcre/LICENCE +93 -0
- data/vendor/libgit2/deps/pcre/pcre.h +2 -2
- data/vendor/libgit2/deps/pcre/pcre_compile.c +29 -17
- data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +4 -4
- data/vendor/libgit2/deps/pcre/pcreposix.c +2 -3
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -5
- data/vendor/libgit2/deps/zlib/deflate.c +1 -0
- data/vendor/libgit2/include/git2/annotated_commit.h +1 -1
- data/vendor/libgit2/include/git2/apply.h +2 -0
- data/vendor/libgit2/include/git2/attr.h +89 -0
- data/vendor/libgit2/include/git2/blame.h +95 -42
- data/vendor/libgit2/include/git2/blob.h +31 -3
- data/vendor/libgit2/include/git2/branch.h +25 -0
- data/vendor/libgit2/include/git2/cert.h +42 -5
- data/vendor/libgit2/include/git2/checkout.h +28 -12
- data/vendor/libgit2/include/git2/commit.h +35 -19
- data/vendor/libgit2/include/git2/common.h +33 -6
- data/vendor/libgit2/include/git2/config.h +1 -1
- data/vendor/libgit2/include/git2/deprecated.h +248 -8
- data/vendor/libgit2/include/git2/diff.h +35 -20
- data/vendor/libgit2/include/git2/errors.h +8 -7
- data/vendor/libgit2/include/git2/filter.h +57 -17
- data/vendor/libgit2/include/git2/graph.h +20 -2
- data/vendor/libgit2/include/git2/index.h +4 -5
- data/vendor/libgit2/include/git2/indexer.h +2 -1
- data/vendor/libgit2/include/git2/odb.h +44 -20
- data/vendor/libgit2/include/git2/pack.h +1 -1
- data/vendor/libgit2/include/git2/patch.h +8 -0
- data/vendor/libgit2/include/git2/rebase.h +25 -1
- data/vendor/libgit2/include/git2/refs.h +9 -5
- data/vendor/libgit2/include/git2/remote.h +59 -6
- data/vendor/libgit2/include/git2/repository.h +95 -52
- data/vendor/libgit2/include/git2/revparse.h +5 -5
- data/vendor/libgit2/include/git2/status.h +115 -59
- data/vendor/libgit2/include/git2/strarray.h +6 -10
- data/vendor/libgit2/include/git2/submodule.h +9 -0
- data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
- data/vendor/libgit2/include/git2/sys/filter.h +49 -28
- data/vendor/libgit2/include/git2/sys/midx.h +74 -0
- data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -0
- data/vendor/libgit2/include/git2/sys/transport.h +1 -0
- data/vendor/libgit2/include/git2/tag.h +12 -0
- data/vendor/libgit2/include/git2/transport.h +1 -1
- data/vendor/libgit2/include/git2/tree.h +2 -14
- data/vendor/libgit2/include/git2/types.h +9 -0
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/include/git2/worktree.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +77 -44
- data/vendor/libgit2/src/alloc.c +21 -8
- data/vendor/libgit2/src/allocators/failalloc.c +92 -0
- data/vendor/libgit2/src/allocators/failalloc.h +23 -0
- data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
- data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
- data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
- data/vendor/libgit2/src/annotated_commit.c +21 -9
- data/vendor/libgit2/src/apply.c +21 -8
- data/vendor/libgit2/src/array.h +11 -11
- data/vendor/libgit2/src/assert_safe.h +58 -0
- data/vendor/libgit2/src/attr.c +181 -74
- data/vendor/libgit2/src/attr_file.c +92 -42
- data/vendor/libgit2/src/attr_file.h +32 -11
- data/vendor/libgit2/src/attrcache.c +44 -40
- data/vendor/libgit2/src/attrcache.h +4 -5
- data/vendor/libgit2/src/blame.c +28 -15
- data/vendor/libgit2/src/blame_git.c +6 -3
- data/vendor/libgit2/src/blob.c +46 -24
- data/vendor/libgit2/src/branch.c +87 -37
- data/vendor/libgit2/src/buffer.c +339 -27
- data/vendor/libgit2/src/buffer.h +153 -2
- data/vendor/libgit2/src/cache.c +3 -24
- data/vendor/libgit2/src/cache.h +7 -7
- data/vendor/libgit2/src/cc-compat.h +10 -2
- data/vendor/libgit2/src/checkout.c +97 -98
- data/vendor/libgit2/src/cherrypick.c +8 -2
- data/vendor/libgit2/src/clone.c +104 -29
- data/vendor/libgit2/src/commit.c +41 -28
- data/vendor/libgit2/src/commit_graph.c +1209 -0
- data/vendor/libgit2/src/commit_graph.h +162 -0
- data/vendor/libgit2/src/commit_list.c +46 -0
- data/vendor/libgit2/src/commit_list.h +2 -0
- data/vendor/libgit2/src/common.h +26 -2
- data/vendor/libgit2/src/config.c +40 -22
- data/vendor/libgit2/src/config_cache.c +9 -4
- data/vendor/libgit2/src/config_entries.c +35 -27
- data/vendor/libgit2/src/config_file.c +25 -8
- data/vendor/libgit2/src/config_parse.c +5 -7
- data/vendor/libgit2/src/config_snapshot.c +2 -1
- data/vendor/libgit2/src/crlf.c +16 -6
- data/vendor/libgit2/src/date.c +4 -3
- data/vendor/libgit2/src/delta.c +1 -1
- data/vendor/libgit2/src/describe.c +11 -4
- data/vendor/libgit2/src/diff.c +23 -19
- data/vendor/libgit2/src/diff_driver.c +21 -17
- data/vendor/libgit2/src/diff_file.c +5 -7
- data/vendor/libgit2/src/diff_generate.c +56 -28
- data/vendor/libgit2/src/diff_parse.c +2 -3
- data/vendor/libgit2/src/diff_print.c +81 -65
- data/vendor/libgit2/src/diff_stats.c +19 -16
- data/vendor/libgit2/src/diff_tform.c +13 -13
- data/vendor/libgit2/src/diff_xdiff.c +4 -2
- data/vendor/libgit2/src/diff_xdiff.h +1 -1
- data/vendor/libgit2/src/errors.c +26 -19
- data/vendor/libgit2/src/features.h.in +5 -1
- data/vendor/libgit2/src/fetch.c +7 -2
- data/vendor/libgit2/src/fetchhead.c +8 -4
- data/vendor/libgit2/src/filebuf.c +9 -7
- data/vendor/libgit2/src/filter.c +209 -113
- data/vendor/libgit2/src/filter.h +24 -5
- data/vendor/libgit2/src/futils.c +8 -8
- data/vendor/libgit2/src/futils.h +4 -4
- data/vendor/libgit2/src/graph.c +64 -9
- data/vendor/libgit2/src/hash/sha1/collisiondetect.c +3 -3
- data/vendor/libgit2/src/hash/sha1/common_crypto.c +3 -3
- data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +12 -12
- data/vendor/libgit2/src/hash/sha1/openssl.c +3 -3
- data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +0 -2
- data/vendor/libgit2/src/hash/sha1/win32.c +15 -11
- data/vendor/libgit2/src/hash.c +16 -13
- data/vendor/libgit2/src/hash.h +1 -1
- data/vendor/libgit2/src/hashsig.c +23 -10
- data/vendor/libgit2/src/ident.c +13 -3
- data/vendor/libgit2/src/idxmap.c +0 -22
- data/vendor/libgit2/src/ignore.c +35 -19
- data/vendor/libgit2/src/index.c +126 -84
- data/vendor/libgit2/src/index.h +1 -1
- data/vendor/libgit2/src/indexer.c +60 -36
- data/vendor/libgit2/src/integer.h +79 -2
- data/vendor/libgit2/src/iterator.c +40 -28
- data/vendor/libgit2/src/iterator.h +1 -1
- data/vendor/libgit2/src/khash.h +2 -11
- data/vendor/libgit2/src/{settings.c → libgit2.c} +125 -49
- data/vendor/libgit2/src/libgit2.h +15 -0
- data/vendor/libgit2/src/mailmap.c +23 -10
- data/vendor/libgit2/src/map.h +3 -3
- data/vendor/libgit2/src/merge.c +108 -46
- data/vendor/libgit2/src/merge.h +2 -1
- data/vendor/libgit2/src/merge_driver.c +19 -13
- data/vendor/libgit2/src/merge_file.c +15 -9
- data/vendor/libgit2/src/message.c +3 -1
- data/vendor/libgit2/src/midx.c +879 -0
- data/vendor/libgit2/src/midx.h +110 -0
- data/vendor/libgit2/src/mwindow.c +214 -95
- data/vendor/libgit2/src/mwindow.h +3 -3
- data/vendor/libgit2/src/net.c +133 -4
- data/vendor/libgit2/src/net.h +16 -2
- data/vendor/libgit2/src/netops.c +6 -4
- data/vendor/libgit2/src/netops.h +2 -2
- data/vendor/libgit2/src/notes.c +10 -10
- data/vendor/libgit2/src/object.c +24 -15
- data/vendor/libgit2/src/odb.c +298 -57
- data/vendor/libgit2/src/odb.h +16 -2
- data/vendor/libgit2/src/odb_loose.c +31 -21
- data/vendor/libgit2/src/odb_mempack.c +3 -1
- data/vendor/libgit2/src/odb_pack.c +391 -114
- data/vendor/libgit2/src/oid.c +7 -4
- data/vendor/libgit2/src/pack-objects.c +83 -69
- data/vendor/libgit2/src/pack.c +383 -150
- data/vendor/libgit2/src/pack.h +44 -9
- data/vendor/libgit2/src/patch.c +14 -7
- data/vendor/libgit2/src/patch_generate.c +3 -5
- data/vendor/libgit2/src/patch_parse.c +6 -3
- data/vendor/libgit2/src/path.c +102 -57
- data/vendor/libgit2/src/path.h +79 -6
- data/vendor/libgit2/src/pathspec.c +12 -11
- data/vendor/libgit2/src/pool.c +34 -22
- data/vendor/libgit2/src/pool.h +9 -1
- data/vendor/libgit2/src/posix.c +43 -12
- data/vendor/libgit2/src/posix.h +9 -0
- data/vendor/libgit2/src/proxy.c +2 -0
- data/vendor/libgit2/src/push.c +2 -0
- data/vendor/libgit2/src/reader.c +10 -6
- data/vendor/libgit2/src/rebase.c +95 -49
- data/vendor/libgit2/src/refdb.c +165 -13
- data/vendor/libgit2/src/refdb.h +69 -0
- data/vendor/libgit2/src/refdb_fs.c +144 -152
- data/vendor/libgit2/src/reflog.c +21 -20
- data/vendor/libgit2/src/refs.c +151 -231
- data/vendor/libgit2/src/refs.h +2 -20
- data/vendor/libgit2/src/refspec.c +80 -44
- data/vendor/libgit2/src/regexp.c +2 -2
- data/vendor/libgit2/src/remote.c +312 -121
- data/vendor/libgit2/src/remote.h +2 -1
- data/vendor/libgit2/src/repository.c +351 -189
- data/vendor/libgit2/src/repository.h +23 -29
- data/vendor/libgit2/src/reset.c +7 -6
- data/vendor/libgit2/src/revert.c +8 -2
- data/vendor/libgit2/src/revparse.c +19 -13
- data/vendor/libgit2/src/revwalk.c +35 -20
- data/vendor/libgit2/src/runtime.c +162 -0
- data/vendor/libgit2/src/runtime.h +62 -0
- data/vendor/libgit2/src/{refdb_fs.h → settings.h} +3 -11
- data/vendor/libgit2/src/signature.c +6 -5
- data/vendor/libgit2/src/sortedcache.c +2 -3
- data/vendor/libgit2/src/sortedcache.h +10 -8
- data/vendor/libgit2/src/stash.c +7 -3
- data/vendor/libgit2/src/status.c +9 -4
- data/vendor/libgit2/src/strarray.c +64 -0
- data/vendor/libgit2/src/streams/mbedtls.c +14 -17
- data/vendor/libgit2/src/streams/mbedtls.h +1 -1
- data/vendor/libgit2/src/streams/openssl.c +113 -207
- data/vendor/libgit2/src/streams/openssl.h +9 -1
- data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
- data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
- data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
- data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
- data/vendor/libgit2/src/streams/registry.c +10 -9
- data/vendor/libgit2/src/streams/socket.c +6 -2
- data/vendor/libgit2/src/streams/stransport.c +6 -3
- data/vendor/libgit2/src/streams/tls.c +5 -3
- data/vendor/libgit2/src/submodule.c +134 -66
- data/vendor/libgit2/src/submodule.h +9 -9
- data/vendor/libgit2/src/sysdir.c +8 -26
- data/vendor/libgit2/src/sysdir.h +0 -11
- data/vendor/libgit2/src/tag.c +49 -11
- data/vendor/libgit2/src/thread.c +140 -0
- data/vendor/libgit2/src/thread.h +479 -0
- data/vendor/libgit2/src/threadstate.c +83 -0
- data/vendor/libgit2/src/threadstate.h +24 -0
- data/vendor/libgit2/src/trace.c +2 -2
- data/vendor/libgit2/src/trace.h +17 -13
- data/vendor/libgit2/src/transaction.c +21 -9
- data/vendor/libgit2/src/transport.c +3 -3
- data/vendor/libgit2/src/transports/auth.c +1 -1
- data/vendor/libgit2/src/transports/auth_negotiate.c +11 -4
- data/vendor/libgit2/src/transports/auth_ntlm.c +10 -6
- data/vendor/libgit2/src/transports/credential.c +17 -7
- data/vendor/libgit2/src/transports/credential_helpers.c +2 -0
- data/vendor/libgit2/src/transports/git.c +1 -3
- data/vendor/libgit2/src/transports/http.c +19 -17
- data/vendor/libgit2/src/transports/http.h +1 -0
- data/vendor/libgit2/src/transports/httpclient.c +84 -42
- data/vendor/libgit2/src/transports/httpclient.h +1 -1
- data/vendor/libgit2/src/transports/local.c +5 -5
- data/vendor/libgit2/src/transports/smart.c +14 -9
- data/vendor/libgit2/src/transports/smart.h +1 -1
- data/vendor/libgit2/src/transports/smart_protocol.c +11 -5
- data/vendor/libgit2/src/transports/ssh.c +51 -17
- data/vendor/libgit2/src/transports/winhttp.c +156 -88
- data/vendor/libgit2/src/tree.c +100 -77
- data/vendor/libgit2/src/tree.h +1 -0
- data/vendor/libgit2/src/tsort.c +0 -2
- data/vendor/libgit2/src/unix/map.c +3 -1
- data/vendor/libgit2/src/unix/posix.h +16 -1
- data/vendor/libgit2/src/unix/pthread.h +2 -1
- data/vendor/libgit2/src/utf8.c +150 -0
- data/vendor/libgit2/src/utf8.h +52 -0
- data/vendor/libgit2/src/util.c +74 -183
- data/vendor/libgit2/src/util.h +33 -39
- data/vendor/libgit2/src/vector.c +23 -19
- data/vendor/libgit2/src/vector.h +4 -2
- data/vendor/libgit2/src/win32/findfile.c +4 -2
- data/vendor/libgit2/src/win32/git2.rc +18 -3
- data/vendor/libgit2/src/win32/map.c +1 -1
- data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
- data/vendor/libgit2/src/win32/path_w32.c +23 -25
- data/vendor/libgit2/src/win32/path_w32.h +0 -1
- data/vendor/libgit2/src/win32/posix_w32.c +77 -1
- data/vendor/libgit2/src/win32/precompiled.h +0 -1
- data/vendor/libgit2/src/win32/reparse.h +4 -4
- data/vendor/libgit2/src/win32/thread.c +24 -15
- data/vendor/libgit2/src/win32/thread.h +1 -1
- data/vendor/libgit2/src/win32/w32_buffer.c +3 -3
- data/vendor/libgit2/src/win32/w32_common.h +18 -9
- data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
- data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
- data/vendor/libgit2/src/win32/w32_util.h +6 -6
- data/vendor/libgit2/src/worktree.c +37 -15
- data/vendor/libgit2/src/zstream.c +1 -1
- metadata +56 -38
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +0 -29
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +0 -96
- data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
- data/vendor/libgit2/src/buf_text.c +0 -316
- data/vendor/libgit2/src/buf_text.h +0 -122
- data/vendor/libgit2/src/global.c +0 -361
- data/vendor/libgit2/src/global.h +0 -41
- data/vendor/libgit2/src/thread-utils.c +0 -58
- data/vendor/libgit2/src/thread-utils.h +0 -246
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
- data/vendor/libgit2/src/win32/w32_stack.c +0 -188
- data/vendor/libgit2/src/win32/w32_stack.h +0 -140
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
5
|
+
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#ifndef INCLUDE_midx_h__
|
|
9
|
+
#define INCLUDE_midx_h__
|
|
10
|
+
|
|
11
|
+
#include "common.h"
|
|
12
|
+
|
|
13
|
+
#include <ctype.h>
|
|
14
|
+
|
|
15
|
+
#include "git2/sys/midx.h"
|
|
16
|
+
|
|
17
|
+
#include "map.h"
|
|
18
|
+
#include "mwindow.h"
|
|
19
|
+
#include "odb.h"
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* A multi-pack-index file.
|
|
23
|
+
*
|
|
24
|
+
* This file contains a merged index for multiple independent .pack files. This
|
|
25
|
+
* can help speed up locating objects without requiring a garbage collection
|
|
26
|
+
* cycle to create a single .pack file.
|
|
27
|
+
*
|
|
28
|
+
* Support for this feature was added in git 2.21, and requires the
|
|
29
|
+
* `core.multiPackIndex` config option to be set.
|
|
30
|
+
*/
|
|
31
|
+
typedef struct git_midx_file {
|
|
32
|
+
git_map index_map;
|
|
33
|
+
|
|
34
|
+
/* The table of Packfile Names. */
|
|
35
|
+
git_vector packfile_names;
|
|
36
|
+
|
|
37
|
+
/* The OID Fanout table. */
|
|
38
|
+
const uint32_t *oid_fanout;
|
|
39
|
+
/* The total number of objects in the index. */
|
|
40
|
+
uint32_t num_objects;
|
|
41
|
+
|
|
42
|
+
/* The OID Lookup table. */
|
|
43
|
+
git_oid *oid_lookup;
|
|
44
|
+
|
|
45
|
+
/* The Object Offsets table. Each entry has two 4-byte fields with the pack index and the offset. */
|
|
46
|
+
const unsigned char *object_offsets;
|
|
47
|
+
|
|
48
|
+
/* The Object Large Offsets table. */
|
|
49
|
+
const unsigned char *object_large_offsets;
|
|
50
|
+
/* The number of entries in the Object Large Offsets table. Each entry has an 8-byte with an offset */
|
|
51
|
+
size_t num_object_large_offsets;
|
|
52
|
+
|
|
53
|
+
/* The trailer of the file. Contains the SHA1-checksum of the whole file. */
|
|
54
|
+
git_oid checksum;
|
|
55
|
+
|
|
56
|
+
/* something like ".git/objects/pack/multi-pack-index". */
|
|
57
|
+
git_buf filename;
|
|
58
|
+
} git_midx_file;
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* An entry in the multi-pack-index file. Similar in purpose to git_pack_entry.
|
|
62
|
+
*/
|
|
63
|
+
typedef struct git_midx_entry {
|
|
64
|
+
/* The index within idx->packfile_names where the packfile name can be found. */
|
|
65
|
+
size_t pack_index;
|
|
66
|
+
/* The offset within the .pack file where the requested object is found. */
|
|
67
|
+
off64_t offset;
|
|
68
|
+
/* The SHA-1 hash of the requested object. */
|
|
69
|
+
git_oid sha1;
|
|
70
|
+
} git_midx_entry;
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
* A writer for `multi-pack-index` files.
|
|
74
|
+
*/
|
|
75
|
+
struct git_midx_writer {
|
|
76
|
+
/*
|
|
77
|
+
* The path of the directory where the .pack/.idx files are stored. The
|
|
78
|
+
* `multi-pack-index` file will be written to the same directory.
|
|
79
|
+
*/
|
|
80
|
+
git_buf pack_dir;
|
|
81
|
+
|
|
82
|
+
/* The list of `git_pack_file`s. */
|
|
83
|
+
git_vector packs;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
int git_midx_open(
|
|
87
|
+
git_midx_file **idx_out,
|
|
88
|
+
const char *path);
|
|
89
|
+
bool git_midx_needs_refresh(
|
|
90
|
+
const git_midx_file *idx,
|
|
91
|
+
const char *path);
|
|
92
|
+
int git_midx_entry_find(
|
|
93
|
+
git_midx_entry *e,
|
|
94
|
+
git_midx_file *idx,
|
|
95
|
+
const git_oid *short_oid,
|
|
96
|
+
size_t len);
|
|
97
|
+
int git_midx_foreach_entry(
|
|
98
|
+
git_midx_file *idx,
|
|
99
|
+
git_odb_foreach_cb cb,
|
|
100
|
+
void *data);
|
|
101
|
+
int git_midx_close(git_midx_file *idx);
|
|
102
|
+
void git_midx_free(git_midx_file *idx);
|
|
103
|
+
|
|
104
|
+
/* This is exposed for use in the fuzzers. */
|
|
105
|
+
int git_midx_parse(
|
|
106
|
+
git_midx_file *idx,
|
|
107
|
+
const unsigned char *data,
|
|
108
|
+
size_t size);
|
|
109
|
+
|
|
110
|
+
#endif
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#include "vector.h"
|
|
11
11
|
#include "futils.h"
|
|
12
12
|
#include "map.h"
|
|
13
|
-
#include "
|
|
13
|
+
#include "runtime.h"
|
|
14
14
|
#include "strmap.h"
|
|
15
15
|
#include "pack.h"
|
|
16
16
|
|
|
@@ -20,31 +20,45 @@
|
|
|
20
20
|
: 32 * 1024 * 1024)
|
|
21
21
|
|
|
22
22
|
#define DEFAULT_MAPPED_LIMIT \
|
|
23
|
-
((1024 * 1024) * (sizeof(void*) >= 8 ?
|
|
23
|
+
((1024 * 1024) * (sizeof(void*) >= 8 ? UINT64_C(8192) : UINT64_C(256)))
|
|
24
|
+
|
|
25
|
+
/* default is unlimited */
|
|
26
|
+
#define DEFAULT_FILE_LIMIT 0
|
|
24
27
|
|
|
25
28
|
size_t git_mwindow__window_size = DEFAULT_WINDOW_SIZE;
|
|
26
29
|
size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT;
|
|
30
|
+
size_t git_mwindow__file_limit = DEFAULT_FILE_LIMIT;
|
|
31
|
+
|
|
32
|
+
/* Mutex to control access to `git_mwindow__mem_ctl` and `git__pack_cache`. */
|
|
33
|
+
git_mutex git__mwindow_mutex;
|
|
27
34
|
|
|
28
|
-
/* Whenever you want to read or modify this, grab git__mwindow_mutex */
|
|
29
|
-
|
|
35
|
+
/* Whenever you want to read or modify this, grab `git__mwindow_mutex` */
|
|
36
|
+
git_mwindow_ctl git_mwindow__mem_ctl;
|
|
30
37
|
|
|
31
38
|
/* Global list of mwindow files, to open packs once across repos */
|
|
32
39
|
git_strmap *git__pack_cache = NULL;
|
|
33
40
|
|
|
34
|
-
static void
|
|
41
|
+
static void git_mwindow_global_shutdown(void)
|
|
35
42
|
{
|
|
36
43
|
git_strmap *tmp = git__pack_cache;
|
|
37
44
|
|
|
45
|
+
git_mutex_free(&git__mwindow_mutex);
|
|
46
|
+
|
|
38
47
|
git__pack_cache = NULL;
|
|
39
48
|
git_strmap_free(tmp);
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
int git_mwindow_global_init(void)
|
|
43
52
|
{
|
|
44
|
-
|
|
53
|
+
int error;
|
|
54
|
+
|
|
55
|
+
GIT_ASSERT(!git__pack_cache);
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
if ((error = git_mutex_init(&git__mwindow_mutex)) < 0 ||
|
|
58
|
+
(error = git_strmap_new(&git__pack_cache)) < 0)
|
|
59
|
+
return error;
|
|
60
|
+
|
|
61
|
+
return git_runtime_shutdown_register(git_mwindow_global_shutdown);
|
|
48
62
|
}
|
|
49
63
|
|
|
50
64
|
int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
|
|
@@ -65,7 +79,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
|
|
|
65
79
|
git__free(packname);
|
|
66
80
|
|
|
67
81
|
if (pack != NULL) {
|
|
68
|
-
|
|
82
|
+
git_atomic32_inc(&pack->refcount);
|
|
69
83
|
git_mutex_unlock(&git__mwindow_mutex);
|
|
70
84
|
*out = pack;
|
|
71
85
|
return 0;
|
|
@@ -77,62 +91,51 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
|
|
|
77
91
|
return error;
|
|
78
92
|
}
|
|
79
93
|
|
|
80
|
-
|
|
94
|
+
git_atomic32_inc(&pack->refcount);
|
|
81
95
|
|
|
82
96
|
error = git_strmap_set(git__pack_cache, pack->pack_name, pack);
|
|
83
97
|
git_mutex_unlock(&git__mwindow_mutex);
|
|
84
|
-
|
|
85
98
|
if (error < 0) {
|
|
86
|
-
git_packfile_free(pack);
|
|
87
|
-
return
|
|
99
|
+
git_packfile_free(pack, false);
|
|
100
|
+
return error;
|
|
88
101
|
}
|
|
89
102
|
|
|
90
103
|
*out = pack;
|
|
91
104
|
return 0;
|
|
92
105
|
}
|
|
93
106
|
|
|
94
|
-
|
|
107
|
+
int git_mwindow_put_pack(struct git_pack_file *pack)
|
|
95
108
|
{
|
|
96
|
-
int count;
|
|
109
|
+
int count, error;
|
|
110
|
+
struct git_pack_file *pack_to_delete = NULL;
|
|
97
111
|
|
|
98
|
-
if (git_mutex_lock(&git__mwindow_mutex) < 0)
|
|
99
|
-
return;
|
|
112
|
+
if ((error = git_mutex_lock(&git__mwindow_mutex)) < 0)
|
|
113
|
+
return error;
|
|
100
114
|
|
|
101
115
|
/* put before get would be a corrupted state */
|
|
102
|
-
|
|
116
|
+
GIT_ASSERT(git__pack_cache);
|
|
103
117
|
|
|
104
118
|
/* if we cannot find it, the state is corrupted */
|
|
105
|
-
|
|
119
|
+
GIT_ASSERT(git_strmap_exists(git__pack_cache, pack->pack_name));
|
|
106
120
|
|
|
107
|
-
count =
|
|
121
|
+
count = git_atomic32_dec(&pack->refcount);
|
|
108
122
|
if (count == 0) {
|
|
109
123
|
git_strmap_delete(git__pack_cache, pack->pack_name);
|
|
110
|
-
|
|
124
|
+
pack_to_delete = pack;
|
|
111
125
|
}
|
|
112
|
-
|
|
113
126
|
git_mutex_unlock(&git__mwindow_mutex);
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
void git_mwindow_free_all(git_mwindow_file *mwf)
|
|
118
|
-
{
|
|
119
|
-
if (git_mutex_lock(&git__mwindow_mutex)) {
|
|
120
|
-
git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex");
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
git_mwindow_free_all_locked(mwf);
|
|
127
|
+
git_packfile_free(pack_to_delete, false);
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
return 0;
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
/*
|
|
130
133
|
* Free all the windows in a sequence, typically because we're done
|
|
131
|
-
* with the file
|
|
134
|
+
* with the file. Needs to hold the git__mwindow_mutex.
|
|
132
135
|
*/
|
|
133
|
-
|
|
136
|
+
static int git_mwindow_free_all_locked(git_mwindow_file *mwf)
|
|
134
137
|
{
|
|
135
|
-
git_mwindow_ctl *ctl = &
|
|
138
|
+
git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
|
|
136
139
|
size_t i;
|
|
137
140
|
|
|
138
141
|
/*
|
|
@@ -152,7 +155,7 @@ void git_mwindow_free_all_locked(git_mwindow_file *mwf)
|
|
|
152
155
|
|
|
153
156
|
while (mwf->windows) {
|
|
154
157
|
git_mwindow *w = mwf->windows;
|
|
155
|
-
|
|
158
|
+
GIT_ASSERT(w->inuse_cnt == 0);
|
|
156
159
|
|
|
157
160
|
ctl->mapped -= w->window_map.len;
|
|
158
161
|
ctl->open_windows--;
|
|
@@ -162,6 +165,24 @@ void git_mwindow_free_all_locked(git_mwindow_file *mwf)
|
|
|
162
165
|
mwf->windows = w->next;
|
|
163
166
|
git__free(w);
|
|
164
167
|
}
|
|
168
|
+
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
int git_mwindow_free_all(git_mwindow_file *mwf)
|
|
173
|
+
{
|
|
174
|
+
int error;
|
|
175
|
+
|
|
176
|
+
if (git_mutex_lock(&git__mwindow_mutex)) {
|
|
177
|
+
git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex");
|
|
178
|
+
return -1;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
error = git_mwindow_free_all_locked(mwf);
|
|
182
|
+
|
|
183
|
+
git_mutex_unlock(&git__mwindow_mutex);
|
|
184
|
+
|
|
185
|
+
return error;
|
|
165
186
|
}
|
|
166
187
|
|
|
167
188
|
/*
|
|
@@ -174,92 +195,154 @@ int git_mwindow_contains(git_mwindow *win, off64_t offset)
|
|
|
174
195
|
&& offset <= (off64_t)(win_off + win->window_map.len);
|
|
175
196
|
}
|
|
176
197
|
|
|
198
|
+
#define GIT_MWINDOW__LRU -1
|
|
199
|
+
#define GIT_MWINDOW__MRU 1
|
|
200
|
+
|
|
177
201
|
/*
|
|
178
|
-
* Find the least-recently-used window in a file
|
|
202
|
+
* Find the least- or most-recently-used window in a file that is not currently
|
|
203
|
+
* being used. The 'only_unused' flag controls whether the caller requires the
|
|
204
|
+
* file to only have unused windows. If '*out_window' is non-null, it is used as
|
|
205
|
+
* a starting point for the comparison.
|
|
206
|
+
*
|
|
207
|
+
* Returns whether such a window was found in the file.
|
|
179
208
|
*/
|
|
180
|
-
static
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
209
|
+
static bool git_mwindow_scan_recently_used(
|
|
210
|
+
git_mwindow_file *mwf,
|
|
211
|
+
git_mwindow **out_window,
|
|
212
|
+
git_mwindow **out_last,
|
|
213
|
+
bool only_unused,
|
|
214
|
+
int comparison_sign)
|
|
184
215
|
{
|
|
185
|
-
git_mwindow *w, *
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
216
|
+
git_mwindow *w, *w_last;
|
|
217
|
+
git_mwindow *lru_window = NULL, *lru_last = NULL;
|
|
218
|
+
bool found = false;
|
|
219
|
+
|
|
220
|
+
GIT_ASSERT_ARG(mwf);
|
|
221
|
+
GIT_ASSERT_ARG(out_window);
|
|
222
|
+
|
|
223
|
+
lru_window = *out_window;
|
|
224
|
+
if (out_last)
|
|
225
|
+
lru_last = *out_last;
|
|
226
|
+
|
|
227
|
+
for (w_last = NULL, w = mwf->windows; w; w_last = w, w = w->next) {
|
|
228
|
+
if (w->inuse_cnt) {
|
|
229
|
+
if (only_unused)
|
|
230
|
+
return false;
|
|
231
|
+
/* This window is currently being used. Skip it. */
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/*
|
|
236
|
+
* If the current one is more (or less) recent than the last one,
|
|
237
|
+
* store it in the output parameter. If lru_window is NULL,
|
|
238
|
+
* it's the first loop, so store it as well.
|
|
239
|
+
*/
|
|
240
|
+
if (!lru_window ||
|
|
241
|
+
(comparison_sign == GIT_MWINDOW__LRU && lru_window->last_used > w->last_used) ||
|
|
242
|
+
(comparison_sign == GIT_MWINDOW__MRU && lru_window->last_used < w->last_used)) {
|
|
243
|
+
lru_window = w;
|
|
244
|
+
lru_last = w_last;
|
|
245
|
+
found = true;
|
|
198
246
|
}
|
|
199
|
-
w_l = w;
|
|
200
247
|
}
|
|
248
|
+
|
|
249
|
+
if (!found)
|
|
250
|
+
return false;
|
|
251
|
+
|
|
252
|
+
*out_window = lru_window;
|
|
253
|
+
if (out_last)
|
|
254
|
+
*out_last = lru_last;
|
|
255
|
+
return true;
|
|
201
256
|
}
|
|
202
257
|
|
|
203
258
|
/*
|
|
204
|
-
* Close the least recently used window
|
|
205
|
-
* the
|
|
206
|
-
* lock from new_window.
|
|
259
|
+
* Close the least recently used window (that is currently not being used) out
|
|
260
|
+
* of all the files. Called under lock from new_window_locked.
|
|
207
261
|
*/
|
|
208
|
-
static int
|
|
262
|
+
static int git_mwindow_close_lru_window_locked(void)
|
|
209
263
|
{
|
|
210
|
-
git_mwindow_ctl *ctl = &
|
|
264
|
+
git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
|
|
265
|
+
git_mwindow_file *cur;
|
|
211
266
|
size_t i;
|
|
212
|
-
git_mwindow *
|
|
267
|
+
git_mwindow *lru_window = NULL, *lru_last = NULL, **list = NULL;
|
|
213
268
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
for (i = 0; i < ctl->windowfiles.length; ++i) {
|
|
219
|
-
git_mwindow *last = lru_w;
|
|
220
|
-
git_mwindow_file *cur = git_vector_get(&ctl->windowfiles, i);
|
|
221
|
-
git_mwindow_scan_lru(cur, &lru_w, &lru_l);
|
|
222
|
-
if (lru_w != last)
|
|
269
|
+
git_vector_foreach(&ctl->windowfiles, i, cur) {
|
|
270
|
+
if (git_mwindow_scan_recently_used(
|
|
271
|
+
cur, &lru_window, &lru_last, false, GIT_MWINDOW__LRU)) {
|
|
223
272
|
list = &cur->windows;
|
|
273
|
+
}
|
|
224
274
|
}
|
|
225
275
|
|
|
226
|
-
if (!
|
|
276
|
+
if (!lru_window) {
|
|
227
277
|
git_error_set(GIT_ERROR_OS, "failed to close memory window; couldn't find LRU");
|
|
228
278
|
return -1;
|
|
229
279
|
}
|
|
230
280
|
|
|
231
|
-
ctl->mapped -=
|
|
232
|
-
git_futils_mmap_free(&
|
|
281
|
+
ctl->mapped -= lru_window->window_map.len;
|
|
282
|
+
git_futils_mmap_free(&lru_window->window_map);
|
|
233
283
|
|
|
234
|
-
if (
|
|
235
|
-
|
|
284
|
+
if (lru_last)
|
|
285
|
+
lru_last->next = lru_window->next;
|
|
236
286
|
else
|
|
237
|
-
*list =
|
|
287
|
+
*list = lru_window->next;
|
|
238
288
|
|
|
239
|
-
git__free(
|
|
289
|
+
git__free(lru_window);
|
|
240
290
|
ctl->open_windows--;
|
|
241
291
|
|
|
242
292
|
return 0;
|
|
243
293
|
}
|
|
244
294
|
|
|
295
|
+
/*
|
|
296
|
+
* Finds the file that does not have any open windows AND whose
|
|
297
|
+
* most-recently-used window is the least-recently used one across all
|
|
298
|
+
* currently open files.
|
|
299
|
+
*
|
|
300
|
+
* Called under lock from new_window_locked.
|
|
301
|
+
*/
|
|
302
|
+
static int git_mwindow_find_lru_file_locked(git_mwindow_file **out)
|
|
303
|
+
{
|
|
304
|
+
git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
|
|
305
|
+
git_mwindow_file *lru_file = NULL, *current_file = NULL;
|
|
306
|
+
git_mwindow *lru_window = NULL;
|
|
307
|
+
size_t i;
|
|
308
|
+
|
|
309
|
+
git_vector_foreach(&ctl->windowfiles, i, current_file) {
|
|
310
|
+
git_mwindow *mru_window = NULL;
|
|
311
|
+
if (!git_mwindow_scan_recently_used(
|
|
312
|
+
current_file, &mru_window, NULL, true, GIT_MWINDOW__MRU)) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (!lru_window || lru_window->last_used > mru_window->last_used) {
|
|
316
|
+
lru_window = mru_window;
|
|
317
|
+
lru_file = current_file;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (!lru_file) {
|
|
322
|
+
git_error_set(GIT_ERROR_OS, "failed to close memory window file; couldn't find LRU");
|
|
323
|
+
return -1;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
*out = lru_file;
|
|
327
|
+
return 0;
|
|
328
|
+
}
|
|
329
|
+
|
|
245
330
|
/* This gets called under lock from git_mwindow_open */
|
|
246
|
-
static git_mwindow *
|
|
247
|
-
git_mwindow_file *mwf,
|
|
331
|
+
static git_mwindow *new_window_locked(
|
|
248
332
|
git_file fd,
|
|
249
333
|
off64_t size,
|
|
250
334
|
off64_t offset)
|
|
251
335
|
{
|
|
252
|
-
git_mwindow_ctl *ctl = &
|
|
336
|
+
git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
|
|
253
337
|
size_t walign = git_mwindow__window_size / 2;
|
|
254
338
|
off64_t len;
|
|
255
339
|
git_mwindow *w;
|
|
256
340
|
|
|
257
|
-
w =
|
|
341
|
+
w = git__calloc(1, sizeof(*w));
|
|
258
342
|
|
|
259
343
|
if (w == NULL)
|
|
260
344
|
return NULL;
|
|
261
345
|
|
|
262
|
-
memset(w, 0x0, sizeof(*w));
|
|
263
346
|
w->offset = (offset / walign) * walign;
|
|
264
347
|
|
|
265
348
|
len = size - w->offset;
|
|
@@ -269,7 +352,7 @@ static git_mwindow *new_window(
|
|
|
269
352
|
ctl->mapped += (size_t)len;
|
|
270
353
|
|
|
271
354
|
while (git_mwindow__mapped_limit < ctl->mapped &&
|
|
272
|
-
|
|
355
|
+
git_mwindow_close_lru_window_locked() == 0) /* nop */;
|
|
273
356
|
|
|
274
357
|
/*
|
|
275
358
|
* We treat `mapped_limit` as a soft limit. If we can't find a
|
|
@@ -283,7 +366,7 @@ static git_mwindow *new_window(
|
|
|
283
366
|
* we're below our soft limits, so free up what we can and try again.
|
|
284
367
|
*/
|
|
285
368
|
|
|
286
|
-
while (
|
|
369
|
+
while (git_mwindow_close_lru_window_locked() == 0)
|
|
287
370
|
/* nop */;
|
|
288
371
|
|
|
289
372
|
if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < 0) {
|
|
@@ -315,7 +398,7 @@ unsigned char *git_mwindow_open(
|
|
|
315
398
|
size_t extra,
|
|
316
399
|
unsigned int *left)
|
|
317
400
|
{
|
|
318
|
-
git_mwindow_ctl *ctl = &
|
|
401
|
+
git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
|
|
319
402
|
git_mwindow *w = *cursor;
|
|
320
403
|
|
|
321
404
|
if (git_mutex_lock(&git__mwindow_mutex)) {
|
|
@@ -339,7 +422,7 @@ unsigned char *git_mwindow_open(
|
|
|
339
422
|
* one.
|
|
340
423
|
*/
|
|
341
424
|
if (!w) {
|
|
342
|
-
w =
|
|
425
|
+
w = new_window_locked(mwf->fd, mwf->size, offset);
|
|
343
426
|
if (w == NULL) {
|
|
344
427
|
git_mutex_unlock(&git__mwindow_mutex);
|
|
345
428
|
return NULL;
|
|
@@ -367,8 +450,11 @@ unsigned char *git_mwindow_open(
|
|
|
367
450
|
|
|
368
451
|
int git_mwindow_file_register(git_mwindow_file *mwf)
|
|
369
452
|
{
|
|
370
|
-
|
|
371
|
-
|
|
453
|
+
git_vector closed_files = GIT_VECTOR_INIT;
|
|
454
|
+
git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
|
|
455
|
+
int error;
|
|
456
|
+
size_t i;
|
|
457
|
+
git_mwindow_file *closed_file = NULL;
|
|
372
458
|
|
|
373
459
|
if (git_mutex_lock(&git__mwindow_mutex)) {
|
|
374
460
|
git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex");
|
|
@@ -376,20 +462,53 @@ int git_mwindow_file_register(git_mwindow_file *mwf)
|
|
|
376
462
|
}
|
|
377
463
|
|
|
378
464
|
if (ctl->windowfiles.length == 0 &&
|
|
379
|
-
git_vector_init(&ctl->windowfiles, 8, NULL) < 0) {
|
|
465
|
+
(error = git_vector_init(&ctl->windowfiles, 8, NULL)) < 0) {
|
|
380
466
|
git_mutex_unlock(&git__mwindow_mutex);
|
|
381
|
-
|
|
467
|
+
goto cleanup;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (git_mwindow__file_limit) {
|
|
471
|
+
git_mwindow_file *lru_file;
|
|
472
|
+
while (git_mwindow__file_limit <= ctl->windowfiles.length &&
|
|
473
|
+
git_mwindow_find_lru_file_locked(&lru_file) == 0) {
|
|
474
|
+
if ((error = git_vector_insert(&closed_files, lru_file)) < 0) {
|
|
475
|
+
/*
|
|
476
|
+
* Exceeding the file limit seems preferrable to being open to
|
|
477
|
+
* data races that can end up corrupting the heap.
|
|
478
|
+
*/
|
|
479
|
+
break;
|
|
480
|
+
}
|
|
481
|
+
git_mwindow_free_all_locked(lru_file);
|
|
482
|
+
}
|
|
382
483
|
}
|
|
383
484
|
|
|
384
|
-
|
|
485
|
+
error = git_vector_insert(&ctl->windowfiles, mwf);
|
|
385
486
|
git_mutex_unlock(&git__mwindow_mutex);
|
|
487
|
+
if (error < 0)
|
|
488
|
+
goto cleanup;
|
|
489
|
+
|
|
490
|
+
/*
|
|
491
|
+
* Once we have released the global windowfiles lock, we can close each
|
|
492
|
+
* individual file. Before doing so, acquire that file's lock to avoid
|
|
493
|
+
* closing a file that is currently being used.
|
|
494
|
+
*/
|
|
495
|
+
git_vector_foreach(&closed_files, i, closed_file) {
|
|
496
|
+
error = git_mutex_lock(&closed_file->lock);
|
|
497
|
+
if (error < 0)
|
|
498
|
+
continue;
|
|
499
|
+
p_close(closed_file->fd);
|
|
500
|
+
closed_file->fd = -1;
|
|
501
|
+
git_mutex_unlock(&closed_file->lock);
|
|
502
|
+
}
|
|
386
503
|
|
|
387
|
-
|
|
504
|
+
cleanup:
|
|
505
|
+
git_vector_free(&closed_files);
|
|
506
|
+
return error;
|
|
388
507
|
}
|
|
389
508
|
|
|
390
509
|
void git_mwindow_file_deregister(git_mwindow_file *mwf)
|
|
391
510
|
{
|
|
392
|
-
git_mwindow_ctl *ctl = &
|
|
511
|
+
git_mwindow_ctl *ctl = &git_mwindow__mem_ctl;
|
|
393
512
|
git_mwindow_file *cur;
|
|
394
513
|
size_t i;
|
|
395
514
|
|