52 lines
1.6 KiB
Rust
52 lines
1.6 KiB
Rust
use crate::{AtomicBool, AtomicOrdering};
|
|
use std::sync::atomic::AtomicU32;
|
|
|
|
static ORPHAN_CHECK_RUNNING: AtomicBool = AtomicBool::new(false);
|
|
static ORPHAN_RECHECK_REQUESTED: AtomicBool = AtomicBool::new(false);
|
|
static ORPHAN_RECHECK_FROM_HEIGHT: AtomicU32 = AtomicU32::new(0);
|
|
|
|
fn store_earliest_recheck_height(incoming_height: u32) {
|
|
let mut current = ORPHAN_RECHECK_FROM_HEIGHT.load(AtomicOrdering::SeqCst);
|
|
while current == 0 || incoming_height < current {
|
|
match ORPHAN_RECHECK_FROM_HEIGHT.compare_exchange(
|
|
current,
|
|
incoming_height,
|
|
AtomicOrdering::SeqCst,
|
|
AtomicOrdering::SeqCst,
|
|
) {
|
|
Ok(_) => return,
|
|
Err(next_current) => current = next_current,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn try_begin_orphan_check() -> bool {
|
|
if ORPHAN_CHECK_RUNNING
|
|
.compare_exchange(false, true, AtomicOrdering::SeqCst, AtomicOrdering::SeqCst)
|
|
.is_err()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ORPHAN_RECHECK_REQUESTED.store(false, AtomicOrdering::SeqCst);
|
|
ORPHAN_RECHECK_FROM_HEIGHT.store(0, AtomicOrdering::SeqCst);
|
|
true
|
|
}
|
|
|
|
pub fn request_orphan_recheck(incoming_height: u32) {
|
|
store_earliest_recheck_height(incoming_height);
|
|
ORPHAN_RECHECK_REQUESTED.store(true, AtomicOrdering::SeqCst);
|
|
}
|
|
|
|
pub fn take_orphan_recheck_height() -> Option<u32> {
|
|
if !ORPHAN_RECHECK_REQUESTED.swap(false, AtomicOrdering::SeqCst) {
|
|
return None;
|
|
}
|
|
|
|
Some(ORPHAN_RECHECK_FROM_HEIGHT.swap(0, AtomicOrdering::SeqCst))
|
|
}
|
|
|
|
pub fn finish_orphan_check() {
|
|
ORPHAN_CHECK_RUNNING.store(false, AtomicOrdering::SeqCst);
|
|
}
|