Spaces:
No application file
No application file
| declare(strict_types=1); | |
| namespace Mautic\CoreBundle\ProcessSignal; | |
| use Mautic\CoreBundle\ProcessSignal\Exception\SignalCaughtException; | |
| class ProcessSignalService | |
| { | |
| public const SIGTERM = 15; | |
| public const SIGINT = 2; | |
| private const SIGNALS = [self::SIGTERM, self::SIGINT]; | |
| private ?int $signal = null; | |
| /** | |
| * @param int[] $signals | |
| */ | |
| public function registerSignalHandler(callable $beforeCallback = null, array $signals = self::SIGNALS): void | |
| { | |
| if (!function_exists('pcntl_signal')) { | |
| return; | |
| } | |
| $handler = function (int $signal) use ($beforeCallback): void { | |
| if ($beforeCallback) { | |
| call_user_func($beforeCallback, $signal); | |
| } | |
| $this->signal = $signal; | |
| }; | |
| foreach ($signals as $signal) { | |
| pcntl_signal($signal, $handler); | |
| } | |
| } | |
| /** | |
| * @param int[] $signals | |
| */ | |
| public function restoreSignalHandler(array $signals = self::SIGNALS): void | |
| { | |
| if (!function_exists('pcntl_signal')) { | |
| return; | |
| } | |
| foreach ($signals as $signal) { | |
| pcntl_signal($signal, SIG_DFL); | |
| } | |
| } | |
| public function isSignalCaught(): bool | |
| { | |
| if (!function_exists('pcntl_signal_dispatch')) { | |
| return false; | |
| } | |
| pcntl_signal_dispatch(); | |
| return null !== $this->signal; | |
| } | |
| /** | |
| * @throws SignalCaughtException | |
| */ | |
| public function throwExceptionIfSignalIsCaught(): void | |
| { | |
| if (!$this->isSignalCaught()) { | |
| return; | |
| } | |
| throw new SignalCaughtException($this->signal); | |
| } | |
| } | |