Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 66 additions & 47 deletions litebox_broker_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ pub use policy::{
PolicyProfile, SocketPolicy, SocketPolicyError,
};
pub use process::{
AssociationCancellation, BrokerProcess, BrokerThread, CallerCredential, DuplicationTransaction,
ObjectRights, ProcessLifecycleSink, ProcessShutdown,
AssociationCancellation, BrokerProcess, CallerCredential, ObjectRights, ProcessLifecycleSink,
ProcessShutdown,
};
use process::{ObjectReference, ProcessParent, ProcessRoot};
use process::{ObjectReference, ProcessRoot};
use random::RandomProvider;
use socket::{BrokerSocketPorts, SocketProvider};
use stdio::StdioProvider;
Expand Down Expand Up @@ -325,17 +325,55 @@ impl BrokerCore {
Ok((first, second))
}

/// Allocates one authenticated process awaiting association activation.
/// Allocates one authenticated process without an initial thread.
///
/// # Panics
///
/// Panics if the shared ID allocator violates its range or uniqueness
/// invariants.
pub fn create_process(
pub(crate) fn allocate_process(
&self,
caller_credential: CallerCredential,
parent_id: Option<ProcessId>,
) -> Result<Arc<BrokerProcess>> {
let allocate_process = |parent: Option<Weak<BrokerProcess>>,
root: Option<Arc<ProcessRoot>>| {
let mut processes = self.processes.write();
if processes.len() >= self.limits.max_processes {
return Err(BrokerError::ResourceExhausted);
}
processes
.try_reserve(1)
.map_err(|_| BrokerError::OutOfMemory)?;
let raw_id = self.ids.lock().allocate()?;
let id = ProcessId(raw_id);
let process = if let Some(root) = root {
Arc::new(BrokerProcess::new(
self.clone(),
id,
root,
parent,
caller_credential,
))
} else {
assert!(parent.is_none(), "a root process cannot have a parent");
Arc::new_cyclic(|root_process| {
BrokerProcess::new(
self.clone(),
id,
Arc::new(ProcessRoot::new(root_process.clone())),
None,
caller_credential,
)
})
};
assert!(
processes.insert(id, Arc::downgrade(&process)).is_none(),
"the ID allocator returned an occupied process ID"
);
Ok(process)
};

if let Some(parent_id) = parent_id {
let parent = self
.processes
Expand All @@ -344,55 +382,36 @@ impl BrokerCore {
.and_then(Weak::upgrade)
.ok_or(BrokerError::UnknownObject)?;
return parent.with_live_owner(|root| {
self.register_process(
caller_credential,
Some(ProcessParent::new(&parent)),
Some(root),
)
allocate_process(Some(Arc::downgrade(&parent)), Some(root))
})?;
}
self.register_process(caller_credential, None, None)
allocate_process(None, None)
}

fn register_process(
/// Creates one process and its initial thread.
///
/// If initial-thread creation fails, the process is retired before the
/// error is returned.
///
/// # Panics
///
/// Panics if the shared ID allocator violates its range or uniqueness
/// invariants.
pub fn create_process(
&self,
caller_credential: CallerCredential,
parent: Option<ProcessParent>,
root: Option<Arc<ProcessRoot>>,
parent_id: Option<ProcessId>,
) -> Result<Arc<BrokerProcess>> {
let mut processes = self.processes.write();
if processes.len() >= self.limits.max_processes {
return Err(BrokerError::ResourceExhausted);
let process = self.allocate_process(caller_credential, parent_id)?;
match process.create_thread() {
Ok(initial_thread_id) => {
process.set_initial_thread_id(initial_thread_id);
Ok(process)
}
Err(error) => {
process.retire(true);
Err(error)
}
}
processes
.try_reserve(1)
.map_err(|_| BrokerError::OutOfMemory)?;
let raw_id = self.ids.lock().allocate()?;
let id = ProcessId(raw_id);
let process = if let Some(root) = root {
Arc::new(BrokerProcess::new(
self.clone(),
id,
root,
parent,
caller_credential,
))
} else {
assert!(parent.is_none(), "a root process cannot have a parent");
Arc::new_cyclic(|root_process| {
BrokerProcess::new(
self.clone(),
id,
Arc::new(ProcessRoot::new(root_process.clone())),
None,
caller_credential,
)
})
};
assert!(
processes.insert(id, Arc::downgrade(&process)).is_none(),
"the ID allocator returned an occupied process ID"
);
Ok(process)
}
}
Loading
Loading