public function fork(Process $children, $user_name = null, $group_name = null)
 {
     if ($this->allocateSHMPerChildren()) {
         $children->setSHMSegment(new SHMCache(uniqid('process_manager;shm_per_children' . $children->getInternalId()), $this->allocateSHMPerChildren));
     }
     pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
     $pid = pcntl_fork();
     // Error
     if ($pid == -1) {
         throw new RuntimeException('pcntl_fork() returned -1, are you sure you are running the script from CLI?');
     } else {
         if (!$pid) {
             if (!is_null($group_name)) {
                 if (!$this->setGroup($group_name)) {
                     throw new RuntimeException('set group_name failed. are you sure you have the privileges?');
                 }
             }
             if (!is_null($user_name)) {
                 if (!$this->setUser($user_name)) {
                     throw new RuntimeException('set user_name failed. are you sure you have the privileges?');
                 }
             }
             $children->run();
             exit;
             // redundant, added only for clarity
         } else {
             $children->setStarted(true);
             $this->children[] = $children;
             // Store the children's PID
             $children->setPid($pid);
             pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
         }
     }
 }
 /**
  * Create a ParallelParentCollector that will collect
  * issues via a message queue. You'll want to do the
  * real collection via
  * \Phan\Output\Collector\ParallelChildCollector.
  *
  * @param IssueCollectorInterface $base_collector
  * A collector must be given to which collected issues
  * will be passed
  */
 public function __construct(IssueCollectorInterface $base_collector)
 {
     assert(extension_loaded('sysvsem'), 'PHP must be compiled with --enable-sysvsem in order to use -j(>=2).');
     assert(extension_loaded('sysvmsg'), 'PHP must be compiled with --enable-sysvmsg in order to use -j(>=2).');
     $this->base_collector = $base_collector;
     // Create a message queue for this process group
     $message_queue_key = posix_getpgid(posix_getpid());
     $this->message_queue_resource = msg_get_queue($message_queue_key);
     // Listen for ALARMS that indicate we should flush
     // the queue
     pcntl_sigprocmask(SIG_UNBLOCK, array(SIGUSR1), $old);
     pcntl_signal(SIGUSR1, function () {
         $this->readQueuedIssues();
     });
 }
Beispiel #3
0
 private function configureSignals()
 {
     if (extension_loaded('pcntl')) {
         if (!defined('AMQP_WITHOUT_SIGNALS')) {
             define('AMQP_WITHOUT_SIGNALS', false);
         }
         pcntl_signal(SIGUSR1, [&$this, 'signalHandler']);
         pcntl_signal(SIGTERM, [&$this, 'signalHandler']);
         pcntl_signal(SIGHUP, [&$this, 'signalHandler']);
         pcntl_signal(SIGINT, [&$this, 'signalHandler']);
         pcntl_signal(SIGQUIT, [&$this, 'signalHandler']);
         pcntl_signal(SIGUSR2, [&$this, 'signalHandler']);
         pcntl_signal(SIGALRM, [&$this, 'alarmHandler']);
         pcntl_sigprocmask(SIG_BLOCK, array(SIGHUP));
     }
 }
 /**
  * ワーカーの後処理
  */
 public function fin()
 {
     if ($this->_sigset) {
         // シグナルマスクを解除
         pcntl_sigprocmask(SIG_UNBLOCK, $this->_sigset);
         $this->_sigset = null;
     }
     if ($this->_pidlock) {
         // PIDファイルのアンロック
         $this->_pidlock->release();
         $this->_pidlock = null;
         // ログ
         $pid = posix_getpid();
         $this->_log("exit worker [{$pid}]");
     }
 }
