pub struct ThreadGroup {
pub weak_self: Weak<ThreadGroup>,
pub kernel: Arc<Kernel>,
pub process: Process,
pub leader: pid_t,
pub signal_actions: Arc<SignalActions>,
pub timers: TimerTable,
pub drop_notifier: DropNotifier,
pub limits: OrderedMutex<ResourceLimits, ThreadGroupLimits>,
pub next_seccomp_filter_id: AtomicU64Counter,
pub ptracees: Mutex<BTreeMap<tid_t, TaskContainer>>,
pub pending_signals: Mutex<QueuedSignals>,
pub start_time: MonotonicInstant,
/* private fields */
}Expand description
A collection of Task objects that roughly correspond to a “process”.
Userspace programmers often think about “threads” and “process”, but those concepts have no
clear analogs inside the kernel because tasks are typically created using clone(2), which
takes a complex set of flags that describes how much state is shared between the original task
and the new task.
If a new task is created with the CLONE_THREAD flag, the new task will be placed in the same
ThreadGroup as the original task. Userspace typically uses this flag in conjunction with the
CLONE_FILES, CLONE_VM, and CLONE_FS, which corresponds to the userspace notion of a
“thread”. For example, that’s how pthread_create behaves. In that sense, a ThreadGroup
normally corresponds to the set of “threads” in a “process”. However, this pattern is purely a
userspace convention, and nothing stops userspace from using CLONE_THREAD without
CLONE_FILES, for example.
In Starnix, a ThreadGroup corresponds to a Zircon process, which means we do not support the
CLONE_THREAD flag without the CLONE_VM flag. If we run into problems with this limitation,
we might need to revise this correspondence.
Each Task in a ThreadGroup has the same thread group ID (tgid). The task with the same
pid as the tgid is called the thread group leader.
Thread groups are destroyed when the last task in the group exits.
Fields§
§weak_self: Weak<ThreadGroup>Weak reference to the OwnedRef of this ThreadGroup. This allows to retrieve the
TempRef from a raw ThreadGroup.
kernel: Arc<Kernel>The kernel to which this thread group belongs.
process: ProcessA handle to the underlying Zircon process object.
Currently, we have a 1-to-1 mapping between thread groups and zx::process objects. This approach might break down if/when we implement CLONE_VM without CLONE_THREAD because that creates a situation where two thread groups share an address space. To implement that situation, we might need to break the 1-to-1 mapping between thread groups and zx::process or teach zx::process to share address spaces.
leader: pid_tThe lead task of this thread group.
The lead task is typically the initial thread created in the thread group.
signal_actions: Arc<SignalActions>The signal actions that are registered for this process.
timers: TimerTableThe timers for this thread group (from timer_create(), etc.).
drop_notifier: DropNotifierA mechanism to be notified when this ThreadGroup is destroyed.
limits: OrderedMutex<ResourceLimits, ThreadGroupLimits>The resource limits for this thread group. This is outside mutable_state to avoid deadlocks where the thread_group lock is held when acquiring the task lock, and vice versa.
next_seccomp_filter_id: AtomicU64CounterThe next unique identifier for a seccomp filter. These are required to be able to distinguish identical seccomp filters, which are treated differently for the purposes of SECCOMP_FILTER_FLAG_TSYNC. Inherited across clone because seccomp filters are also inherited across clone.
ptracees: Mutex<BTreeMap<tid_t, TaskContainer>>Tasks ptraced by this process
pending_signals: Mutex<QueuedSignals>The signals that are currently pending for this thread group.
start_time: MonotonicInstantThe monotonic time at which the thread group started.
Implementations§
Source§impl ThreadGroup
impl ThreadGroup
pub fn new<L>(
locked: &mut Locked<L>,
kernel: Arc<Kernel>,
process: Process,
parent: Option<ThreadGroupWriteGuard<'_>>,
leader: pid_t,
exit_signal: Option<Signal>,
process_group: Arc<ProcessGroup>,
signal_actions: Arc<SignalActions>,
) -> Arc<ThreadGroup>where
L: LockBefore<ProcessGroupState>,
pub fn read<'a>(self: &'a ThreadGroup) -> ThreadGroupReadGuard<'a>
pub fn write<'a>(self: &'a ThreadGroup) -> ThreadGroupWriteGuard<'a>
pub fn load_stopped(&self) -> StopState
pub fn exit( &self, locked: &mut Locked<Unlocked>, exit_status: ExitStatus, current_task: Option<&mut CurrentTask>, )
pub fn add(&self, task: &TempRef<'_, Task>) -> Result<(), Errno>
Sourcepub fn remove<L>(
&self,
locked: &mut Locked<L>,
pids: &mut PidTable,
task: &OwnedRef<Task>,
)where
L: LockBefore<ProcessGroupState>,
pub fn remove<L>(
&self,
locked: &mut Locked<L>,
pids: &mut PidTable,
task: &OwnedRef<Task>,
)where
L: LockBefore<ProcessGroupState>,
Remove the task from the children of this ThreadGroup.
It is important that the task is taken as an OwnedRef. It ensures the tasks of the
ThreadGroup are always valid as they are still valid when removed.
pub fn do_zombie_notifications(&self, zombie: OwnedRef<ZombieProcess>)
pub fn setsid<L>(&self, locked: &mut Locked<L>) -> Result<(), Errno>where
L: LockBefore<ProcessGroupState>,
pub fn setpgid<L>(
&self,
locked: &mut Locked<L>,
current_task: &CurrentTask,
target: &Task,
pgid: pid_t,
) -> Result<(), Errno>where
L: LockBefore<ProcessGroupState>,
pub fn set_itimer( &self, current_task: &CurrentTask, which: u32, value: itimerval, ) -> Result<itimerval, Errno>
pub fn get_itimer(&self, which: u32) -> Result<itimerval, Errno>
Sourcepub fn set_stopped(
&self,
new_stopped: StopState,
siginfo: Option<SignalInfo>,
finalize_only: bool,
) -> StopState
pub fn set_stopped( &self, new_stopped: StopState, siginfo: Option<SignalInfo>, finalize_only: bool, ) -> StopState
Set the stop status of the process. If you pass |siginfo| of |None|, does not update the signal. If |finalize_only| is set, will check that the set will be a finalize (Stopping -> Stopped or Stopped -> Stopped) before executing it.
Returns the latest stop state after any changes.
pub fn get_foreground_process_group( &self, terminal: &Terminal, ) -> Result<pid_t, Errno>
pub fn set_foreground_process_group<L>(
&self,
locked: &mut Locked<L>,
current_task: &CurrentTask,
terminal: &Terminal,
pgid: pid_t,
) -> Result<(), Errno>where
L: LockBefore<ProcessGroupState>,
pub fn set_controlling_terminal( &self, current_task: &CurrentTask, terminal: &Terminal, is_main: bool, steal: bool, is_readable: bool, ) -> Result<(), Errno>
pub fn release_controlling_terminal<L>(
&self,
locked: &mut Locked<L>,
_current_task: &CurrentTask,
terminal: &Terminal,
is_main: bool,
) -> Result<(), Errno>where
L: LockBefore<ProcessGroupState>,
pub fn get_rlimit<L>(&self, locked: &mut Locked<L>, resource: Resource) -> u64where
L: LockBefore<ThreadGroupLimits>,
Sourcepub fn adjust_rlimits<L>(
locked: &mut Locked<L>,
current_task: &CurrentTask,
target_task: &Task,
resource: Resource,
maybe_new_limit: Option<rlimit>,
) -> Result<rlimit, Errno>where
L: LockBefore<ThreadGroupLimits>,
pub fn adjust_rlimits<L>(
locked: &mut Locked<L>,
current_task: &CurrentTask,
target_task: &Task,
resource: Resource,
maybe_new_limit: Option<rlimit>,
) -> Result<rlimit, Errno>where
L: LockBefore<ThreadGroupLimits>,
Adjusts the rlimits of the ThreadGroup to which target_task belongs to.
pub fn time_stats(&self) -> TaskTimeStats
Sourcepub fn get_ptracees_and(
&self,
selector: &ProcessSelector,
pids: &PidTable,
f: &mut dyn FnMut(&Task, &TaskMutableState),
)
pub fn get_ptracees_and( &self, selector: &ProcessSelector, pids: &PidTable, f: &mut dyn FnMut(&Task, &TaskMutableState), )
For each task traced by this thread_group that matches the given selector, acquire its TaskMutableState and ptracees lock and execute the given function.
Sourcepub fn get_waitable_ptracee(
&self,
selector: &ProcessSelector,
options: &WaitingOptions,
pids: &mut PidTable,
) -> Option<WaitResult>
pub fn get_waitable_ptracee( &self, selector: &ProcessSelector, options: &WaitingOptions, pids: &mut PidTable, ) -> Option<WaitResult>
Returns a tracee whose state has changed, so that waitpid can report on it. If this returns a value, and the pid is being traced, the tracer thread is deemed to have seen the tracee ptrace-stop for the purposes of PTRACE_LISTEN.
Sourcepub fn send_signal_unchecked(
&self,
current_task: &CurrentTask,
unchecked_signal: UncheckedSignal,
) -> Result<(), Errno>
pub fn send_signal_unchecked( &self, current_task: &CurrentTask, unchecked_signal: UncheckedSignal, ) -> Result<(), Errno>
Attempts to send an unchecked signal to this thread group.
current_task: The task that is sending the signal.unchecked_signal: The signal that is to be sent. Unchecked, since0is a sentinel value where rights are to be checked but no signal is actually sent.
§Returns
Returns Ok(()) if the signal was sent, or the permission checks passed with a 0 signal, otherwise the error that was encountered.
Sourcepub unsafe fn send_signal_unchecked_debug(
&self,
current_task: &CurrentTask,
unchecked_signal: UncheckedSignal,
) -> Result<(), Errno>
pub unsafe fn send_signal_unchecked_debug( &self, current_task: &CurrentTask, unchecked_signal: UncheckedSignal, ) -> Result<(), Errno>
Sends a signal to this thread_group without performing any access checks.
§Safety
This is unsafe, because it should only be called by tools and tests.
Sourcepub fn send_signal_unchecked_with_info(
&self,
current_task: &CurrentTask,
unchecked_signal: UncheckedSignal,
siginfo_ref: UserAddress,
) -> Result<(), Errno>
pub fn send_signal_unchecked_with_info( &self, current_task: &CurrentTask, unchecked_signal: UncheckedSignal, siginfo_ref: UserAddress, ) -> Result<(), Errno>
Attempts to send an unchecked signal to this thread group, with info read from
siginfo_ref.
current_task: The task that is sending the signal.unchecked_signal: The signal that is to be sent. Unchecked, since0is a sentinel value where rights are to be checked but no signal is actually sent.siginfo_ref: The siginfo that will be enqueued.
§Returns
Returns Ok(()) if the signal was sent, or the permission checks passed with a 0 signal, otherwise the error that was encountered.
Sourcepub async fn shut_down(this: Weak<Self>)
pub async fn shut_down(this: Weak<Self>)
Drive this ThreadGroup to exit, allowing it time to handle SIGTERM before sending SIGKILL.
Returns once ThreadGroup::exit() has completed.
Must be called from the system task.
Sourcepub fn get_process_koid(&self) -> Result<Koid, Status>
pub fn get_process_koid(&self) -> Result<Koid, Status>
Returns the KOID of the process for this thread group. This method should be used to when mapping 32 bit linux process ids to KOIDs to avoid breaking the encapsulation of the zx::process within the ThreadGroup. This encapsulation is important since the relationship between the ThreadGroup and the Process may change over time. See ThreadGroup::process for more details.
Trait Implementations§
Source§impl Debug for ThreadGroup
impl Debug for ThreadGroup
Source§impl Drop for ThreadGroup
Available on debug-assertions enabled only.
impl Drop for ThreadGroup
Source§impl From<&ThreadGroup> for ThreadGroupKey
impl From<&ThreadGroup> for ThreadGroupKey
Source§fn from(tg: &ThreadGroup) -> Self
fn from(tg: &ThreadGroup) -> Self
Source§impl PartialEq for ThreadGroup
impl PartialEq for ThreadGroup
Auto Trait Implementations§
impl !Freeze for ThreadGroup
impl !RefUnwindSafe for ThreadGroup
impl Send for ThreadGroup
impl Sync for ThreadGroup
impl Unpin for ThreadGroup
impl !UnwindSafe for ThreadGroup
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
Source§impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
§impl<T> InstanceFromServiceTransport<T> for T
impl<T> InstanceFromServiceTransport<T> for T
§fn from_service_transport(handle: T) -> T
fn from_service_transport(handle: T) -> T
T to [Self]Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more