diff rust/hg-cpython/src/update.rs @ 52213:96b113d22b34 stable

rust-update: handle SIGINT from long-running update threads The current code does not respond to ^C until after the Rust bit is finished doing its work. This is expected, since Rust holds the GIL for the duration of the call and does not call `PyErr_CheckSignals`. Freeing the GIL to do our work does not really improve anything since the Rust threads are still going, and the only way of cancelling a thread is by making it cooperate. So we do the following: - remember the SIGINT handler in hg-cpython and reset it after the call into core (see inline comment in `update.rs` about this) - make all update threads watch for a global `AtomicBool` being `true`, and if so stop their work - reset the global bool and exit early (i.e. before writing the dirstate) - raise SIGINT from `hg-cpython` if update returns `InterruptReceived`
author Rapha?l Gom?s <rgomes@octobus.net>
date Tue, 12 Nov 2024 12:52:13 +0100
parents e6a44bc91bc2
children
line wrap: on
line diff
--- a/rust/hg-cpython/src/update.rs	Fri Nov 08 17:08:11 2024 +0100
+++ b/rust/hg-cpython/src/update.rs	Tue Nov 12 12:52:13 2024 +0100
@@ -15,7 +15,7 @@
 
 use crate::{
     exceptions::FallbackError,
-    utils::{hgerror_to_pyerr, repo_from_path},
+    utils::{hgerror_to_pyerr, repo_from_path, with_sigint_wrapper},
 };
 
 pub fn update_from_null_fast_path(
@@ -27,10 +27,12 @@
     log::trace!("Using update from null fastpath");
     let repo = repo_from_path(py, repo_path)?;
     let progress: &dyn Progress = &HgProgressBar::new("updating");
-    hgerror_to_pyerr(
-        py,
-        update_from_null(&repo, to.into(), progress, num_cpus),
-    )
+
+    let res = with_sigint_wrapper(py, || {
+        update_from_null(&repo, to.into(), progress, num_cpus)
+    })?;
+
+    hgerror_to_pyerr(py, res)
 }
 
 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {