forked from pantsbuild/pants
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix immutable inputs DCL bug. (pantsbuild#14016)
Previously we used the double-checked-cell-async crate (See: https://github.com/chrislearn/double-checked-cell-async/blob/46cd3b04eddddbe279282143fe8a936d5854588c/src/lib.rs#L228-L260), which performed the second check of the double check lock with relaxed ordering. The relevant code is snipped below and annotated: ```rust pub struct DoubleCheckedCell<T> { value: UnsafeCell<Option<T>>, initialized: AtomicBool, lock: Mutex<()>, } impl<T> DoubleCheckedCell<T> { pub fn new() -> DoubleCheckedCell<T> { DoubleCheckedCell { value: UnsafeCell::new(None), initialized: AtomicBool::new(false), lock: Mutex::new(()), } } pub async fn get_or_try_init<Fut, E>(&self, init: Fut) -> Result<&T, E> where Fut: Future<Output = Result<T, E>> { // 1.) 1st load & check. if !self.initialized.load(Ordering::Acquire) { // 2.) Lock. let _lock = self.lock.lock().await; // 3.) 2nd load & check. if !self.initialized.load(Ordering::Relaxed) { { // 4.) Critical section. let result = init.await?; let value = unsafe { &mut *self.value.get() }; value.replace(result); } // 5.) Store with lock held. self.initialized.store(true, Ordering::Release); } } let value = unsafe { &*self.value.get() }; Ok(unsafe { value.as_ref().unchecked_unwrap() }) } } ``` Per the C++11 memory model used by Rust (See: https://en.cppreference.com/w/cpp/language/memory_model), this would seem to indicate the second load could be reordered to occur anywhere after the 1st load with acquire ordering and anywhere before the store with released ordering. If that second load was reordered to occur before the lock was acquired, two threads could enter the critical section in serial and the second thread would try to materialize to paths that already were created and marked read-only. Switch to the async-oncecell crate which performs both loads of the double-checked lock with acquire ordering, ensuring they are not re-ordered with respect to the interleaved non-atomics code. Also fixup the materialization process to be atomic. We now cleanup materialization chroots when materialization fails and only move their contents to the destination path if the full materialization has succeeded. Fixes pantsbuild#13899
- Loading branch information
Showing
9 changed files
with
134 additions
and
73 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.