[go: up one dir, main page]

gix 0.62.0

Interact with git repositories just like git would
Documentation
use std::ops::Deref;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;

#[derive(Clone)]
pub enum OwnedOrStaticAtomicBool {
    Owned {
        flag: Arc<AtomicBool>,
        #[cfg_attr(not(feature = "parallel"), allow(dead_code))]
        private: bool,
    },
    Shared(&'static AtomicBool),
}

impl Default for OwnedOrStaticAtomicBool {
    fn default() -> Self {
        OwnedOrStaticAtomicBool::Owned {
            flag: Arc::new(AtomicBool::default()),
            private: true,
        }
    }
}

impl Deref for OwnedOrStaticAtomicBool {
    type Target = std::sync::atomic::AtomicBool;

    fn deref(&self) -> &Self::Target {
        match self {
            OwnedOrStaticAtomicBool::Owned { flag, .. } => flag,
            OwnedOrStaticAtomicBool::Shared(flag) => flag,
        }
    }
}

impl From<&'static AtomicBool> for OwnedOrStaticAtomicBool {
    fn from(value: &'static AtomicBool) -> Self {
        OwnedOrStaticAtomicBool::Shared(value)
    }
}

impl<'a> From<&'a Arc<AtomicBool>> for OwnedOrStaticAtomicBool {
    fn from(value: &'a Arc<AtomicBool>) -> Self {
        OwnedOrStaticAtomicBool::Owned {
            flag: value.clone(),
            private: false,
        }
    }
}

impl From<Arc<AtomicBool>> for OwnedOrStaticAtomicBool {
    fn from(flag: Arc<AtomicBool>) -> Self {
        OwnedOrStaticAtomicBool::Owned { flag, private: false }
    }
}
#[cfg(feature = "parallel")]
pub fn parallel_iter_drop<T, U>(
    mut rx_and_join: Option<(std::sync::mpsc::Receiver<T>, std::thread::JoinHandle<U>)>,
    should_interrupt: &OwnedOrStaticAtomicBool,
) {
    let Some((rx, handle)) = rx_and_join.take() else {
        return;
    };
    let prev = should_interrupt.swap(true, std::sync::atomic::Ordering::Relaxed);
    let undo = match &should_interrupt {
        OwnedOrStaticAtomicBool::Shared(flag) => *flag,
        OwnedOrStaticAtomicBool::Owned { flag, private: false } => flag.as_ref(),
        OwnedOrStaticAtomicBool::Owned { private: true, .. } => {
            // Leak the handle to let it shut down in the background, so drop returns more quickly.
            drop((rx, handle));
            return;
        }
    };
    // Wait until there is time to respond before we undo the change.
    handle.join().ok();
    undo.fetch_update(
        std::sync::atomic::Ordering::SeqCst,
        std::sync::atomic::Ordering::SeqCst,
        |current| current.then_some(prev),
    )
    .ok();
}