feat: update library lifecycle return value

This commit is contained in:
2026-08-10 22:17:19 +08:00
parent 65e825f8db
commit 44adb10989
2 changed files with 61 additions and 42 deletions
+15 -10
View File
@@ -82,15 +82,16 @@ impl<S> LibraryLifecycle<S> {
/// Increment the reference count.
///
/// On the `0 -> 1` transition the supplied `init` closure runs and its produced `S` is stored.
/// If `init` fails, neither the count nor the state is changed and an error is returned.
/// On the `0 -> 1` transition the supplied `init` closure runs and its produced `S` is stored;
/// the call returns `Ok(true)`. If `init` fails, neither the count nor the state is changed and
/// an error is returned.
///
/// On any other call (count already `> 0`) the supplied `init` is **dropped without being run**
/// and the count is simply incremented.
/// On any other call (count already `> 0`) the supplied `init` is **dropped without being run**,
/// the count is simply incremented, and the call returns `Ok(false)`.
///
/// The init closure runs under the write lock and must not re-enter this lifecycle. Its error
/// type `E` is type-erased.
pub fn startup<E>(&self, init: impl FnOnce() -> Result<S, E>) -> Result<(), Error>
pub fn startup<E>(&self, init: impl FnOnce() -> Result<S, E>) -> Result<bool, Error>
where
E: std::error::Error + Send + Sync + 'static,
{
@@ -99,22 +100,24 @@ impl<S> LibraryLifecycle<S> {
let s = init().map_err(|e| Error::Init(Box::new(e)))?;
inner.state = Some(s);
inner.count = 1;
Ok(true)
} else {
inner.count += 1;
Ok(false)
}
Ok(())
}
/// Decrement the reference count.
///
/// On the `-> 0` transition the stored `S` is taken out and handed to the supplied `destroy`
/// closure, which must never fail (destructor semantics). On any other call (count stays `> 0`)
/// the supplied `destroy` is **dropped without being run** and the count is simply decremented.
/// closure, which must never fail (destructor semantics), and the call returns `Ok(true)`. On
/// any other call (count stays `> 0`) the supplied `destroy` is **dropped without being run**,
/// the count is simply decremented, and the call returns `Ok(false)`.
///
/// Returns an error if the count was already zero.
///
/// The destroy closure runs under the write lock and must not re-enter this lifecycle.
pub fn shutdown(&self, destroy: impl FnOnce(S)) -> Result<(), Error> {
pub fn shutdown(&self, destroy: impl FnOnce(S)) -> Result<bool, Error> {
let mut inner = self.inner.write().expect("unexpected poison lock");
if inner.count == 0 {
return Err(Error::Underflow);
@@ -124,8 +127,10 @@ impl<S> LibraryLifecycle<S> {
// Invariant: state is Some whenever count > 0.
let s = inner.state.take().expect("state present while count > 0");
destroy(s);
Ok(true)
} else {
Ok(false)
}
Ok(())
}
/// Access the stored state by shared reference under a read lock.