Beispiel #5
0
function watchdog()
{
    $childpid = 0;
    $signals = array(SIGINT, SIGCHLD);
    pcntl_sigprocmask(SIG_BLOCK, $signals);
    do {
        printf("%s watchdog launching daemon...\n", @date('r'));
        if (0 === ($childpid = pcntl_fork())) {
            unreliable_daemon();
            exit(1);
        }
        $signal = pcntl_sigwaitinfo($signals, $info);
    } while ($signal != SIGINT);
    echo "watchdog got SIGINT. killing child...\n";
    posix_kill($childpid, SIGKILL);
    echo "watchdog exiting...\n";
}
Beispiel #6
0
 /**
  * Creates a new fork of the process and sets all related properties
  *
  * @throws UnableToForkException
  * @return int|false pid of the new process for the parent, false for the child
  */
 public function fork()
 {
     pcntl_sigprocmask(SIG_BLOCK, [SIGCHLD]);
     $pid = pcntl_fork();
     if ($pid === -1) {
         throw new UnableToForkException();
     } else {
         if ($pid) {
             $this->isParent = true;
             $this->children[$pid] = $pid;
             $this->childrenCount++;
             pcntl_sigprocmask(SIG_UNBLOCK, [SIGCHLD]);
             return $pid;
         } else {
             $this->isParent = false;
             $this->children = [];
             $this->childrenCount = 0;
             return false;
         }
     }
 }
 /**
  * 运行守护进程,监控有变化的日志文件。
  * 
  * @see ZtChart_Model_Monitor_Abstract::daemon()
  */
 public function run()
 {
     if (0 == ($pid = pcntl_fork())) {
         // 子进程负责处理当前日志
         try {
             $this->tail($this->_console->getLogPaths());
         } catch (ZtChart_Model_Monitor_Exception $e) {
             $this->_logger->err($e->getMessage());
             exit(1);
         }
     } else {
         if (0 < $pid) {
             pcntl_setpriority(-1);
             // 父进程负责把子进产生的数据写入数据库
             if (pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD, SIGALRM, SIGINT, SIGTERM))) {
                 $interval = 10;
                 // 10秒写一次
                 pcntl_alarm($interval);
                 while ($signo = pcntl_sigwaitinfo(array(SIGCHLD, SIGALRM, SIGINT, SIGTERM))) {
                     if (SIGALRM == $signo) {
                         pcntl_alarm($interval);
                     }
                     try {
                         $this->extract($interval);
                     } catch (ZtChart_Model_Monitor_Exception $e) {
                         posix_kill($pid, 9);
                         exit(1);
                     }
                     if (SIGCHLD == $signo || SIGINT == $signo || SIGTERM == $signo) {
                         break;
                     }
                 }
             }
         }
     }
     exit(0);
 }
 public function fork(Process $children)
 {
     if ($this->allocateSHMPerChildren()) {
         $children->setSHMSegment(new \Zebra\Ipcs\SHMCache(\uniqid('process_manager;shm_per_children' . $children->getInternalId()), $this->allocateSHMPerChildren));
     }
     \pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
     $pid = \pcntl_fork();
     // Error
     if ($pid == -1) {
         throw new RuntimeException('pcntl_fork() returned -1, are you sure you are running the script from CLI?');
     } else {
         if (!$pid) {
             $children->run();
             exit;
             // redundant, added only for clarity
         } else {
             $children->setStarted(true);
             $this->children[] = $children;
             // Store the children's PID
             $children->setPid($pid);
             \pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
         }
     }
 }
