Allow registering multiple ClassLoaders for a thread

This commit is contained in:
Dylan K. Taylor 2021-07-15 19:00:40 +01:00
parent ac8b13ee36
commit 5fbc7681b0
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
4 changed files with 43 additions and 23 deletions

View File

@ -147,7 +147,7 @@ class AsyncPool{
$this->eventLoop->addNotifier($notifier, function() use ($worker) : void{ $this->eventLoop->addNotifier($notifier, function() use ($worker) : void{
$this->collectTasksFromWorker($worker); $this->collectTasksFromWorker($worker);
}); });
$this->workers[$worker]->setClassLoader($this->classLoader); $this->workers[$worker]->setClassLoaders([$this->classLoader]);
$this->workers[$worker]->start(self::WORKER_START_OPTIONS); $this->workers[$worker]->start(self::WORKER_START_OPTIONS);
$this->taskQueues[$worker] = new \SplQueue(); $this->taskQueues[$worker] = new \SplQueue();

View File

@ -28,46 +28,66 @@ use pocketmine\Server;
use function error_reporting; use function error_reporting;
trait CommonThreadPartsTrait{ trait CommonThreadPartsTrait{
/** @var \ClassLoader|null */ /** @var \Threaded|\ClassLoader[]|null */
protected $classLoader; private ?\Threaded $classLoaders = null;
/** @var string|null */ /** @var string|null */
protected $composerAutoloaderPath; protected $composerAutoloaderPath;
/** @var bool */ /** @var bool */
protected $isKilled = false; protected $isKilled = false;
public function getClassLoader() : ?\ClassLoader{ /**
return $this->classLoader; * @return \ClassLoader[]
} */
public function getClassLoaders() : ?array{
public function setClassLoader(?\ClassLoader $loader = null) : void{ return $this->classLoaders !== null ? (array) $this->classLoaders : null;
$this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH;
if($loader === null){
$loader = Server::getInstance()->getLoader();
}
$this->classLoader = $loader;
} }
/** /**
* Registers the class loader for this thread. * @param \ClassLoader[] $autoloaders
*/
public function setClassLoaders(?array $autoloaders = null) : void{
$this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH;
if($autoloaders === null){
$autoloaders = [Server::getInstance()->getLoader()];
}
if($this->classLoaders === null){
$this->classLoaders = new \Threaded();
}else{
foreach($this->classLoaders as $k => $autoloader){
unset($this->classLoaders[$k]);
}
}
foreach($autoloaders as $autoloader){
$this->classLoaders[] = $autoloader;
}
}
/**
* Registers the class loaders for this thread.
* *
* WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable. * WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable.
* If you do not do this, you will not be able to use new classes that were not loaded when the thread was started * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started
* (unless you are using a custom autoloader). * (unless you are using a custom autoloader).
*/ */
public function registerClassLoader() : void{ public function registerClassLoaders() : void{
if($this->composerAutoloaderPath !== null){ if($this->composerAutoloaderPath !== null){
require $this->composerAutoloaderPath; require $this->composerAutoloaderPath;
} }
if($this->classLoader !== null){ $autoloaders = $this->classLoaders;
$this->classLoader->register(false); if($autoloaders !== null){
foreach($autoloaders as $autoloader){
/** @var \ClassLoader $autoloader */
$autoloader->register(false);
}
} }
} }
final public function run() : void{ final public function run() : void{
error_reporting(-1); error_reporting(-1);
$this->registerClassLoader(); $this->registerClassLoaders();
//set this after the autoloader is registered //set this after the autoloader is registered
ErrorToExceptionHandler::set(); ErrorToExceptionHandler::set();
$this->onRun(); $this->onRun();

View File

@ -35,8 +35,8 @@ abstract class Thread extends \Thread{
//this is intentionally not traitified //this is intentionally not traitified
ThreadManager::getInstance()->add($this); ThreadManager::getInstance()->add($this);
if($this->getClassLoader() === null){ if($this->getClassLoaders() === null){
$this->setClassLoader(); $this->setClassLoaders();
} }
return parent::start($options); return parent::start($options);
} }

View File

@ -35,8 +35,8 @@ abstract class Worker extends \Worker{
//this is intentionally not traitified //this is intentionally not traitified
ThreadManager::getInstance()->add($this); ThreadManager::getInstance()->add($this);
if($this->getClassLoader() === null){ if($this->getClassLoaders() === null){
$this->setClassLoader(); $this->setClassLoaders();
} }
return parent::start($options); return parent::start($options);
} }