shim: implement ExitSignal with Condvar

Implement ExitSignal with Condvar instead of busy looping.

Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
This commit is contained in:
Liu Jiang 2021-12-13 00:38:09 +08:00
parent 04af4df73a
commit 7a8fa4413e
1 changed files with 15 additions and 7 deletions

View File

@ -28,8 +28,7 @@ use std::os::unix::io::RawFd;
use std::os::unix::net::UnixListener; use std::os::unix::net::UnixListener;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio}; use std::process::{self, Command, Stdio};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Condvar, Mutex};
use std::sync::Arc;
pub use containerd_shim_client as protos; pub use containerd_shim_client as protos;
@ -71,6 +70,7 @@ pub struct Config {
} }
/// Startup options received from containerd to start new shim instance. /// Startup options received from containerd to start new shim instance.
///
/// These will be passed via [`Shim::start_shim`] to shim. /// These will be passed via [`Shim::start_shim`] to shim.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct StartOpts { pub struct StartOpts {
@ -87,31 +87,39 @@ pub struct StartOpts {
} }
/// Helper structure that wraps atomic bool to signal shim server when to shutdown the TTRPC server. /// Helper structure that wraps atomic bool to signal shim server when to shutdown the TTRPC server.
///
/// Shim implementations are responsible for calling [`Self::signal`]. /// Shim implementations are responsible for calling [`Self::signal`].
#[derive(Clone)] #[derive(Clone)]
pub struct ExitSignal(Arc<AtomicBool>); pub struct ExitSignal(Arc<(Mutex<bool>, Condvar)>);
impl Default for ExitSignal { impl Default for ExitSignal {
#[allow(clippy::mutex_atomic)]
fn default() -> Self { fn default() -> Self {
ExitSignal(Arc::new(AtomicBool::new(false))) ExitSignal(Arc::new((Mutex::new(false), Condvar::new())))
} }
} }
impl ExitSignal { impl ExitSignal {
/// Set exit signal to shutdown shim server. /// Set exit signal to shutdown shim server.
pub fn signal(&self) { pub fn signal(&self) {
self.0.store(true, Ordering::Release) let (lock, cvar) = &*self.0;
let mut exit = lock.lock().unwrap();
*exit = true;
cvar.notify_all();
} }
/// Wait for the exit signal to be set. /// Wait for the exit signal to be set.
fn wait(&self) { fn wait(&self) {
while !self.0.load(Ordering::Acquire) { let (lock, cvar) = &*self.0;
std::hint::spin_loop(); let mut started = lock.lock().unwrap();
while !*started {
started = cvar.wait(started).unwrap();
} }
} }
} }
/// Main shim interface that must be implemented by all shims. /// Main shim interface that must be implemented by all shims.
///
/// Start and delete routines will be called to handle containerd's shim lifecycle requests. /// Start and delete routines will be called to handle containerd's shim lifecycle requests.
pub trait Shim: Task { pub trait Shim: Task {
/// Error type to be returned when starting/deleting shim. /// Error type to be returned when starting/deleting shim.