Beispiel #9
0
function server_loop()
{
    $SERVER =& $GLOBALS['SERVER'];
    $CONF =& $GLOBALS['CONF'];
    $CHILDRENS =& $GLOBALS['CHILDRENS'];
    // create perfork children loop
    $trymask = 0;
    while ($GLOBALS['ALLOW_RUN'] == true) {
        // does allow fork children?
        if ($GLOBALS['ALLOW_FORK'] == false) {
            continue;
        }
        //create
        $idlecount = utils_mem_idle_get();
        for ($ice = $idlecount; $ice < $CONF['daemon']['max_idle_servers']; $ice++) {
            // max of connections
            $children_list_count = count($CHILDRENS);
            if ($children_list_count > $CONF['daemon']['max_connections']) {
                utils_message('[' . __FUNCTION__ . ']: Connection max of limits!', 0, $SERVER['runmode'], $SERVER['output_level']);
                break;
            }
            //block all sig before fork children
            pcntl_sigprocmask(SIG_BLOCK, array(SIGTERM, SIGINT, SIGCHLD, SIGHUP));
            // current
            $pid = pcntl_fork();
            if ($pid == -1) {
                utils_message('[' . __FUNCTION__ . ']: Children fork failure!', 0, $SERVER['runmode'], $SERVER['output_level']);
                die;
            }
            if ($pid == 0) {
                //in child
                //in child signal must default and unlock in children
                pcntl_signal(SIGTERM, SIG_DFL);
                pcntl_signal(SIGINT, SIG_DFL);
                pcntl_signal(SIGCHLD, SIG_DFL);
                pcntl_signal(SIGHUP, SIG_DFL);
                pcntl_sigprocmask(SIG_UNBLOCK, array(SIGTERM, SIGINT, SIGCHLD, SIGHUP));
                //run children work
                server_children_work();
                exit;
            } else {
                //in parent
                utils_message('[' . __FUNCTION__ . ']: children ' . $pid . ' created!', 4, $SERVER['runmode'], $SERVER['output_level']);
                //save memory
                utils_mem_idle_inc();
                //recored childrens
                $CHILDRENS[$pid] = null;
                // unblock
                pcntl_sigprocmask(SIG_UNBLOCK, array(SIGTERM, SIGINT, SIGCHLD, SIGHUP));
            }
        }
        usleep(10000);
    }
}
Beispiel #10
0
 /**
  * Get system-specific signal handler
  *
  * @return callable
  */
 protected function getSignalHandler()
 {
     return function (SignalHandler $handler, $signal) {
         if (SIGKILL != $signal) {
             //do not redefine SIGKILL, for consistency
             pcntl_sigprocmask(SIG_UNBLOCK, [$signal]);
             if (!pcntl_signal($signal, [$handler, 'handle'])) {
                 $this->logger->error('Failed to register system signal ' . $signal . ': ' . pcntl_strerror(pcntl_get_last_error()));
             } else {
                 $this->logger->info('Registered system signal: ' . $signal);
             }
         }
     };
 }
Beispiel #11
0
 private function become_worker()
 {
     $this->log_method_call(__FUNCTION__);
     $pid = $this->fork_process();
     if ($pid === 0) {
         $this->worker_pid = posix_getpid();
         // The child process ignores SIGINT (small race here)
         pcntl_sigprocmask(SIG_BLOCK, array(SIGINT));
         // and lets go of the parent's libevent base
         event_base_reinit($this->event_base);
         // and breaks out of the service event loop
         event_base_loopbreak($this->event_base);
         // and dismantles the whole event structure
         foreach ($this->events as $i => $event) {
             event_del($event);
             event_free($event);
             unset($this->events[$i]);
         }
         $bufferevents = array_merge($this->offers_accepted, $this->offers_waiting, $this->offers_written, $this->requests_accepted, $this->requests_buffered, $this->requests_written, $this->requests_working, $this->responses_accepted, $this->responses_buffering);
         foreach ($bufferevents as $event) {
             event_buffer_disable($event, EV_READ | EV_WRITE);
             event_buffer_free($event);
         }
         event_base_free($this->event_base);
         unset($this->event_base);
         $this->worker = new Prefork_Worker($this);
         return true;
     }
     $start_time = microtime(true);
     $this->workers_alive[$pid] = $start_time;
     $this->workers_starting[$pid] = $start_time;
     return false;
 }
Beispiel #12
0
 public function testUnblockingSignals()
 {
     pcntl_sigprocmask(SIG_BLOCK, array(SIGQUIT), $oldset);
     $pid = pcntl_fork();
     if (0 === $pid) {
         Signal::unblock(array(SIGQUIT));
         while (true) {
             sleep(1);
         }
         exit(0);
     }
     // Put mask back on this process.
     pcntl_sigprocmask(SIG_SETMASK, $oldset);
     $this->assertProcessUp($pid);
     posix_kill($pid, SIGQUIT);
     // Clear off pending process.
     pcntl_waitpid($pid, $status);
     exec("ps {$pid}", $lines);
     $this->assertTrue(count($lines) < 2);
     // Check status exit was SIGQUIT
     $this->assertEquals(SIGQUIT, $status);
 }
