Process Signal Manager
Relevant source files
Purpose and Scope
The Process Signal Manager is a core component of the axsignal
crate that handles signal management at the process level. It provides mechanisms for managing, queuing, and delivering signals to processes in a Unix-like manner. This component serves as the foundation for process-wide signal operations while working alongside thread-specific signal handling. For thread-level signal management, see Thread Signal Manager.
Sources: src/api/process.rs(L32 - L82)
Structure and Components
The Process Signal Manager consists of several key components that work together to manage signals at the process level.
classDiagram class ProcessSignalManager { +Mutex pending +Arc~ actions +WaitQueue wq +usize default_restorer +new(actions, default_restorer) +dequeue_signal(mask) +send_signal(sig) +pending() +wait_signal() } class SignalActions { +[SignalAction; 64] 0 +index(Signo) +index_mut(Signo) } class PendingSignals { +SignalSet set +Option[32] info_std +VecDeque[33] info_rt +new() +put_signal(SignalInfo) +dequeue_signal(SignalSet) } class WaitQueue { +wait() +notify_one() } ProcessSignalManager --> SignalActions : contains Arc> ProcessSignalManager --> PendingSignals : contains Mutex<> ProcessSignalManager --> WaitQueue : contains
Diagram: Process Signal Manager Structure
Sources: src/api/process.rs(L32 - L48) src/api/process.rs(L13 - L30)
Core Components
- Pending Signals: A mutex-protected
PendingSignals
instance that stores signals queued for the process. - Signal Actions: An atomic reference counted, mutex-protected
SignalActions
that defines how the process responds to different signals. - Wait Queue: Provides synchronization for tasks waiting on signals, used in operations like
rt_sigtimedwait
. - Default Restorer: A function pointer (as
usize
) that serves as the default signal handler restorer.
Sources: src/api/process.rs(L32 - L48)
Signal Actions
The SignalActions
structure maintains an array of 64 signal actions, providing indexed access to actions for each signal number.
SignalActions[1] -> Action for SIGHUP
SignalActions[2] -> Action for SIGINT
...
SignalActions[64] -> Action for signal 64
The structure implements Index
and IndexMut
traits to allow convenient access to signal actions by their signal number (Signo
).
Sources: src/api/process.rs(L13 - L30)
Signal Flow and Management
The Process Signal Manager plays a central role in the signal handling flow, serving as an intermediary between signal sources and handler execution.
flowchart TD subgraph subGraph0["Signal Flow"] SendSignal["send_signal(SignalInfo)"] AddPending["Add to pending signals"] NotifyWaiters["Notify waiting tasks"] CheckPending["pending()"] GetPendingSet["Return SignalSet of pending signals"] DequeueSignal["dequeue_signal(mask)"] CheckMask["Signal in mask?"] RemoveSignal["Remove from pending"] ReturnNone["Return None"] ReturnSignal["Return SignalInfo"] WaitSignal["wait_signal()"] SuspendTask["Suspend current task"] WakeupTask["Wake up waiting tasks"] end AddPending --> NotifyWaiters CheckMask --> RemoveSignal CheckMask --> ReturnNone CheckPending --> GetPendingSet DequeueSignal --> CheckMask NotifyWaiters --> WakeupTask RemoveSignal --> ReturnSignal SendSignal --> AddPending WaitSignal --> SuspendTask WakeupTask --> SuspendTask
Diagram: Process Signal Manager Operations
Sources: src/api/process.rs(L60 - L81)
Key Operations
- Signal Queueing: When a signal is sent to a process using
send_signal()
, it's added to the pending signals queue and triggers a notification on the wait queue. - Signal Retrieval: The
dequeue_signal()
method allows retrieving a pending signal if it's not blocked by the provided mask. - Pending Signal Management: The
pending()
method returns the set of signals currently pending for the process. - Signal Waiting: The
wait_signal()
method suspends the current task until a signal is delivered to the process.
Sources: src/api/process.rs(L60 - L81)
Integration with Signal Management System
The Process Signal Manager integrates with the broader signal management system, particularly with the Thread Signal Manager and other signal handling components.
flowchart TD subgraph subGraph0["Signal Management System"] PSM["ProcessSignalManager"] ProcessPending["Process Pending Signals"] SignalActions["Signal Actions"] TSM["ThreadSignalManager"] ThreadPending["Thread Pending Signals"] SignalSource["Signal Source"] SignalInfo["SignalInfo"] Action["SignalAction"] Pending["PendingSignals"] end PSM --> ProcessPending PSM --> SignalActions ProcessPending --> SignalInfo SignalActions --> SignalInfo SignalSource --> PSM SignalSource --> TSM TSM --> PSM TSM --> ThreadPending ThreadPending --> SignalInfo
Diagram: Process Signal Manager in the Signal System
Sources: src/api/process.rs(L32 - L82)
Key Relationships
- Thread Signal Manager: Thread Signal Managers reference a Process Signal Manager, allowing them to check for process-level signals when no thread-specific signals are pending.
- Signal Actions: The Process Signal Manager maintains the signal actions table that defines how signals are handled. This table is shared across all threads in the process.
- Wait Queue: The Process Signal Manager provides a wait queue that allows tasks to wait for signals, with potential false wakeups due to its shared nature.
- Signal Delivery: When signals are sent to a process, they're queued in the Process Signal Manager's pending signals queue. Threads can then dequeue these signals based on their signal masks.
Sources: src/api/process.rs(L32 - L82)
Implementation Details
The Process Signal Manager is a generic structure parameterized by two types:
M
: A type that implements theRawMutex
trait, used for synchronizationWQ
: A type that implements theWaitQueue
trait, used for signal waiting
This allows flexibility in the underlying synchronization mechanisms while maintaining a consistent API.
Constructor
#![allow(unused)] fn main() { pub fn new(actions: Arc<Mutex<M, SignalActions>>, default_restorer: usize) -> Self }
Creates a new Process Signal Manager with the given signal actions and default restorer function.
Signal Handling
The send_signal
method adds a signal to the pending queue and notifies waiting tasks:
#![allow(unused)] fn main() { pub fn send_signal(&self, sig: SignalInfo) { self.pending.lock().put_signal(sig); self.wq.notify_one(); } }
This simple mechanism ensures that signals are properly queued and waiting tasks are notified, allowing them to check for and potentially handle the new signal.
Sources: src/api/process.rs(L49 - L82)
Usage Considerations
When using the Process Signal Manager, consider these important points:
- Shared Access: The Process Signal Manager is shared across all threads in a process, requiring proper synchronization (provided by the mutex implementations).
- Wait Queue Behavior: The wait queue may cause false wakeups since it's shared by all threads in the process. Applications should be designed to handle this case.
- Default Restorer: The default restorer function is architecture-specific and is used when a signal handler doesn't provide its own restorer.
- Signal Actions: Signal actions define the behavior for each signal and are shared across the process, ensuring consistent handling regardless of which thread receives a signal.
Sources: src/api/process.rs(L32 - L82)