Signals.php
TLDR
The Signals
class in the Illuminate\Console
namespace is responsible for registering and unregistering signal handlers for console applications. It interacts with the SignalRegistry
class. It also provides a method to check if signals are available and execute a callback if so.
Methods
__construct($registry)
This is the constructor method that creates a new instance of the Signals
class. It takes a SignalRegistry
object as a parameter and assigns it to the $registry
property.
register($signal, $callback)
This method is used to register a new signal handler. It takes an integer $signal
parameter and a callable $callback
parameter. It registers the signal and the callback with the SignalRegistry
object. It also sets and updates the handlers for the signal.
initializeSignal($signal)
This is a protected method that initializes the signal's existing handler in array format. It takes an integer $signal
parameter and checks if the existing handler is callable. If it is, it returns an array containing the existing handler, otherwise it returns null.
unregister()
This method is used to unregister the current signal handlers. It restores the previous handlers and sets them as the current handlers in the SignalRegistry
object.
whenAvailable($callback)
This is a static method that executes the given callback if signals are available. It checks if the availability resolver returns true and if so, it calls the callback.
getHandlers()
This is a protected method that returns the registry's handlers. It retrieves the signalHandlers
property from the SignalRegistry
object.
setHandlers($handlers)
This is a protected method that sets the registry's handlers. It assigns the given handlers to the signalHandlers
property of the SignalRegistry
object.
resolveAvailabilityUsing($resolver)
This is a static method that sets the availability resolver. It takes a callable resolver as a parameter and assigns it to the availabilityResolver
property of the Signals
class.
Classes
There are no additional classes in this file.
<?php
namespace Illuminate\Console;
/**
* @internal
*/
class Signals
{
/**
* The signal registry instance.
*
* @var \Symfony\Component\Console\SignalRegistry\SignalRegistry
*/
protected $registry;
/**
* The signal registry's previous list of handlers.
*
* @var array<int, array<int, callable>>|null
*/
protected $previousHandlers;
/**
* The current availability resolver, if any.
*
* @var (callable(): bool)|null
*/
protected static $availabilityResolver;
/**
* Create a new signal registrar instance.
*
* @param \Symfony\Component\Console\SignalRegistry\SignalRegistry $registry
* @return void
*/
public function __construct($registry)
{
$this->registry = $registry;
$this->previousHandlers = $this->getHandlers();
}
/**
* Register a new signal handler.
*
* @param int $signal
* @param callable(int $signal): void $callback
* @return void
*/
public function register($signal, $callback)
{
$this->previousHandlers[$signal] ??= $this->initializeSignal($signal);
with($this->getHandlers(), function ($handlers) use ($signal) {
$handlers[$signal] ??= $this->initializeSignal($signal);
$this->setHandlers($handlers);
});
$this->registry->register($signal, $callback);
with($this->getHandlers(), function ($handlers) use ($signal) {
$lastHandlerInserted = array_pop($handlers[$signal]);
array_unshift($handlers[$signal], $lastHandlerInserted);
$this->setHandlers($handlers);
});
}
/**
* Gets the signal's existing handler in array format.
*
* @return array<int, callable(int $signal): void>
*/
protected function initializeSignal($signal)
{
return is_callable($existingHandler = pcntl_signal_get_handler($signal))
? [$existingHandler]
: null;
}
/**
* Unregister the current signal handlers.
*
* @return void
*/
public function unregister()
{
$previousHandlers = $this->previousHandlers;
foreach ($previousHandlers as $signal => $handler) {
if (is_null($handler)) {
pcntl_signal($signal, SIG_DFL);
unset($previousHandlers[$signal]);
}
}
$this->setHandlers($previousHandlers);
}
/**
* Execute the given callback if "signals" should be used and are available.
*
* @param callable $callback
* @return void
*/
public static function whenAvailable($callback)
{
$resolver = static::$availabilityResolver;
if ($resolver()) {
$callback();
}
}
/**
* Get the registry's handlers.
*
* @return array<int, array<int, callable>>
*/
protected function getHandlers()
{
return (fn () => $this->signalHandlers)
->call($this->registry);
}
/**
* Set the registry's handlers.
*
* @param array<int, array<int, callable(int $signal):void>> $handlers
* @return void
*/
protected function setHandlers($handlers)
{
(fn () => $this->signalHandlers = $handlers)
->call($this->registry);
}
/**
* Set the availability resolver.
*
* @param callable(): bool
* @return void
*/
public static function resolveAvailabilityUsing($resolver)
{
static::$availabilityResolver = $resolver;
}
}