Beispiel #13
0
 /**
  * Unblock common used signals
  */
 public static function stopSignalHandler()
 {
     pcntl_sigprocmask(SIG_UNBLOCK, array(SIGTERM, SIGINT, SIGQUIT));
 }
 /**
  * Registers a callback function for the signal dispatcher or for special signals used by PowerProcess
  * 
  * Special signals are:
  *   - 'shutdown' : Triggered on completion of the Shutdown() method
  *   - 'threadotl' : Triggered on killing a thread due to exceeding time limit
  *   
  * @param int|string $signal The signal to register a callback for
  * @param callback $callback The callback function
  */
 public function RegisterCallback($signal, $callback = false)
 {
     if ($callback !== false) {
         $this->callbacks[$signal][] = $callback;
     }
     // Register with PCNTL
     if (is_int($signal)) {
         $this->Log("Registering signal {$signal} with dispatcher", true);
         pcntl_signal($signal, array(&$this, 'SignalDispatch'));
         // Unblock the Signal
         pcntl_sigprocmask(SIG_UNBLOCK, array($signal));
     }
 }
Beispiel #15
0
 /**
  * Starts the thread.
  * @return bool On successful execution returns true otherwise returns false.
  */
 public final function start()
 {
     // {{{
     if (!$this->amIParent()) {
         return false;
     }
     if ($this->amIStarted) {
         return false;
     }
     $this->childPid = pcntl_fork();
     if ($this->childPid == -1) {
         return false;
     }
     $this->_childPid = getmypid();
     $this->amIStarted = true;
     $csInitializationResult = null;
     if ($this->criticalSection !== null) {
         $csInitializationResult = $this->criticalSection->initialize($this->childPid, $this->uniqueId);
     }
     if (!$this->amIParent()) {
         // child
         // no dispatchers needed in the children; this means that no threads withing threads creation is possible
         unregister_tick_function('GPhpThreadCriticalSection::dispatch');
         // flag any subscribed variables indicating that the current
         // instance is located in a GPhpThread
         foreach (self::$originDynamicDataArr as &$o) {
             if ($o instanceof \GPhpThreadNotCloneableContainer) {
                 $o->import(true);
             }
         }
         if ($csInitializationResult === false) {
             $this->stop();
         }
         // don't execute the thread body if critical section is required, but missing
         pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
         $this->run();
         if ($this->criticalSection !== null) {
             $this->notifyParentThatChildIsTerminated();
         }
         $this->stop();
     } else {
         // parent
         if ($this->childPid != -1 && $this->criticalSection !== null) {
             if ($csInitializationResult === false) {
                 // don't add the thread to the dispatch queue if missing but required critical section is the case (actually this is done in the initialize method above)
                 $this->childPid = -1;
                 $this->_childPid = null;
                 $this->amIStarted = false;
                 return false;
             }
             if (!GPhpThread::$isCriticalSectionDispatcherRegistered) {
                 GPhpThread::$isCriticalSectionDispatcherRegistered = register_tick_function('GPhpThreadCriticalSection::dispatch');
             }
             pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
             // SIGCHLD will wait in the queue until it's processed
         }
         return true;
     }
     return true;
 }
Beispiel #16
0
 /**
  * @param \EvWatcher $watcher
  * @param BeanieWorker $worker
  * @param JobOath $jobOath
  */
 protected function handleIncomingJob(\EvWatcher $watcher, BeanieWorker $worker, JobOath $jobOath)
 {
     pcntl_sigprocmask(SIG_BLOCK, $this->terminationSignals);
     try {
         $job = $jobOath->invoke();
         call_user_func($this->jobReceivedCallback, $job);
     } catch (SocketException $socketException) {
         $this->logger->error($socketException->getCode() . ': ' . $socketException->getMessage());
         $this->removeWatcher($watcher);
         $this->removeJobListener($worker);
         return;
     } catch (\Exception $exception) {
         $this->logger->error($exception->getCode() . ': ' . $exception->getMessage());
         $this->removeWatcher($watcher);
         return;
     } finally {
         pcntl_sigprocmask(SIG_UNBLOCK, $this->terminationSignals);
     }
     $worker->reserveOath();
 }
