dirstate: add a synchronisation point before doing a full dirstate read stable
authorPierre-Yves David <pierre-yves.david@octobus.net>
Sat, 25 Feb 2023 01:07:44 +0100
branchstable
changeset 50228 fc8e37c380d3
parent 50227 cbd4c9234e25
child 50229 7169ff59a2f8
dirstate: add a synchronisation point before doing a full dirstate read This will be useful to test some race conditions around the dirstate.
mercurial/configitems.py
mercurial/dirstatemap.py
rust/hg-core/src/repo.rs
rust/hg-core/src/utils/debug.rs
--- a/mercurial/configitems.py	Tue Feb 28 12:15:19 2023 +0100
+++ b/mercurial/configitems.py	Sat Feb 25 01:07:44 2023 +0100
@@ -704,6 +704,16 @@
 )
 coreconfigitem(
     b'devel',
+    b'sync.dirstate.pre-read-file',
+    default=None,
+)
+coreconfigitem(
+    b'devel',
+    b'sync.dirstate.pre-read-file-timeout',
+    default=2,
+)
+coreconfigitem(
+    b'devel',
     b'strip-obsmarkers',
     default=True,
 )
--- a/mercurial/dirstatemap.py	Tue Feb 28 12:15:19 2023 +0100
+++ b/mercurial/dirstatemap.py	Sat Feb 25 01:07:44 2023 +0100
@@ -10,6 +10,7 @@
     error,
     pathutil,
     policy,
+    testing,
     txnutil,
     util,
 )
@@ -276,7 +277,9 @@
             self._opener.join(self._filename)
         )
 
+        testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
         if self._use_dirstate_v2:
+
             if not self.docket.uuid:
                 return
             st = self._opener.read(self.docket.data_filename())
@@ -541,6 +544,7 @@
                 self._opener.join(self._filename)
             )
 
+            testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
             if self._use_dirstate_v2:
                 if self.docket.uuid:
                     # TODO: use mmap when possible
--- a/rust/hg-core/src/repo.rs	Tue Feb 28 12:15:19 2023 +0100
+++ b/rust/hg-core/src/repo.rs	Sat Feb 25 01:07:44 2023 +0100
@@ -10,6 +10,7 @@
 use crate::manifest::{Manifest, Manifestlog};
 use crate::revlog::filelog::Filelog;
 use crate::revlog::revlog::RevlogError;
+use crate::utils::debug::debug_wait_for_file_or_print;
 use crate::utils::files::get_path_from_bytes;
 use crate::utils::hg_path::HgPath;
 use crate::utils::SliceExt;
@@ -308,6 +309,10 @@
         if self.has_dirstate_v2() {
             self.read_docket_and_data_file()
         } else {
+            debug_wait_for_file_or_print(
+                self.config(),
+                "dirstate.pre-read-file",
+            );
             let dirstate_file_contents = self.dirstate_file_contents()?;
             if dirstate_file_contents.is_empty() {
                 self.dirstate_parents.set(DirstateParents::NULL);
@@ -324,6 +329,7 @@
     fn read_docket_and_data_file(
         &self,
     ) -> Result<OwningDirstateMap, DirstateError> {
+        debug_wait_for_file_or_print(self.config(), "dirstate.pre-read-file");
         let dirstate_file_contents = self.dirstate_file_contents()?;
         if dirstate_file_contents.is_empty() {
             self.dirstate_parents.set(DirstateParents::NULL);
--- a/rust/hg-core/src/utils/debug.rs	Tue Feb 28 12:15:19 2023 +0100
+++ b/rust/hg-core/src/utils/debug.rs	Sat Feb 25 01:07:44 2023 +0100
@@ -79,3 +79,9 @@
         Ok(())
     }
 }
+
+pub fn debug_wait_for_file_or_print(config: &Config, config_option: &str) {
+    if let Err(e) = debug_wait_for_file(&config, config_option) {
+        eprintln!("{e}");
+    };
+}