diff --git a/src/libfetchers/git-utils.cc b/src/libfetchers/git-utils.cc index 5306d8780..fb5341599 100644 --- a/src/libfetchers/git-utils.cc +++ b/src/libfetchers/git-utils.cc @@ -211,8 +211,12 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this try { PackBuilder packBuilder; git_packbuilder_new(Setter(packBuilder), *this); + checkInterrupt(); git_mempack_write_thin_pack(mempack_backend, packBuilder.get()); + checkInterrupt(); + // TODO make git_packbuilder_write_buf() interruptible git_packbuilder_write_buf(&buf, packBuilder.get()); + checkInterrupt(); std::string repo_path = std::string(git_repository_path(repo.get())); while (!repo_path.empty() && repo_path.back() == '/') @@ -224,8 +228,10 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this git_indexer_progress stats; if (git_indexer_new(Setter(indexer), pack_dir_path.c_str(), 0, nullptr, nullptr)) throw Error("creating git packfile indexer: %s", git_error_last()->message); + // TODO: feed buf in (fairly large) chunk to make this interruptible if (git_indexer_append(indexer.get(), buf.ptr, buf.size, &stats)) throw Error("appending to git packfile index: %s", git_error_last()->message); + checkInterrupt(); if (git_indexer_commit(indexer.get(), &stats)) throw Error("committing git packfile index: %s", git_error_last()->message); @@ -237,6 +243,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this git_buf_dispose(&buf); throw; } + checkInterrupt(); } uint64_t getRevCount(const Hash & rev) override diff --git a/src/libutil/unix/signals-impl.hh b/src/libutil/unix/signals-impl.hh index 7ac8c914d..2193922be 100644 --- a/src/libutil/unix/signals-impl.hh +++ b/src/libutil/unix/signals-impl.hh @@ -84,6 +84,12 @@ static inline bool getInterrupted() return unix::_isInterrupted; } +/** + * Throw `Interrupted` exception if the process has been interrupted. + * + * Call this in long-running loops and between slow operations to terminate + * them as needed. + */ void inline checkInterrupt() { using namespace unix;