Beispiel #17
0
 /**
  * Time the execution loop and sleep an appropriate amount of time.
  * @param boolean $start
  * @return mixed
  */
 private function timer($start = false)
 {
     static $start_time = null;
     // Start the Stop Watch and Return
     if ($start) {
         return $start_time = microtime(true);
     }
     // End the Stop Watch
     // Determine if we should run the ON_IDLE tasks.
     // In timer based applications, determine if we have remaining time.
     // Otherwise apply the $idle_probability factor
     $end_time = $probability = null;
     if ($this->loop_interval) {
         $end_time = $start_time + $this->loop_interval() - 0.01;
     }
     if ($this->idle_probability) {
         $probability = 1 / $this->idle_probability;
     }
     $is_idle = function () use($end_time, $probability) {
         if ($end_time) {
             return microtime(true) < $end_time;
         }
         if ($probability) {
             return mt_rand(1, $probability) == 1;
         }
         return false;
     };
     // If we have idle time, do any housekeeping tasks
     if ($is_idle()) {
         $this->dispatch(array(Core_Daemon::ON_IDLE), array($is_idle));
     }
     $stats = array();
     $stats['duration'] = microtime(true) - $start_time;
     $stats['idle'] = $this->loop_interval - $stats['duration'];
     // Suppress child signals during sleep to stop exiting forks/workers from interrupting the timer.
     // Note: SIGCONT (-18) signals are not suppressed and can be used to "wake up" the daemon.
     if ($stats['idle'] > 0) {
         pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
         usleep($stats['idle'] * 1000000);
         pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
     } else {
         // There is no time to sleep between intervals -- but we still need to give the CPU a break
         // Sleep for 1/100 a second.
         usleep(10000);
         if ($this->loop_interval > 0) {
             $this->error('Run Loop Taking Too Long. Duration: ' . number_format($stats['duration'], 3) . ' Interval: ' . $this->loop_interval);
         }
     }
     $this->stats[] = $stats;
     return $stats;
 }
Beispiel #18
0
 /**
  * Constructor.
  *
  * @param array $options options.
  *
  * @return void
  */
 protected function __construct(array $options)
 {
     // Setup logger.
     $this->_logger = \Logger::getLogger(get_class($this));
     $this->_logDebugEnabled = $this->_logger->isDebugEnabled();
     $soullessArray = array();
     $this->_beanAliases = $soullessArray;
     $this->_beanDefs = $soullessArray;
     $this->_beans = $soullessArray;
     $this->_shutdowners = $soullessArray;
     $this->_resources = $soullessArray;
     $this->_eventListeners = $soullessArray;
     $this->_properties = $soullessArray;
     // Merge options with our defaults.
     self::$_options = array_replace_recursive(self::$_options, $options);
     $this->registerProperties(self::$_options['properties']);
     $sapi = php_sapi_name();
     if (function_exists('pcntl_signal')) {
         if ($sapi == 'cgi' || $sapi == 'cli') {
             $signals = array(SIGQUIT, SIGHUP, SIGINT, SIGCHLD, SIGTERM, SIGUSR1, SIGUSR2);
             $handler = array($this, 'signalHandler');
             foreach ($signals as $signal) {
                 pcntl_signal($signal, $handler);
             }
             pcntl_sigprocmask(SIG_UNBLOCK, $signals);
         }
     }
     set_error_handler(array($this, 'errorHandler'));
     register_shutdown_function(array($this, 'shutdownHandler'));
     $this->_lifecycleManager = new BeanLifecycleManager();
     $this->_dispatcherTemplate = new DispatcherImpl();
     $this->_aspectManager = new AspectManager();
     $this->_aspectManager->setCache(DummyCacheImpl::getInstance());
     $this->_beanDefCache = DummyCacheImpl::getInstance();
     $this->_beanCache = DummyCacheImpl::getInstance();
     $this->registerBeanDefinitionProvider(new Core(self::$_options));
     $this->_reflectionFactory = $this;
     $this->_reflectionFactory = $this->getBean('dingReflectionFactory');
     $this->_proxyFactory = $this->getBean('dingProxyFactory');
     $this->_beanDefCache = $this->getBean('dingDefinitionsCache');
     $this->_beanCache = $this->getBean('dingBeanCache');
     $this->_lifecycleManager = $this->getBean('dingLifecycleManager');
     $this->_aspectManager = $this->getBean('dingAspectManager');
     $this->_dispatcherTemplate = $this->getBean('dingAspectCallDispatcher');
     // Set drivers
     if (isset(self::$_options['bdef']['xml'])) {
         $xmlDriver = $this->getBean('dingXmlBeanDefinitionProvider');
     }
     if (isset(self::$_options['bdef']['yaml'])) {
         $yamlDriver = $this->getBean('dingYamlBeanDefinitionProvider');
     }
     $this->getBean('dingPropertiesDriver');
     $this->getBean('dingMessageSourceDriver');
     $this->getBean('dingMethodInjectionDriver');
     // All set, continue.
     if (isset(self::$_options['bdef']['annotation'])) {
         $this->getBean('dingAnnotationDiscovererDriver');
         $this->getBean('dingAnnotationBeanDefinitionProvider');
         $this->getBean('dingAnnotationValueDriver');
         $this->getBean('dingAnnotationResourceDriver');
         $this->getBean('dingAnnotationInjectDriver');
         $this->getBean('dingAnnotationInitDestroyMethodDriver');
         $this->getBean('dingAnnotationRequiredDriver');
         $this->getBean('dingMvcAnnotationDriver');
     }
     $this->_lifecycleManager->afterConfig();
 }
