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->collectTasksFromWorker($worker);
});
$this->workers[$worker]->setClassLoader($this->classLoader);
$this->workers[$worker]->setClassLoaders([$this->classLoader]);
$this->workers[$worker]->start(self::WORKER_START_OPTIONS);
$this->taskQueues[$worker] = new \SplQueue();

View File

@ -28,46 +28,66 @@ use pocketmine\Server;
use function error_reporting;
trait CommonThreadPartsTrait{
/** @var \ClassLoader|null */
protected $classLoader;
/** @var \Threaded|\ClassLoader[]|null */
private ?\Threaded $classLoaders = null;
/** @var string|null */
protected $composerAutoloaderPath;
/** @var bool */
protected $isKilled = false;
public function getClassLoader() : ?\ClassLoader{
return $this->classLoader;
}
public function setClassLoader(?\ClassLoader $loader = null) : void{
$this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH;
if($loader === null){
$loader = Server::getInstance()->getLoader();
}
$this->classLoader = $loader;
/**
* @return \ClassLoader[]
*/
public function getClassLoaders() : ?array{
return $this->classLoaders !== null ? (array) $this->classLoaders : null;
}
/**
* 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.
* 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).
*/
public function registerClassLoader() : void{
public function registerClassLoaders() : void{
if($this->composerAutoloaderPath !== null){
require $this->composerAutoloaderPath;
}
if($this->classLoader !== null){
$this->classLoader->register(false);
$autoloaders = $this->classLoaders;
if($autoloaders !== null){
foreach($autoloaders as $autoloader){
/** @var \ClassLoader $autoloader */
$autoloader->register(false);
}
}
}
final public function run() : void{
error_reporting(-1);
$this->registerClassLoader();
$this->registerClassLoaders();
//set this after the autoloader is registered
ErrorToExceptionHandler::set();
$this->onRun();

View File

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

View File

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