From 8404ce88bd6ea2beba7057dbb583e5052b185290 Mon Sep 17 00:00:00 2001 From: SOFe Date: Sat, 12 Nov 2016 18:30:55 +0800 Subject: [PATCH] Fixed pthreads crashes with progressUpdates --- src/pocketmine/scheduler/AsyncPool.php | 7 ++----- src/pocketmine/scheduler/AsyncTask.php | 15 +++++++++++++-- src/pocketmine/scheduler/ServerScheduler.php | 1 + 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index a4bdb55d1..22433690c 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -142,11 +142,8 @@ class AsyncPool{ Timings::$schedulerAsyncTimer->startTiming(); foreach($this->tasks as $task){ - if(!$task->isGarbage() and $task->progressUpdates !== null){ - if($task->progressUpdates->count() !== 0){ - $progress = $task->progressUpdates->shift(); - $task->onProgressUpdate($this->server, $progress); - } + if(!$task->isGarbage()){ + $task->checkProgressUpdates($this->server); } if($task->isGarbage() and !$task->isRunning() and !$task->isCrashed()){ if(!$task->hasCancelledRun()){ diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 295b881b1..eeabd63d4 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -35,7 +35,7 @@ abstract class AsyncTask extends Collectable{ public $worker = null; /** @var \Threaded */ - public $progressUpdates = null; + public $progressUpdates; private $result = null; private $serialized = false; @@ -69,7 +69,6 @@ abstract class AsyncTask extends Collectable{ } public function run(){ - $this->progressUpdates = new \Threaded; // Do not move this to __construct for backwards compatibility. $this->result = null; if($this->cancelRun !== true){ @@ -182,6 +181,18 @@ abstract class AsyncTask extends Collectable{ $this->progressUpdates[] = $progress; } + /** + * @internal Only call from AsyncPool.php on the main thread + * + * @param Server $server + */ + public function checkProgressUpdates(Server $server){ + if($this->progressUpdates->count() !== 0){ + $progress = $this->progressUpdates->shift(); + $this->onProgressUpdate($server, $progress); + } + } + /** * Called from the main thread after {@link AsyncTask#publishProgress} is called. * All {@link AsyncTask#publishProgress} calls should result in {@link AsyncTask#onProgressUpdate} calls before diff --git a/src/pocketmine/scheduler/ServerScheduler.php b/src/pocketmine/scheduler/ServerScheduler.php index b25453648..76e8a5566 100644 --- a/src/pocketmine/scheduler/ServerScheduler.php +++ b/src/pocketmine/scheduler/ServerScheduler.php @@ -78,6 +78,7 @@ class ServerScheduler{ public function scheduleAsyncTask(AsyncTask $task){ $id = $this->nextId(); $task->setTaskId($id); + $task->progressUpdates = new \Threaded; $this->asyncPool->submitTask($task); }