Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
hypervisor extension
Browse files Browse the repository at this point in the history
  • Loading branch information
NikVolf committed Aug 26, 2016
1 parent 1c19a80 commit c685a72
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 13 deletions.
18 changes: 16 additions & 2 deletions ipc/hypervisor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ impl Hypervisor {
self.service.unchecked_count() == 0
}

pub fn modules_shutdown(&self) -> bool {
self.service.running_count() == 0
}

/// Waits for every required module to check in
pub fn wait_for_startup(&self) {
let mut worker = self.ipc_worker.write().unwrap();
Expand All @@ -182,15 +186,25 @@ impl Hypervisor {
}
}

/// Waits for every required module to check in
pub fn wait_for_shutdown(&self) {
let mut worker = self.ipc_worker.write().unwrap();
while !self.modules_shutdown() {
worker.poll()
}
}

/// Shutdown the ipc and all managed child processes
pub fn shutdown(&self, wait_time: Option<std::time::Duration>) {
if wait_time.is_some() { std::thread::sleep(wait_time.unwrap()) }

let mut childs = self.processes.write().unwrap();
for (ref mut module, ref mut child) in childs.iter_mut() {
for (ref mut module, _) in childs.iter_mut() {
trace!(target: "hypervisor", "Stopping process module: {}", module);
child.kill().unwrap();
self.service.send_shutdown(**module);
}

self.wait_for_shutdown();
}
}

Expand Down
60 changes: 49 additions & 11 deletions ipc/hypervisor/src/service.rs.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use std::sync::{RwLock,Arc};
use ipc::IpcConfig;
use std::collections::HashMap;
use nanoipc;

pub type IpcModuleId = u64;

Expand All @@ -28,15 +29,37 @@ pub const SYNC_MODULE_ID: IpcModuleId = 2100;

/// IPC service that handles module management
pub struct HypervisorService {
check_list: RwLock<HashMap<IpcModuleId, bool>>,
modules: RwLock<HashMap<IpcModuleId, ModuleState>>,
}

#[derive(Default)]
pub struct ModuleState {
started: bool,
control_url: String,
shutdown: bool,
}


#[derive(Ipc)]
trait ControlService {
fn shutdown(&self);
}

#[derive(Ipc)]
impl HypervisorService {
fn module_ready(&self, module_id: u64) -> bool {
let mut check_list = self.check_list.write().unwrap();
check_list.get_mut(&module_id).map(|mut status| *status = true);
check_list.iter().any(|(_, status)| !status)
fn module_ready(&self, control_url: String, module_id: u64) {
let mut modules = self.modules.write().unwrap();
modules.get_mut(&module_id).map(|mut module| {
module.started = true;
module.control_url = control_url;
});
}

fn module_shutdown(&self, module_id: u64) {
let mut modules = self.modules.write().unwrap();
modules.get_mut(&module_id).map(|mut module| {
module.shutdown = true;
});
}
}

Expand All @@ -48,29 +71,44 @@ impl HypervisorService {

/// New service with list of modules that will report for being ready
pub fn with_modules(module_ids: Vec<IpcModuleId>) -> Arc<HypervisorService> {
let mut check_list = HashMap::new();
let mut modules = HashMap::new();
for module_id in module_ids {
check_list.insert(module_id, false);
modules.insert(module_id, ModuleState::default());
}
Arc::new(HypervisorService {
check_list: RwLock::new(check_list),
modules: RwLock::new(modules),
})
}

/// Add the module to the check-list
pub fn add_module(&self, module_id: IpcModuleId) {
self.check_list.write().unwrap().insert(module_id, false);
self.modules.write().unwrap().insert(module_id, ModuleState::default());
}

/// Number of modules still being waited for check-in
pub fn unchecked_count(&self) -> usize {
self.check_list.read().unwrap().iter().filter(|&(_, status)| !status).count()
self.modules.read().unwrap().iter().filter(|&(_, module)| !module.started).count()
}

/// List of all modules within this service
pub fn module_ids(&self) -> Vec<IpcModuleId> {
self.check_list.read().unwrap().iter().map(|(module_id, _)| module_id).cloned().collect()
self.modules.read().unwrap().iter().map(|(module_id, _)| module_id).cloned().collect()
}

/// Number of modules started and running
pub fn running_count(&self) -> usize {
self.modules.read().unwrap().iter().filter(|&(_, module)| module.started && !module.shutdown).count()
}

pub fn send_shutdown(&self, module_id: IpcModuleId) {
let modules = self.modules.read().unwrap();
modules.get(&module_id).map(|module| {
let client = nanoipc::init_client::<ControlServiceClient<_>>(&module.control_url).unwrap();
client.shutdown();
});
}
}

impl ::ipc::IpcConfig for HypervisorService {}

impl ::ipc::IpcConfig for ControlService {}

0 comments on commit c685a72

Please sign in to comment.