/**
  * @return boolean
  */
 public static function isForkedProfilingSupported()
 {
     if (null === self::$m_isForkedProfilingSupported) {
         self::$m_isForkedProfilingSupported = function_exists('pcntl_fork') && Memory_Shared_Shm::isSupported();
     }
     return self::$m_isForkedProfilingSupported;
 }
 /**
  * @see \Components\Debug_Profiler::profileCallForked() \Components\Debug_Profiler::profileCallForked()
  *
  * @return \Components\Test_Profiler
  */
 public static function profileCallForked(array $callable_, array $args_ = [])
 {
     if (false === static::isForkedProfilingSupported() || false === Memory_Shared_Shm::isSupported()) {
         throw new Exception_NotSupported('test/profiler', 'Forked profiling is not supported on this platform\'s configuration.');
     }
     if (false === is_callable($callable_)) {
         throw new Exception_IllegalArgument('test/profiler', 'Valid callback expected.');
     }
     $shm = Memory_Shared_Shm_Temporary::create();
     $shm->attach();
     self::$m_profileForkedArgs = $args_;
     self::$m_profileForkedCallable = $callable_;
     self::$m_profileForkedSegmentId = $shm->getSegmentId();
     $pid = pcntl_fork();
     if (-1 == $pid) {
         throw new Exception_IllegalState('test/profiler', 'Unable to fork child process. Forked profiling failed.');
     }
     if ($pid) {
         $pid = pcntl_wait($status);
     } else {
         ob_start();
         // FIXME (CSH) Find elegant solution to transfer state of global scope & context.
         Assertion_Context::push(new Assertion_Context());
         $sessionId = static::start();
         try {
             $returnValue = call_user_func_array(self::$m_profileForkedCallable, self::$m_profileForkedArgs);
             $profiler = static::stop($sessionId);
             $profiler->m_returnValue = $returnValue;
         } catch (\ErrorException $e) {
             $profiler = static::stop($sessionId);
             $profiler->m_exception = Exception_Flat::create($e);
         } catch (\Exception $e) {
             $profiler = static::stop($sessionId);
             $profiler->m_exception = Exception_Flat::create($e);
         }
         $assertions = Assertion_Context::pop()->getAssertions();
         self::$m_profileForkedArgs = null;
         self::$m_profileForkedCallable = null;
         $segment = Memory_Shared_Shm::forSegment(self::$m_profileForkedSegmentId);
         $segment->attach();
         $segment->set(1, ob_get_clean());
         $segment->set(2, $assertions);
         $segment->set(3, $profiler->result()->m_exception);
         $segment->set(4, $profiler->result()->m_memoryConsumptionAfter);
         $segment->set(5, $profiler->result()->m_memoryConsumptionBefore);
         $segment->set(6, $profiler->result()->m_memoryConsumptionPeak);
         $segment->set(7, $profiler->result()->m_posixSystemTime);
         $segment->set(8, $profiler->result()->m_posixUserTime);
         $segment->set(9, $profiler->result()->m_returnValue);
         $segment->set(10, $profiler->result()->m_timeStart);
         $segment->set(11, $profiler->result()->m_timeStop);
         $segment->set(12, $profiler->result()->m_splitTimeTable);
         exit(0);
     }
     echo $shm->get(1);
     Assertion_Context::current()->addAssertions((array) $shm->get(2));
     $profiler = new static();
     $profiler->m_profiling = false;
     $profiler->m_exception = $shm->get(3);
     $profiler->m_memoryConsumptionAfter = $shm->get(4);
     $profiler->m_memoryConsumptionBefore = $shm->get(5);
     $profiler->m_memoryConsumptionPeak = $shm->get(6);
     $profiler->m_posixSystemTime = $shm->get(7);
     $profiler->m_posixUserTime = $shm->get(8);
     $profiler->m_returnValue = $shm->get(9);
     $profiler->m_timeStart = $shm->get(10);
     $profiler->m_timeStop = $shm->get(11);
     $profiler->m_splitTimeTable = $shm->get(12);
     $shm->clear();
     return $profiler;
 }