Beispiel #19
0
<?php

// This is more or less a copy of zend/bad/ext/pcntl/tests/003.php.
// 003.php.skipif is overly-cautious, so it would skip that test.  This test
// also makes less assumptions about what the blocked signal set looks like
// coming into the test.
pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD, SIGTERM), $first_set);
pcntl_sigprocmask(SIG_BLOCK, array(SIGINT), $old);
var_dump(count($old) - count($first_set));
pcntl_sigprocmask(SIG_UNBLOCK, array(SIGINT), $old);
var_dump(count($old) - count($first_set));
pcntl_sigprocmask(SIG_SETMASK, array(SIGINT), $old);
var_dump(count($old) - count($first_set));
pcntl_sigprocmask(SIG_SETMASK, array(), $old);
var_dump(count($old));
pcntl_sigprocmask(SIG_SETMASK, array(), $old);
var_dump(count($old));
Beispiel #20
0
<?php

declare (ticks=1);
$parentPid = posix_getpid();
$child1 = pcntl_fork();
if ($child1 != 0) {
    $child2 = pcntl_fork();
    if ($child2 != 0) {
        pcntl_setpriority(10);
        echo "Parent\n";
        $firstChildIsFree = true;
        $secondChildIsFree = true;
        pcntl_sigprocmask(SIG_BLOCK, array(SIGUSR1, SIGUSR2));
        while (true) {
            $changes = file_get_contents('db.txt');
            if (!empty($changes)) {
                $got2execution = false;
                if ($firstChildIsFree) {
                    posix_kill($child1, SIGHUP);
                    $firstChildIsFree = false;
                    $got2execution = true;
                } elseif ($secondChildIsFree) {
                    posix_kill($child2, SIGHUP);
                    $secondChildIsFree = false;
                    $got2execution = true;
                }
                if ($got2execution) {
                    file_put_contents('db.txt', '');
                } else {
                    echo "No free workers\n";
                }
Beispiel #21
0
        echo "signo === SIGCHLD\n";
        var_dump($siginfo['signo'] === SIGCHLD);
        echo "signo === uid\n";
        var_dump($siginfo['uid'] === posix_getuid());
        echo "signo === pid\n";
        var_dump($siginfo['pid'] === $pid);
        pcntl_waitpid($pid, $status);
        set_error_handler(function ($errno, $errstr) {
            echo "Error triggered\n";
        }, E_WARNING);
        echo "sigprocmask with invalid arguments\n";
        /* Valgrind expectedly complains about this:
         * "sigprocmask: unknown 'how' field 2147483647"
         * Skip */
        if (getenv("USE_ZEND_ALLOC") !== '0') {
            var_dump(pcntl_sigprocmask(PHP_INT_MAX, array(SIGTERM)));
        } else {
            echo "Error triggered\n";
            echo "bool(false)\n";
        }
        var_dump(pcntl_sigprocmask(SIG_SETMASK, array(0)));
        echo "sigwaitinfo with invalid arguments\n";
        var_dump(pcntl_sigwaitinfo(array(0)));
        echo "sigtimedwait with invalid arguments\n";
        var_dump(pcntl_sigtimedwait(array(SIGTERM), $signo, PHP_INT_MAX, PHP_INT_MAX));
    } else {
        $siginfo = NULL;
        pcntl_sigtimedwait(array(SIGINT), $siginfo, 3600, 0);
        exit;
    }
}
Beispiel #22
0
 /**
  * Unblock an array of signals so that
  * the process thread will receive them.
  * @param array $signals
  */
 public static function unblock(array $signals)
 {
     $signals = array_map(array(__CLASS__, 'interpretSignal'), $signals);
     pcntl_sigprocmask(SIG_UNBLOCK, $signals, $old);
 }
<?php

// For simple cases, see php5_pcntl_003.php
print "Correct usage, two args\n";
var_dump(pcntl_sigprocmask(SIG_BLOCK, [SIGHUP]));
print "Invalid \$how\n";
var_dump(pcntl_sigprocmask(PHP_INT_MAX, []));
print "Invalid signal\n";
var_dump(pcntl_sigprocmask(SIG_SETMASK, [1337]));
print "Invalid byref arg\n";
$oldset = new stdClass();
var_dump(pcntl_sigprocmask(SIG_SETMASK, [SIGHUP], $oldset));
var_dump($oldset);
Beispiel #24
0
 /**
  * Sig Proc Mask
  *
  * @param int   $how    Sets the behavior of pcntl_sigprocmask(). Possible values: SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK
  * @param array $set    List of signals.
  * @param array $oldSet The oldset parameter is set to an array containing the list of the previously blocked signals.
  *
  * @return bool Returns TRUE on success or FALSE on failure.
  */
 public function sigProcMask($how, array $set, array $oldSet = array())
 {
     return pcntl_sigprocmask($how, $set, $oldSet);
 }
Beispiel #25
0
 /**
  * Fork a process, execute the callback and store process information
  *
  * @param string $name
  * @param callable $callback
  * @return bool True in parent process and False in child process if no callback was supplied
  */
 protected function forkChild($name, callable $callback = null)
 {
     $pid = \pcntl_fork();
     if ($pid === -1) {
         throw new \RuntimeException('Failed to fork process "' . $name . '"".');
     } elseif ($pid === 0) {
         if (function_exists('\\cli_set_process_title')) {
             \cli_set_process_title('php ' . $_SERVER['argv'][0] . ' (' . $name . ': ' . ((isset($this->processStartCounter[$name]) ? $this->processStartCounter[$name] : 0) + 1) . ')');
         }
         \pcntl_sigprocmask(SIG_SETMASK, []);
         unset($this->processCallbacks);
         unset($this->processFinished);
         unset($this->processPIDs);
         unset($this->processRestart);
         unset($this->processStartCounter);
         unset($this->processStarted);
         unset($this->processTimeouts);
         if ($callback !== null) {
             call_user_func($callback);
             exit(0);
         } else {
             return false;
         }
     }
     $this->processPIDs[$pid] = $name;
     $this->processStarted[$name] = microtime(true);
     $this->processStartCounter[$name] = (isset($this->processStartCounter[$name]) ? $this->processStartCounter[$name] : 0) + 1;
     unset($this->processRestart[$name]);
     return true;
 }