When the parent process exits, cleans shared memory and semaphore.

This is called using 'register_shutdown_function' pattern.
@see http://php.net/register_shutdown_function
559690
public function onShutdown()
	{
		if (posix_getpid() == $this->_nParentPid) {
			$this->_log('INFO: Parent shutdown, cleaning memory...');
			@shm_remove($this->_hShm) && @shm_detach($this->_hShm);
			@sem_remove($this->_hSem);
		}
	}
304741
final public static function shutdownFunctionHandler()
    {
        $lasterror = error_get_last();
        if (!FEnv::isset("framework.env")) {
            die($lasterror['message']);
        }

        if (isset($lasterror['type']) == true) {
            if ($lasterror['type'] === E_ERROR) {
                $mess = explode("Stack trace", $lasterror['message']);
                throw new Server500(new \ArrayObject(array("explain" => $mess[0],
                    "type_error" => self::errorMap($lasterror['type']),
                    "file_error" => $lasterror["file"], "line_error" => $lasterror["line"])));
            } elseif ($lasterror['type'] === E_PARSE) {
                $mess = explode("Stack trace", $lasterror['message']);
                throw new Server500(new \ArrayObject(array("explain" => $mess[0],
                    "type_error" => self::errorMap($lasterror['type']),
                    "file_error" => $lasterror["file"], "line_error" => $lasterror["line"])));
            } elseif ($lasterror['type'] === E_WARNING) {
                $mess = explode("Stack trace", $lasterror['message']);
                throw new Server500(new \ArrayObject(array("explain" => $mess[0],
                    "type_error" => self::errorMap($lasterror['type']),
                    "file_error" => $lasterror["file"], "line_error" => $lasterror["line"])));
            } else {
                trigger_error($lasterror['message']);
            }
        }

        exit(1);
    }
1368578
protected function handleShutdowns() {
        declare(ticks = 1);

        $self = $this;

        $cleanup = function($signal = null) use ($self) {
            if ($signal === SIGTERM) {
                fprintf(STDERR, 'Received SIGTERM...');
            } else if ($signal === SIGINT) {
                fprintf(STDERR, 'Received SIGINT...');
            } else if ($signal === SIGTSTP) {
                fprintf(STDERR, 'Received SIGTSTP...');
            }

            $self->deleteAllLocks();
            exit;
        };

        if (extension_loaded('pcntl')) {
            pcntl_signal(SIGTERM, $cleanup, false);
            pcntl_signal(SIGINT, $cleanup, false);
            pcntl_signal(SIGTSTP, $cleanup, false);
        }

        register_shutdown_function($cleanup);
    }
1034032
public function shutdownObject()
    {
        $this->cache->set('parsedFormats', $this->parsedFormats);
        $this->cache->set('parsedFormatsIndices', $this->parsedFormatsIndices);
        $this->cache->set('localizedSymbols', $this->localizedSymbols);
    }
668113
static function clear() {
    if ( empty(self::$_cache) || DEBUGKEEPTEMP ) return;
    
    foreach ( self::$_cache as $file ) {
      if (DEBUGPNG) print "[clear unlink $file]";
      unlink($file);
    }
  }
673385
public function cleanup()
    {
        // unlock everything
        foreach ($this->locks as $lock) {
            flock($lock, LOCK_UN);
            fclose($lock);
        }

        $this->locks = [];
    }
1118268
protected static function exitAndClearAll()
    {
        foreach (self::$_workers as $worker) {
            $socket_name = $worker->getSocketName();
            if ($worker->transport === 'unix' && $socket_name) {
                list(, $address) = explode(':', $socket_name, 2);
                @unlink($address);
            }
        }
        @unlink(self::$pidFile);
        self::log("Workerman[" . basename(self::$_startFile) . "] has been stopped");
        if (self::$onMasterStop) {
            call_user_func(self::$onMasterStop);
        }
        exit(0);
    }
1007450
public function shutdownProcesses()
    {
        foreach ($this->processes as $pid => $process) {
            unset($this->processes[$pid]);
    
            posix_kill($pid, SIGUSR1);
        }
    
        exit;
    }
453446
protected function ()
    {
        // Main processing loop for the parent process
        while (!$this->stopWork || \count($this->workers)) {
            $this->dispatchSignals();

            // Check for exited workers
            $status = null;
            $exitedPid = pcntl_wait($status, WNOHANG);

            // We run other workers, make sure this is a worker
            if (isset($this->workers[$exitedPid])) {
                /*
                 * If they have exited, remove them from the workers array
                 * If we are not stopping work, start another in its place
                 */
                if ($exitedPid) {
                    $workerId = $this->workers[$exitedPid]['id'];
                    $workerJobs = $this->workers[$exitedPid]['jobs'];
                    $exitCode = pcntl_wexitstatus($status);
                    unset($this->workers[$exitedPid]);

                    $this->logWorkerStatus($exitedPid, $workerJobs, $exitCode);

                    if (!$this->stopWork) {
                        $this->startWorker($workerJobs, $workerId, false);
                    }
                }
            }

            if ($this->stopWork) {
                if (time() - $this->stat['stopTime'] > 60) {
                    $this->log('Workers exiting timeout, will force killing.', ProcessLogger::PROC_INFO);
                    $this->stopWorkers(SIGKILL);
                }
            } else {
                // If any workers have been running 150% of max run time, forcibly terminate them
                foreach ($this->workers as $pid => $worker) {
                    if (!empty($worker['startTime']) && time() - $worker['startTime'] > $this->maxLifetime * 1.5) {
                        $this->logWorkerStatus($pid, $worker['jobs'], self::CODE_MANUAL_KILLED);
                        $this->sendSignal($pid, SIGKILL);
                    }
                }
            }

            // php will eat up your cpu if you don't have this
            usleep(10000);
        }
    }
