1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//
// ░▀█▀░█▀▀░█▀█░█▀▄░█▀█░█▀▀░█░░░█▀▀
// ░░█░░▀▀█░█░█░█▀▄░█▀█░█░░░█░░░█▀▀
// ░░▀░░▀▀▀░▀▀▀░▀░▀░▀░▀░▀▀▀░▀▀▀░▀▀▀
//
// tsoracle — Distributed Timestamp Oracle
//
// Copyright (c) 2026 Prisma Risk
// Licensed under the Apache License, Version 2.0
// https://github.com/prisma-risk/tsoracle
//
//! Async yield points — the structural analogue of [`fail-rs`] failpoints,
//! but driven by a `tokio::sync::Notify` so the production code yields its
//! tokio worker while parked instead of blocking the thread.
//!
//! A fail-crate `pause` action uses `std::thread::park` / a condvar, which
//! blocks the OS thread the failpoint fires on. Inside a tokio task that
//! starves the runtime's timer driver — `tokio::time::sleep` stops
//! returning for every task on that worker, and any race the test is
//! trying to observe gets masked. Yield points exist for exactly the case
//! where the call site is in an async path that must keep yielding to
//! the runtime while parked.
//!
//! # Quick reference
//!
//! Opt in by declaring a feature on the consumer crate that flips
//! `tsoracle-yieldpoint/yieldpoints`:
//!
//! ```toml
//! # consumer Cargo.toml
//! [features]
//! yieldpoints = ["tsoracle-yieldpoint/yieldpoints"]
//!
//! [dependencies]
//! tsoracle-yieldpoint = { workspace = true }
//! ```
//!
//! Insert the macro at the call site:
//!
//! ```ignore
//! tsoracle_yieldpoint::yieldpoint!("module::site::after_X_before_Y");
//! ```
//!
//! Arm and release from a test:
//!
//! ```ignore
//! let handle = tsoracle_yieldpoint::cfg("module::site::after_X_before_Y");
//! // ... drive code into the yield point ...
//! handle.notify_one(); // release
//! tsoracle_yieldpoint::remove("module::site::after_X_before_Y");
//! ```
//!
//! The registry is process-global (same pattern as `fail-rs`). Tests that
//! arm the same name must serialize.
//!
//! [`fail-rs`]: https://docs.rs/fail
pub use ;
/// Await the registered `Notify` at this site if armed; no-op otherwise.
///
/// Expands to `{}` when the `yieldpoints` cargo feature is off (on
/// `yield-rs` itself), so production builds of consuming crates carry
/// zero overhead. When on, an armed entry parks the calling task on
/// `Notify::notified().await` — yielding the tokio worker so timers and
/// other tasks continue to run. Release with `notify_one()` on the
/// handle returned by [`cfg`].