public function handle(int $signal)
    {
        // If this signal is already being handled, return a Failure Promise and don't do anything
        if (isset($this->handlers[$signal]) && $this->handlers[$signal] === true) {
            return new Failure(new Exception('Signal is already being processed.'));
        }

        // Indicate that we're handling this signal to block repeat signals
        $this->handlers[$signal] = true;

        // Disable processing of new jobs while we handle the signal
        $this->dispatcher->setIsRunning(false);

        // Call the signal handler from the signal mapping
        $fn = $this->signals[$signal];
        $result = $this->$fn();

        // $result is either going to be `null` or a boolean value
        // If it's `true`, then skip the shutdown sequence
        if ($result === true) {
            unset($this->handlers[$signal]);
            return new Success($result);
        }

        // Wait until all processes have ended before resolving the promise
        $deferred = new Deferred;
        Loop::repeat(1000, function ($watcherId, $callback) use ($deferred, $signal, $result) {
            if (count($this->dispatcher->getProcesses()) === 0) {
                Loop::cancel($watcherId);
                unset($this->handlers[$signal]);
                return $deferred->resolve($result);
            }
        });

        return $deferred->promise();
    }