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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//! A lightweight crate for detecting process forks.
//!
//! ```rust
//! let mut guard = forkguard::new();
//!
//! // Some time later...
//! if guard.detected_fork() {
//! // Handle the fork (e.g., re-initialize state)
//! }
//! ```
//!
//! This crate provides `Guard` types that can detect if the current process has
//! been forked since the last check. This is useful for resetting state (like
//! random number generators or connection pools) that should not be shared between
//! a parent and its forked child.
//!
//! Depending on the platform and enabled features, [`new()`] returns one of three
//! specialized `Guard` flavors:
//!
//! - [`atfork::Guard`] (Unix with `atfork` crate feature): Uses `pthread_atfork()` to
//! update the global state on fork. This is the most efficient detection
//! mechanism for supported Unix-like systems, though the usual caveats of fork
//! handlers apply.
//! - [`pid::Guard`] (Unix default): Tracks the process ID and detects changes. This
//! is a simple and sufficiently efficient option for Unix-like platforms unless
//! `getpid()` overhead is a concern.
//! - [`noop::Guard`] (Non-Unix): Provides a no-op implementation that always returns
//! `false`, used on platforms where fork detection is not required.
//!
//! The top-level `forkguard::Guard` resolves to the active flavor.
//!
//! # Crate features
//!
//! - `atfork` (optional): See the above description.
//!
//! This crate lets downstream users opt-in to the `atfork` feature even when the
//! intermediate dependencies do not. To do this, add the following to your
//! `Cargo.toml` no matter if your crate uses `forkguard` directly:
//!
//! ```toml
//! [dependencies]
//! forkguard = { version = "0.1", features = ["atfork"] }
//! ```
//!
//! Alternatively, add the following to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! forkguard = "0.1"
//! ```
//!
//! And then enable the feature in your build command:
//!
//! ```bash
//! cargo build --features forkguard/atfork
//! ```
pub use Guard;
pub use Guard;
pub use Guard;
/// Creates a new fork `Guard` instance.
///
/// The actual type of the returned `Guard` depends on the platform and enabled features:
///
/// - Unix with `atfork` feature: Returns [`atfork::Guard`], which uses `pthread_atfork()` to
/// detect forks.
/// - Unix without `atfork` feature: Returns [`pid::Guard`], which tracks changes in the process
/// ID.
/// - Non-Unix platforms: Returns [`noop::Guard`], which never detects a fork.
///
/// # Panics
///
/// Panics if `atfork::Guard` cannot be created due to `pthread_atfork()` failure, which is
/// extremely unlikely under normal conditions. `pid::Guard` or `noop::Guard` never panics.
///
/// # Examples
///
/// ```rust
/// let mut guard = forkguard::new();
///
/// if guard.detected_fork() {
/// // Handle the fork (e.g., re-initialize state)
/// }
/// ```
/// An enumeration of the different fork detection flavors provided by this crate.