mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-03 18:42:37 +00:00
pmmpthread support
This commit is contained in:
parent
8454076235
commit
e0630fbb25
10
.github/workflows/main.yml
vendored
10
.github/workflows/main.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Build and prepare PHP cache
|
||||
uses: pmmp/setup-php-action@c7fb29d83535320922068087c7285bdedbbfa3c2
|
||||
uses: pmmp/setup-php-action@fa2accea978a84097cf40ecc7d46b2d71f258bd5
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -38,7 +38,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@c7fb29d83535320922068087c7285bdedbbfa3c2
|
||||
uses: pmmp/setup-php-action@fa2accea978a84097cf40ecc7d46b2d71f258bd5
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -77,7 +77,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@c7fb29d83535320922068087c7285bdedbbfa3c2
|
||||
uses: pmmp/setup-php-action@fa2accea978a84097cf40ecc7d46b2d71f258bd5
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -118,7 +118,7 @@ jobs:
|
||||
submodules: true
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@c7fb29d83535320922068087c7285bdedbbfa3c2
|
||||
uses: pmmp/setup-php-action@fa2accea978a84097cf40ecc7d46b2d71f258bd5
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -157,7 +157,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@c7fb29d83535320922068087c7285bdedbbfa3c2
|
||||
uses: pmmp/setup-php-action@fa2accea978a84097cf40ecc7d46b2d71f258bd5
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
|
@ -22,7 +22,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": "^5.1",
|
||||
"ext-pmmpthread": "^6.0",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
@ -40,17 +40,17 @@
|
||||
"pocketmine/bedrock-protocol": "~21.0.0+bedrock-1.19.80",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/classloader": "^0.3.0",
|
||||
"pocketmine/classloader": "dev-stable",
|
||||
"pocketmine/color": "^0.3.0",
|
||||
"pocketmine/errorhandler": "^0.6.0",
|
||||
"pocketmine/locale-data": "~2.19.0",
|
||||
"pocketmine/log": "^0.4.0",
|
||||
"pocketmine/log-pthreads": "^0.5.0",
|
||||
"pocketmine/log-pthreads": "dev-stable",
|
||||
"pocketmine/math": "^0.4.0",
|
||||
"pocketmine/nbt": "^0.3.2",
|
||||
"pocketmine/raklib": "^0.15.0",
|
||||
"pocketmine/raklib-ipc": "^0.2.0",
|
||||
"pocketmine/snooze": "^0.4.0",
|
||||
"pocketmine/snooze": "dev-master",
|
||||
"ramsey/uuid": "^4.1",
|
||||
"symfony/filesystem": "^5.4"
|
||||
},
|
||||
|
79
composer.lock
generated
79
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "8c09886bd34e74a61c3ea1ee2be3b2e9",
|
||||
"content-hash": "507c2a45350440a7717ed089190fe4f0",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -466,32 +466,33 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/classloader",
|
||||
"version": "0.3.0",
|
||||
"version": "dev-stable",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/ClassLoader.git",
|
||||
"reference": "407caf521186ec1f03024f39031cc681ad491026"
|
||||
"reference": "e15c9b4d310581d2d2c9bf2794869cb940e011e1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/407caf521186ec1f03024f39031cc681ad491026",
|
||||
"reference": "407caf521186ec1f03024f39031cc681ad491026",
|
||||
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/e15c9b4d310581d2d2c9bf2794869cb940e011e1",
|
||||
"reference": "e15c9b4d310581d2d2c9bf2794869cb940e011e1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "^5.0",
|
||||
"ext-pmmpthread": "^6.0",
|
||||
"ext-reflection": "*",
|
||||
"php": "^8.0"
|
||||
"php": "^8.1"
|
||||
},
|
||||
"conflict": {
|
||||
"pocketmine/spl": "<0.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "1.9.4",
|
||||
"phpstan/phpstan": "1.10.15",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
@ -505,9 +506,9 @@
|
||||
"description": "Ad-hoc autoloading components used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/ClassLoader/issues",
|
||||
"source": "https://github.com/pmmp/ClassLoader/tree/0.3.0"
|
||||
"source": "https://github.com/pmmp/ClassLoader/tree/stable"
|
||||
},
|
||||
"time": "2023-01-23T19:46:53+00:00"
|
||||
"time": "2023-05-19T23:39:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/color",
|
||||
@ -652,21 +653,21 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log-pthreads",
|
||||
"version": "0.5.0",
|
||||
"version": "dev-stable",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/LogPthreads.git",
|
||||
"reference": "0ecfea6dcfc9a9f5c86e126ac1661732de5c5666"
|
||||
"reference": "bb3b5395042d12ec0d7ad5c855fd86eaf12869d3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/0ecfea6dcfc9a9f5c86e126ac1661732de5c5666",
|
||||
"reference": "0ecfea6dcfc9a9f5c86e126ac1661732de5c5666",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/bb3b5395042d12ec0d7ad5c855fd86eaf12869d3",
|
||||
"reference": "bb3b5395042d12ec0d7ad5c855fd86eaf12869d3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "^5.0",
|
||||
"php": "^8.0",
|
||||
"ext-pmmpthread": "^6.0",
|
||||
"php": "^8.1",
|
||||
"pocketmine/log": "^0.4.0"
|
||||
},
|
||||
"conflict": {
|
||||
@ -674,9 +675,10 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "1.8.11",
|
||||
"phpstan/phpstan": "1.10.3",
|
||||
"phpstan/phpstan-strict-rules": "^1.0"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
@ -690,9 +692,9 @@
|
||||
"description": "Logging components specialized for pthreads used by PocketMine-MP and related projects",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/LogPthreads/issues",
|
||||
"source": "https://github.com/pmmp/LogPthreads/tree/0.5.0"
|
||||
"source": "https://github.com/pmmp/LogPthreads/tree/stable"
|
||||
},
|
||||
"time": "2023-01-23T19:52:12+00:00"
|
||||
"time": "2023-05-19T23:38:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/math",
|
||||
@ -863,27 +865,28 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/snooze",
|
||||
"version": "0.4.0",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Snooze.git",
|
||||
"reference": "6b1d6cc645d674590ff9be2438ac00032f9ee292"
|
||||
"reference": "3207a201cbb10eebb4a96749678f7adef216bb71"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/6b1d6cc645d674590ff9be2438ac00032f9ee292",
|
||||
"reference": "6b1d6cc645d674590ff9be2438ac00032f9ee292",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/3207a201cbb10eebb4a96749678f7adef216bb71",
|
||||
"reference": "3207a201cbb10eebb4a96749678f7adef216bb71",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "^5.0",
|
||||
"php-64bit": "^8.0"
|
||||
"ext-pmmpthread": "^6.0",
|
||||
"php-64bit": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "1.9.14",
|
||||
"phpstan/phpstan": "1.10.3",
|
||||
"phpstan/phpstan-strict-rules": "^1.0"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@ -897,9 +900,9 @@
|
||||
"description": "Thread notification management library for code using the pthreads extension",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Snooze/issues",
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.4.0"
|
||||
"source": "https://github.com/pmmp/Snooze/tree/master"
|
||||
},
|
||||
"time": "2023-01-23T19:43:19+00:00"
|
||||
"time": "2023-05-19T23:38:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/collection",
|
||||
@ -1527,16 +1530,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.15.4",
|
||||
"version": "v4.15.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290"
|
||||
"reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
|
||||
"reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e",
|
||||
"reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1577,9 +1580,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5"
|
||||
},
|
||||
"time": "2023-03-05T19:49:14+00:00"
|
||||
"time": "2023-05-19T20:20:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@ -3293,7 +3296,11 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"pocketmine/classloader": 20,
|
||||
"pocketmine/log-pthreads": 20,
|
||||
"pocketmine/snooze": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
@ -3314,7 +3321,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": "^5.1",
|
||||
"ext-pmmpthread": "^6.0",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
|
@ -44,7 +44,7 @@ parameters:
|
||||
- tests/phpstan/stubs/JsonMapper.stub
|
||||
- tests/phpstan/stubs/leveldb.stub
|
||||
- tests/phpstan/stubs/phpasn1.stub
|
||||
- tests/phpstan/stubs/pthreads.stub
|
||||
- tests/phpstan/stubs/pmmpthread.stub
|
||||
reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings
|
||||
staticReflectionClassNamePatterns:
|
||||
- "#^COM$#"
|
||||
|
@ -338,7 +338,7 @@ JIT_WARNING
|
||||
$logger->info("Stopping other threads");
|
||||
|
||||
$killer = new ServerKiller(8);
|
||||
$killer->start(PTHREADS_INHERIT_NONE);
|
||||
$killer->start();
|
||||
usleep(10000); //Fixes ServerKiller not being able to start on single-core machines
|
||||
|
||||
if(ThreadManager::getInstance()->stopAll() > 0){
|
||||
|
@ -417,7 +417,7 @@ class Server{
|
||||
return $this->autoloader;
|
||||
}
|
||||
|
||||
public function getLogger() : \AttachableThreadedLogger{
|
||||
public function getLogger() : \AttachableThreadSafeLogger{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
@ -760,7 +760,7 @@ class Server{
|
||||
|
||||
public function __construct(
|
||||
private \DynamicClassLoader $autoloader,
|
||||
private \AttachableThreadedLogger $logger,
|
||||
private \AttachableThreadSafeLogger $logger,
|
||||
string $dataPath,
|
||||
string $pluginPath
|
||||
){
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\console;
|
||||
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use pocketmine\utils\Process;
|
||||
use function cli_set_process_title;
|
||||
use function count;
|
||||
@ -30,7 +32,6 @@ use function dirname;
|
||||
use function feof;
|
||||
use function fwrite;
|
||||
use function stream_socket_client;
|
||||
use const PTHREADS_INHERIT_NONE;
|
||||
|
||||
require dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
|
||||
@ -46,14 +47,14 @@ if($socket === false){
|
||||
throw new \RuntimeException("Failed to connect to server process ($errCode): $errMessage");
|
||||
}
|
||||
|
||||
/** @phpstan-var \ThreadedArray<int, string> $channel */
|
||||
$channel = new \ThreadedArray();
|
||||
$thread = new class($channel) extends \Thread{
|
||||
/** @phpstan-var ThreadSafeArray<int, string> $channel */
|
||||
$channel = new ThreadSafeArray();
|
||||
$thread = new class($channel) extends NativeThread{
|
||||
/**
|
||||
* @phpstan-param \ThreadedArray<int, string> $channel
|
||||
* @phpstan-param ThreadSafeArray<int, string> $channel
|
||||
*/
|
||||
public function __construct(
|
||||
private \ThreadedArray $channel,
|
||||
private ThreadSafeArray $channel,
|
||||
){}
|
||||
|
||||
public function run() : void{
|
||||
@ -73,7 +74,7 @@ $thread = new class($channel) extends \Thread{
|
||||
}
|
||||
};
|
||||
|
||||
$thread->start(PTHREADS_INHERIT_NONE);
|
||||
$thread->start(NativeThread::INHERIT_NONE);
|
||||
while(!feof($socket)){
|
||||
$line = $channel->synchronized(function() use ($channel) : ?string{
|
||||
if(count($channel) === 0){
|
||||
|
@ -23,13 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\raklib;
|
||||
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use raklib\server\ipc\InterThreadChannelReader;
|
||||
|
||||
final class PthreadsChannelReader implements InterThreadChannelReader{
|
||||
/**
|
||||
* @phpstan-param \ThreadedArray<int, string> $buffer
|
||||
* @phpstan-param ThreadSafeArray<int, string> $buffer
|
||||
*/
|
||||
public function __construct(private \ThreadedArray $buffer){}
|
||||
public function __construct(private ThreadSafeArray $buffer){}
|
||||
|
||||
public function read() : ?string{
|
||||
return $this->buffer->shift();
|
||||
|
@ -23,13 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\raklib;
|
||||
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use raklib\server\ipc\InterThreadChannelWriter;
|
||||
|
||||
final class PthreadsChannelWriter implements InterThreadChannelWriter{
|
||||
/**
|
||||
* @phpstan-param \ThreadedArray<int, string> $buffer
|
||||
* @phpstan-param ThreadSafeArray<int, string> $buffer
|
||||
*/
|
||||
public function __construct(private \ThreadedArray $buffer){}
|
||||
public function __construct(private ThreadSafeArray $buffer){}
|
||||
|
||||
public function write(string $str) : void{
|
||||
$this->buffer[] = $str;
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\raklib;
|
||||
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use pocketmine\lang\KnownTranslationFactory;
|
||||
use pocketmine\network\AdvancedNetworkInterface;
|
||||
use pocketmine\network\mcpe\compression\ZlibCompressor;
|
||||
@ -105,10 +106,10 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
||||
|
||||
$this->sleeper = new SleeperNotifier();
|
||||
|
||||
/** @phpstan-var \ThreadedArray<int, string> $mainToThreadBuffer */
|
||||
$mainToThreadBuffer = new \ThreadedArray();
|
||||
/** @phpstan-var \ThreadedArray<int, string> $threadToMainBuffer */
|
||||
$threadToMainBuffer = new \ThreadedArray();
|
||||
/** @phpstan-var ThreadSafeArray<int, string> $mainToThreadBuffer */
|
||||
$mainToThreadBuffer = new ThreadSafeArray();
|
||||
/** @phpstan-var ThreadSafeArray<int, string> $threadToMainBuffer */
|
||||
$threadToMainBuffer = new ThreadSafeArray();
|
||||
|
||||
$this->rakLib = new RakLibServer(
|
||||
$this->server->getLogger(),
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\raklib;
|
||||
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use pocketmine\snooze\SleeperNotifier;
|
||||
use pocketmine\thread\NonThreadSafeValue;
|
||||
use pocketmine\thread\Thread;
|
||||
@ -38,7 +40,6 @@ use function error_get_last;
|
||||
use function gc_enable;
|
||||
use function ini_set;
|
||||
use function register_shutdown_function;
|
||||
use const PTHREADS_INHERIT_NONE;
|
||||
|
||||
class RakLibServer extends Thread{
|
||||
protected bool $cleanShutdown = false;
|
||||
@ -50,13 +51,13 @@ class RakLibServer extends Thread{
|
||||
protected NonThreadSafeValue $address;
|
||||
|
||||
/**
|
||||
* @phpstan-param \ThreadedArray<int, string> $mainToThreadBuffer
|
||||
* @phpstan-param \ThreadedArray<int, string> $threadToMainBuffer
|
||||
* @phpstan-param ThreadSafeArray<int, string> $mainToThreadBuffer
|
||||
* @phpstan-param ThreadSafeArray<int, string> $threadToMainBuffer
|
||||
*/
|
||||
public function __construct(
|
||||
protected \ThreadedLogger $logger,
|
||||
protected \ThreadedArray $mainToThreadBuffer,
|
||||
protected \ThreadedArray $threadToMainBuffer,
|
||||
protected \ThreadSafeLogger $logger,
|
||||
protected ThreadSafeArray $mainToThreadBuffer,
|
||||
protected ThreadSafeArray $threadToMainBuffer,
|
||||
InternetAddress $address,
|
||||
protected int $serverId,
|
||||
protected int $maxMtuSize,
|
||||
@ -88,13 +89,13 @@ class RakLibServer extends Thread{
|
||||
}
|
||||
|
||||
private function setCrashInfo(RakLibThreadCrashInfo $info) : void{
|
||||
$this->synchronized(function(RakLibThreadCrashInfo $info) : void{
|
||||
$this->synchronized(function() use ($info) : void{
|
||||
$this->crashInfo = new NonThreadSafeValue($info);
|
||||
$this->notify();
|
||||
}, $info);
|
||||
});
|
||||
}
|
||||
|
||||
public function startAndWait(int $options = PTHREADS_INHERIT_NONE) : void{
|
||||
public function startAndWait(int $options = NativeThread::INHERIT_NONE) : void{
|
||||
$this->start($options);
|
||||
$this->synchronized(function() : void{
|
||||
while(!$this->ready && $this->crashInfo === null){
|
||||
|
@ -23,15 +23,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\raklib;
|
||||
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use pocketmine\snooze\SleeperNotifier;
|
||||
use raklib\server\ipc\InterThreadChannelWriter;
|
||||
|
||||
final class SnoozeAwarePthreadsChannelWriter implements InterThreadChannelWriter{
|
||||
/**
|
||||
* @phpstan-param \ThreadedArray<int, string> $buffer
|
||||
* @phpstan-param ThreadSafeArray<int, string> $buffer
|
||||
*/
|
||||
public function __construct(
|
||||
private \ThreadedArray $buffer,
|
||||
private ThreadSafeArray $buffer,
|
||||
private SleeperNotifier $notifier
|
||||
){}
|
||||
|
||||
|
@ -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")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -23,16 +23,17 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\thread;
|
||||
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use pocketmine\errorhandler\ErrorToExceptionHandler;
|
||||
use pocketmine\Server;
|
||||
use function error_reporting;
|
||||
|
||||
trait CommonThreadPartsTrait{
|
||||
/**
|
||||
* @var \ThreadedArray|\ClassLoader[]|null
|
||||
* @phpstan-var \ThreadedArray<int, \ClassLoader>|null
|
||||
* @var ThreadSafeArray|\ClassLoader[]|null
|
||||
* @phpstan-var ThreadSafeArray<int, \ClassLoader>|null
|
||||
*/
|
||||
private ?\ThreadedArray $classLoaders = null;
|
||||
private ?ThreadSafeArray $classLoaders = null;
|
||||
protected ?string $composerAutoloaderPath = null;
|
||||
|
||||
protected bool $isKilled = false;
|
||||
@ -55,14 +56,15 @@ trait CommonThreadPartsTrait{
|
||||
}
|
||||
|
||||
if($this->classLoaders === null){
|
||||
$this->classLoaders = new \ThreadedArray();
|
||||
$loaders = $this->classLoaders = new ThreadSafeArray();
|
||||
}else{
|
||||
$loaders = $this->classLoaders;
|
||||
foreach($this->classLoaders as $k => $autoloader){
|
||||
unset($this->classLoaders[$k]);
|
||||
}
|
||||
}
|
||||
foreach($autoloaders as $autoloader){
|
||||
$this->classLoaders[] = $autoloader;
|
||||
$loaders[] = $autoloader;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\thread;
|
||||
|
||||
use pmmp\thread\ThreadSafe;
|
||||
use function get_debug_type;
|
||||
use function igbinary_serialize;
|
||||
use function igbinary_unserialize;
|
||||
@ -34,7 +35,7 @@ use function igbinary_unserialize;
|
||||
*
|
||||
* @phpstan-template TValue
|
||||
*/
|
||||
final class NonThreadSafeValue extends \ThreadedBase{
|
||||
final class NonThreadSafeValue extends ThreadSafe{
|
||||
private string $variable;
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\thread;
|
||||
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pocketmine\scheduler\AsyncTask;
|
||||
use const PTHREADS_INHERIT_NONE;
|
||||
|
||||
/**
|
||||
* Specialized Thread class aimed at PocketMine-MP-related usages. It handles setting up autoloading and error handling.
|
||||
@ -35,10 +35,10 @@ use const PTHREADS_INHERIT_NONE;
|
||||
* CPU.
|
||||
* @see AsyncTask
|
||||
*/
|
||||
abstract class Thread extends \Thread{
|
||||
abstract class Thread extends NativeThread{
|
||||
use CommonThreadPartsTrait;
|
||||
|
||||
public function start(int $options = PTHREADS_INHERIT_NONE) : bool{
|
||||
public function start(int $options = NativeThread::INHERIT_NONE) : bool{
|
||||
//this is intentionally not traitified
|
||||
ThreadManager::getInstance()->add($this);
|
||||
|
||||
|
@ -23,9 +23,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\thread;
|
||||
|
||||
use pmmp\thread\ThreadSafe;
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use function spl_object_id;
|
||||
|
||||
class ThreadManager extends \ThreadedBase{
|
||||
class ThreadManager extends ThreadSafe{
|
||||
|
||||
private static ?self $instance = null;
|
||||
|
||||
@ -40,11 +42,11 @@ class ThreadManager extends \ThreadedBase{
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/** @phpstan-var \ThreadedArray<int, Thread|Worker> */
|
||||
private \ThreadedArray $threads;
|
||||
/** @phpstan-var ThreadSafeArray<int, Thread|Worker> */
|
||||
private ThreadSafeArray $threads;
|
||||
|
||||
private function __construct(){
|
||||
$this->threads = new \ThreadedArray();
|
||||
$this->threads = new ThreadSafeArray();
|
||||
}
|
||||
|
||||
public function add(Worker|Thread $thread) : void{
|
||||
|
@ -23,8 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\thread;
|
||||
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pmmp\thread\Worker as NativeWorker;
|
||||
use pocketmine\scheduler\AsyncTask;
|
||||
use const PTHREADS_INHERIT_NONE;
|
||||
|
||||
/**
|
||||
* Specialized Worker class for PocketMine-MP-related use cases. It handles setting up autoloading and error handling.
|
||||
@ -36,10 +37,10 @@ use const PTHREADS_INHERIT_NONE;
|
||||
* If you want to run tasks on other CPU cores, check out AsyncTask first.
|
||||
* @see AsyncTask
|
||||
*/
|
||||
abstract class Worker extends \Worker{
|
||||
abstract class Worker extends NativeWorker{
|
||||
use CommonThreadPartsTrait;
|
||||
|
||||
public function start(int $options = PTHREADS_INHERIT_NONE) : bool{
|
||||
public function start(int $options = NativeThread::INHERIT_NONE) : bool{
|
||||
//this is intentionally not traitified
|
||||
ThreadManager::getInstance()->add($this);
|
||||
|
||||
|
@ -24,14 +24,14 @@ declare(strict_types=1);
|
||||
namespace pocketmine\utils;
|
||||
|
||||
use LogLevel;
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pocketmine\thread\Thread;
|
||||
use pocketmine\thread\Worker;
|
||||
use function implode;
|
||||
use function sprintf;
|
||||
use const PHP_EOL;
|
||||
use const PTHREADS_INHERIT_NONE;
|
||||
|
||||
class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
class MainLogger extends \AttachableThreadSafeLogger implements \BufferedLogger{
|
||||
protected bool $logDebug;
|
||||
|
||||
private string $format = TextFormat::AQUA . "[%s] " . TextFormat::RESET . "%s[%s/%s]: %s" . TextFormat::RESET;
|
||||
@ -52,7 +52,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
$this->timezone = $timezone->getName();
|
||||
|
||||
$this->logWriterThread = new MainLoggerThread($logFile);
|
||||
$this->logWriterThread->start(PTHREADS_INHERIT_NONE);
|
||||
$this->logWriterThread->start(NativeThread::INHERIT_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,7 +165,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
}
|
||||
|
||||
public function shutdownLogWriterThread() : void{
|
||||
if(\Thread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
|
||||
if(NativeThread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
|
||||
$this->logWriterThread->shutdown();
|
||||
}else{
|
||||
throw new \LogicException("Only the creator thread can shutdown the logger thread");
|
||||
@ -175,7 +175,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
protected function send(string $message, string $level, string $prefix, string $color) : void{
|
||||
$time = new \DateTime('now', new \DateTimeZone($this->timezone));
|
||||
|
||||
$thread = \Thread::getCurrentThread();
|
||||
$thread = NativeThread::getCurrentThread();
|
||||
if($thread === null){
|
||||
$threadName = $this->mainThreadName . " thread";
|
||||
}elseif($thread instanceof Thread || $thread instanceof Worker){
|
||||
@ -195,7 +195,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
$this->logWriterThread->write($time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL);
|
||||
|
||||
/**
|
||||
* @var \ThreadedLoggerAttachment $attachment
|
||||
* @var \ThreadSafeLoggerAttachment $attachment
|
||||
*/
|
||||
foreach($this->attachments as $attachment){
|
||||
$attachment->log($level, $message);
|
||||
@ -208,7 +208,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
if(!$this->logWriterThread->isJoined() && \Thread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
|
||||
if(!$this->logWriterThread->isJoined() && NativeThread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
|
||||
$this->shutdownLogWriterThread();
|
||||
}
|
||||
}
|
||||
|
@ -23,22 +23,24 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
use pmmp\thread\Thread;
|
||||
use pmmp\thread\ThreadSafeArray;
|
||||
use function fclose;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function is_resource;
|
||||
use function touch;
|
||||
|
||||
final class MainLoggerThread extends \Thread{
|
||||
/** @phpstan-var \ThreadedArray<int, string> */
|
||||
private \ThreadedArray $buffer;
|
||||
final class MainLoggerThread extends Thread{
|
||||
/** @phpstan-var ThreadSafeArray<int, string> */
|
||||
private ThreadSafeArray $buffer;
|
||||
private bool $syncFlush = false;
|
||||
private bool $shutdown = false;
|
||||
|
||||
public function __construct(
|
||||
private string $logFile
|
||||
){
|
||||
$this->buffer = new \ThreadedArray();
|
||||
$this->buffer = new ThreadSafeArray();
|
||||
touch($this->logFile);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace pmmp\thread;
|
||||
|
||||
/**
|
||||
* @implements \IteratorAggregate<array-key, mixed>
|
||||
*/
|
||||
abstract class ThreadedBase implements \IteratorAggregate{
|
||||
abstract class ThreadSafe implements \IteratorAggregate{
|
||||
|
||||
/**
|
||||
* @template TReturn
|
||||
@ -17,9 +19,9 @@ abstract class ThreadedBase implements \IteratorAggregate{
|
||||
/**
|
||||
* @template TKey of array-key
|
||||
* @template TValue
|
||||
* @implements ArrayAccess<TKey, TValue>
|
||||
* @implements \ArrayAccess<TKey, TValue>
|
||||
*/
|
||||
final class ThreadedArray extends ThreadedBase implements Countable, ArrayAccess{
|
||||
final class ThreadSafeArray extends ThreadSafe implements \Countable, \ArrayAccess{
|
||||
|
||||
/**
|
||||
* @return TValue|null
|
||||
@ -30,4 +32,4 @@ final class ThreadedArray extends ThreadedBase implements Countable, ArrayAccess
|
||||
* @return TValue|null
|
||||
*/
|
||||
public function shift() : mixed{}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user