mainPath = \pocketmine\PATH; } /** * @return void */ public function shutdownHandler(){ if($this->cleanShutdown !== true && $this->crashInfo === null){ $error = error_get_last(); if($error !== null){ $this->logger->emergency("Fatal error: " . $error["message"] . " in " . $error["file"] . " on line " . $error["line"]); $this->setCrashInfo(RakLibThreadCrashInfo::fromLastErrorInfo($error)); }else{ $this->logger->emergency("RakLib shutdown unexpectedly"); } } } public function getCrashInfo() : ?RakLibThreadCrashInfo{ return $this->crashInfo; } private function setCrashInfo(RakLibThreadCrashInfo $info) : void{ $this->synchronized(function(RakLibThreadCrashInfo $info) : void{ $this->crashInfo = $info; $this->notify(); }, $info); } public function startAndWait(int $options = PTHREADS_INHERIT_NONE) : void{ $this->start($options); $this->synchronized(function() : void{ while(!$this->ready && $this->crashInfo === null){ $this->wait(); } $crashInfo = $this->crashInfo; if($crashInfo !== null){ if($crashInfo->getClass() === SocketException::class){ throw new SocketException($crashInfo->getMessage()); } throw new \RuntimeException("RakLib failed to start: " . $crashInfo->makePrettyMessage()); } }); } protected function onRun() : void{ try{ gc_enable(); ini_set("display_errors", '1'); ini_set("display_startup_errors", '1'); register_shutdown_function([$this, "shutdownHandler"]); try{ $socket = new Socket($this->address); }catch(SocketException $e){ $this->setCrashInfo(RakLibThreadCrashInfo::fromThrowable($e)); return; } $manager = new Server( $this->serverId, $this->logger, $socket, $this->maxMtuSize, new SimpleProtocolAcceptor($this->protocolVersion), new UserToRakLibThreadMessageReceiver(new PthreadsChannelReader($this->mainToThreadBuffer)), new RakLibToUserThreadMessageSender(new SnoozeAwarePthreadsChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), new ExceptionTraceCleaner($this->mainPath) ); $this->synchronized(function() : void{ $this->ready = true; $this->notify(); }); while(!$this->isKilled){ $manager->tickProcessor(); } $manager->waitShutdown(); $this->cleanShutdown = true; }catch(\Throwable $e){ $this->setCrashInfo(RakLibThreadCrashInfo::fromThrowable($e)); $this->logger->logException($e); } } public function getThreadName() : string{ return "RakLib"; } }