/** * Helper method for testing threads in asynchronous mode * * @param callable $callback * @param bool $simple More simple test * * @throws \Exception */ function processAsyncTest($callback, $simple = false) { if (!Thread::$useForks) { $this->markTestSkipped('You need LibEvent, PCNTL and POSIX support' . ' with CLI sapi to fully test Threads'); return; } if ($simple) { $ipcModes = array(Thread::$ipcDataMode => false); $socketModes = array(Socket::$useSockets); } else { $ipcModes = array(Thread::IPC_IGBINARY => 'igbinary_serialize', Thread::IPC_SERIALIZE => false); $socketModes = array(true, false); } $defSocketMode = Socket::$useSockets; foreach ($socketModes as $socketMode) { Socket::$useSockets = $socketMode; foreach ($ipcModes as $mode => $check) { if ($check && !function_exists($check)) { continue; } Thread::$ipcDataMode = $mode; try { if (false === $callback()) { break 2; } } catch (\Exception $e) { if ($base = EventBase::getMainLoop(false)) { $base->resource && $base->loopBreak(); } throw $e; } } } Socket::$useSockets = $defSocketMode; }
/** * Marks thread as waiting for job * * @param int $threadId * * @throws Exception * * @internal */ public function markThreadWorking($threadId) { if (empty($this->waitingForJob[$threadId])) { // @codeCoverageIgnoreStart // Should not be called // Break event loop to avoid freezes and other bugs $base = isset($this->threads[$threadId]) ? $this->threads[$threadId]->getEventLoop() : EventBase::getMainLoop(false); $base && $base->loopBreak(); throw new Exception("Incorrect thread for working #{$threadId}"); // @codeCoverageIgnoreEnd } unset($this->waitingForJob[$threadId]); $this->working[$threadId] = $threadId; // @codeCoverageIgnoreStart $this->debug && $this->debug("Thread #{$threadId} is marked as working"); // @codeCoverageIgnoreEnd }