1286283
static function cleanup()
    {
        $http = eZHTTPTool::instance();

        $http->removeSessionVariable( 'CanInstantiateClassList' );
        $http->removeSessionVariable( 'ClassesCachedForUser' );

        // Note: This must be done more generic with an internal
        //       callback system.
        eZPreferences::sessionCleanup();
    }
359822
protected function shutdown($restart = false)
    {
        // If we are already exiting, chill.
        if ($this->exiting) {
            return;
        } else // If not, now we are.
        {
            $this->exiting = true;
        }

        // If we aren't already daemonized then just kill the application.
        if (!$this->running && !$this->isActive()) {
            $this->getLogger()->info('Process was not daemonized yet, just halting current process');

            $this->close();
        }

        // Only read the pid for the parent file.
        if ($this->parentId == $this->processId) {
            // Read the contents of the process id file as an integer.
            $fp = fopen($this->config->get('application_pid_file'), 'r');
            $pid = fread($fp, filesize($this->config->get('application_pid_file')));
            $pid = (int) $pid;
            fclose($fp);

            // Remove the process id file.
            @ unlink($this->config->get('application_pid_file'));

            // If we are supposed to restart the daemon we need to execute the same command.
            if ($restart) {
                $this->close(exec(implode(' ', $GLOBALS['argv']) . ' > /dev/null &'));
            } else // If we are not supposed to restart the daemon let's just kill -9.
            {
                passthru('kill -9 ' . $pid);
                $this->close();
            }
        }
    }
970225
function cleanup( $process, $event )
    {
        $theGateway = $this->getCurrentGateway( $event );
        if( $theGateway != null and $theGateway->needCleanup() )
        {
            $theGateway->cleanup( $process, $event );
        }
    }
204342
static void shutdown() {
        synchronized (lock) {
            switch (state) {
            case RUNNING:       /* Initiate shutdown */
                state = HOOKS;
                break;
            case HOOKS:         /* Stall and then return */
            case FINALIZERS:
                break;
            }
        }
        synchronized (Shutdown.class) {
            sequence();
        }
    }
686650
public function onShutdown()
    {
        // Get the last error if there was one, if not, let's get out of here.
        if (!$error = error_get_last()) {
            return;
        }

        $fatal  = array(E_ERROR,E_PARSE,E_CORE_ERROR,E_COMPILE_ERROR,E_USER_ERROR,E_RECOVERABLE_ERROR);
        if (!in_array($error['type'], $fatal)) {
            return;
        }

        $message   = '[Shutdown Error]: %s';
        $message   = sprintf($message, $error['message']);
        $backtrace = array(array('file' => $error['file'], 'line' => $error['line']));

        $this->client->notifyOnError($message, $backtrace, 'error');
        error_log($message.' in: '.$error['file'].':'.$error['line']);
    }
532818
public function cleanup()
    {
        ezpEvent::getInstance()->notify( 'session/cleanup', array() );
        $db = eZDB::instance();
        eZSession::triggerCallback( 'cleanup_pre', array( $db ) );
        eZSession::triggerCallback( 'cleanup_post', array( $db ) );
        return true;
    }
1169603
protected function tearDown(): void
    {
        parent::tearDown();

        if ($this->prevSniffedFile && $this->prevSniffedFile !== $this->file->getFilename()) {
            $this->sniffedVars = [];
            $this->prevSniffedFile = '';
        }
    }
354447
public function unregister()
    {
        if ($this->child === 0) {
            // This is a child process so don't unregister worker
            // However if the shutdown was due to an error, for instance the job hitting the
            // max execution time, then catch the error and fail the job
            if (($error = error_get_last()) and in_array($error['type'], $this->shutdownErrors)) {
                $this->job->fail(new \ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
            }

            return;
        } elseif (!is_null($this->child)) {
            // There is a child process running
            $this->log('There is a child process pid:'.$this->child.' running, killing it', Logger::DEBUG);
            $this->killChild();
        }

        if (is_object($this->job)) {
            $this->job->fail(new Exception\Cancel);
            $this->log('Failing running job <pop>'.$this->job.'</pop>', Logger::NOTICE);
        }

        $this->log('Unregistering worker <pop>'.$this.'</pop>', Logger::NOTICE);

        $this->redis->srem(self::redisKey(), $this->id);
        $this->redis->expire(self::redisKey($this), \Resque::getConfig('default.expiry_time', \Resque::DEFAULT_EXPIRY_TIME));

        $this->host->finished($this);

        // Remove pid file if one set
        if (!is_null($this->pidFile) and getmypid() === (int)trim(file_get_contents($this->pidFile))) {
            unlink($this->pidFile);
        }

        Event::fire(Event::WORKER_UNREGISTER, $this);
    }