mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-07 02:08:21 +00:00
pmmpthread support
This commit is contained in:
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\scheduler;
|
||||
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use pocketmine\snooze\SleeperHandler;
|
||||
use pocketmine\snooze\SleeperNotifier;
|
||||
use pocketmine\utils\Utils;
|
||||
@ -33,14 +35,13 @@ use function count;
|
||||
use function spl_object_id;
|
||||
use function time;
|
||||
use const PHP_INT_MAX;
|
||||
use const PTHREADS_INHERIT_INI;
|
||||
|
||||
/**
|
||||
* Manages general-purpose worker threads used for processing asynchronous tasks, and the tasks submitted to those
|
||||
* workers.
|
||||
*/
|
||||
class AsyncPool{
|
||||
private const WORKER_START_OPTIONS = PTHREADS_INHERIT_INI;
|
||||
private const WORKER_START_OPTIONS = NativeThread::INHERIT_INI | NativeThread::INHERIT_COMMENTS;
|
||||
|
||||
/**
|
||||
* @var \SplQueue[]|AsyncTask[][]
|
||||
@ -69,7 +70,7 @@ class AsyncPool{
|
||||
protected int $size,
|
||||
private int $workerMemoryLimit,
|
||||
private \ClassLoader $classLoader,
|
||||
private \ThreadedLogger $logger,
|
||||
private \ThreadSafeLogger $logger,
|
||||
private SleeperHandler $eventLoop
|
||||
){}
|
||||
|
||||
@ -158,7 +159,7 @@ class AsyncPool{
|
||||
throw new \InvalidArgumentException("Cannot submit the same AsyncTask instance more than once");
|
||||
}
|
||||
|
||||
$task->progressUpdates = new \ThreadedArray();
|
||||
$task->progressUpdates = new ThreadSafeArray();
|
||||
$task->setSubmitted();
|
||||
|
||||
$this->getWorker($worker)->stack($task);
|
||||
|
@ -23,7 +23,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\scheduler;
|
||||
|
||||
use pmmp\thread\Runnable;
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use pocketmine\thread\NonThreadSafeValue;
|
||||
use function assert;
|
||||
use function igbinary_serialize;
|
||||
use function igbinary_unserialize;
|
||||
use function is_null;
|
||||
@ -54,7 +58,7 @@ use function spl_object_id;
|
||||
* If you want to store non-thread-safe objects to access when the task completes, store them using
|
||||
* {@link AsyncTask::storeLocal}.
|
||||
*/
|
||||
abstract class AsyncTask extends \ThreadedRunnable{
|
||||
abstract class AsyncTask extends Runnable{
|
||||
/**
|
||||
* @var \ArrayObject|mixed[]|null object hash => mixed data
|
||||
* @phpstan-var \ArrayObject<int, array<string, mixed>>|null
|
||||
@ -63,11 +67,8 @@ abstract class AsyncTask extends \ThreadedRunnable{
|
||||
*/
|
||||
private static ?\ArrayObject $threadLocalStorage = null;
|
||||
|
||||
/** @var AsyncWorker|null $worker */
|
||||
public $worker = null;
|
||||
|
||||
/** @phpstan-var \ThreadedArray<int, string> */
|
||||
public \ThreadedArray $progressUpdates;
|
||||
/** @phpstan-var ThreadSafeArray<int, string> */
|
||||
public ThreadSafeArray $progressUpdates;
|
||||
|
||||
/** @phpstan-var NonThreadSafeValue<mixed>|string|int|bool|float|null */
|
||||
private NonThreadSafeValue|string|int|bool|null|float $result = null;
|
||||
@ -85,12 +86,15 @@ abstract class AsyncTask extends \ThreadedRunnable{
|
||||
$this->onRun();
|
||||
}catch(\Throwable $e){
|
||||
$this->crashed = true;
|
||||
$this->worker->handleException($e);
|
||||
|
||||
\GlobalLogger::get()->logException($e);
|
||||
}
|
||||
}
|
||||
|
||||
$this->finished = true;
|
||||
$this->worker->getNotifier()->wakeupSleeper();
|
||||
$worker = NativeThread::getCurrentThread();
|
||||
assert($worker instanceof AsyncWorker);
|
||||
$worker->getNotifier()->wakeupSleeper();
|
||||
}
|
||||
|
||||
public function isCrashed() : bool{
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\scheduler;
|
||||
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pocketmine\snooze\SleeperNotifier;
|
||||
use pocketmine\thread\Worker;
|
||||
use function gc_enable;
|
||||
@ -33,7 +34,7 @@ class AsyncWorker extends Worker{
|
||||
private static array $store = [];
|
||||
|
||||
public function __construct(
|
||||
private \ThreadedLogger $logger,
|
||||
private \ThreadSafeLogger $logger,
|
||||
private int $id,
|
||||
private int $memoryLimit,
|
||||
private SleeperNotifier $notifier
|
||||
@ -57,7 +58,7 @@ class AsyncWorker extends Worker{
|
||||
}
|
||||
}
|
||||
|
||||
public function getLogger() : \ThreadedLogger{
|
||||
public function getLogger() : \ThreadSafeLogger{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
@ -78,7 +79,7 @@ class AsyncWorker extends Worker{
|
||||
* want to use on this worker thread from multiple AsyncTasks.
|
||||
*/
|
||||
public function saveToThreadStore(string $identifier, mixed $value) : void{
|
||||
if(\Thread::getCurrentThread() !== $this){
|
||||
if(NativeThread::getCurrentThread() !== $this){
|
||||
throw new \LogicException("Thread-local data can only be stored in the thread context");
|
||||
}
|
||||
self::$store[$identifier] = $value;
|
||||
@ -93,7 +94,7 @@ class AsyncWorker extends Worker{
|
||||
* Objects stored in this storage may ONLY be retrieved while the task is running.
|
||||
*/
|
||||
public function getFromThreadStore(string $identifier) : mixed{
|
||||
if(\Thread::getCurrentThread() !== $this){
|
||||
if(NativeThread::getCurrentThread() !== $this){
|
||||
throw new \LogicException("Thread-local data can only be fetched in the thread context");
|
||||
}
|
||||
return self::$store[$identifier] ?? null;
|
||||
@ -103,7 +104,7 @@ class AsyncWorker extends Worker{
|
||||
* Removes previously-stored mixed data from the worker's thread-local object store.
|
||||
*/
|
||||
public function removeFromThreadStore(string $identifier) : void{
|
||||
if(\Thread::getCurrentThread() !== $this){
|
||||
if(NativeThread::getCurrentThread() !== $this){
|
||||
throw new \LogicException("Thread-local data can only be removed in the thread context");
|
||||
}
|
||||
unset(self::$store[$identifier]);
|
||||
|
@ -23,8 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\scheduler;
|
||||
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pocketmine\MemoryManager;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function assert;
|
||||
|
||||
/**
|
||||
* Task used to dump memory from AsyncWorkers
|
||||
@ -37,12 +39,14 @@ class DumpWorkerMemoryTask extends AsyncTask{
|
||||
){}
|
||||
|
||||
public function onRun() : void{
|
||||
$worker = NativeThread::getCurrentThread();
|
||||
assert($worker instanceof AsyncWorker);
|
||||
MemoryManager::dumpMemory(
|
||||
$this->worker,
|
||||
Path::join($this->outputFolder, "AsyncWorker#" . $this->worker->getAsyncWorkerId()),
|
||||
$worker,
|
||||
Path::join($this->outputFolder, "AsyncWorker#" . $worker->getAsyncWorkerId()),
|
||||
$this->maxNesting,
|
||||
$this->maxStringSize,
|
||||
new \PrefixedLogger($this->worker->getLogger(), "Memory Dump")
|
||||
new \PrefixedLogger($worker->getLogger(), "Memory Dump")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user