Use Console Thread for Async I/O

This commit is contained in:
Shoghi Cervantes Pueyo 2012-12-29 19:10:04 +01:00
parent b3cc13d4f2
commit 302c865f4e
6 changed files with 56 additions and 64 deletions

View File

@ -26,21 +26,26 @@ the Free Software Foundation, either version 3 of the License, or
*/
class ConsoleAPI{
private $input, $server, $event;
private $loop, $server, $event;
function __construct(PocketMinecraftServer $server){
$this->help = array();
$this->server = $server;
$this->input = fopen(FILE_PATH."logs/console.in", "w+b");
$this->last = microtime(true);
}
public function init(){
$this->event = $this->server->event("server.tick", array($this, "handle"));
$this->loop = new ConsoleLoop;
$this->loop->start();
}
function __destroy(){
function __destruct(){
$this->server->deleteEvent($this->event);
fclose($this->input);
$this->loop->stop = true;
$this->loop->notify();
$this->loop->join();
unset($this->loop);
gc_collect_cycles();
}
public function defaultCommands($cmd, $params){
@ -74,7 +79,8 @@ class ConsoleAPI{
$this->server->api->setProperty("last-update", time());
break;
case "stop":
console("[INFO] Stopping the server...");
$this->loop->stop = true;
console("[INFO] Stopping the server...");
$this->server->close();
break;
/*case "restart":
@ -229,22 +235,34 @@ class ConsoleAPI{
}
public function handle($time){
while(($line = fgets($this->input)) !== false){
$line = trim($line);
if($line === ""){
continue;
}
$params = explode(" ", $line);
$cmd = strtolower(array_shift($params));
console("[INFO] Issued server command: /$cmd ".implode(" ", $params));
if(isset($this->help[$cmd]) and is_callable($this->help[$cmd][1])){
call_user_func($this->help[$cmd][1], $cmd, $params);
}elseif($this->server->trigger("api.console.command", array("cmd" => $cmd, "params" => $params)) !== false){
$this->defaultCommands($cmd, $params);
if($this->loop->line !== false){
$line = trim($this->loop->line);
$this->loop->line = false;
if($line !== ""){
$params = explode(" ", $line);
$cmd = strtolower(array_shift($params));
console("[INFO] Issued server command: /$cmd ".implode(" ", $params));
if(isset($this->help[$cmd]) and is_callable($this->help[$cmd][1])){
call_user_func($this->help[$cmd][1], $cmd, $params);
}elseif($this->server->trigger("api.console.command", array("cmd" => $cmd, "params" => $params)) !== false){
$this->defaultCommands($cmd, $params);
}
}
}else{
$this->loop->notify();
}
ftruncate($this->input, 0);
fseek($this->input, 0);
}
}
class ConsoleLoop extends Thread{
var $line = false, $stop = false;
public function run(){
$fp = fopen("php://stdin", "r");
while($this->stop === false and ($line = fgets($fp)) !== false){
$this->line = $line;
$this->wait();
$this->line = false;
}
}
}

View File

@ -36,7 +36,6 @@ class ServerAPI extends stdClass{ //Yay! I can add anything to this class in run
@mkdir(FILE_PATH."worlds/", 0777);
@mkdir(FILE_PATH."plugins/", 0777);
file_put_contents(FILE_PATH."logs/packets.log", "");
file_put_contents(FILE_PATH."logs/console.in", "");
if(!file_exists(FILE_PATH."logs/test.bin.log") or md5_file(FILE_PATH."logs/test.bin.log") !== TEST_MD5){
console("[NOTICE] Executing integrity tests...");
console("[INFO] OS: ".PHP_OS.", ".Utils::getOS());
@ -187,6 +186,16 @@ class ServerAPI extends stdClass{ //Yay! I can add anything to this class in run
$this->server->loadEntities();
}
public function __destruct(){
foreach($this->apiList as $ob){
if(is_callable($ob, "__destruct")){
$ob->__destruct();
unset($this->apiList[$ob]);
}
}
}
private function loadProperties(){
if(isset($this->config["memory-limit"])){
@ini_set("memory_limit", $this->config["memory-limit"]);
@ -276,6 +285,7 @@ class ServerAPI extends stdClass{ //Yay! I can add anything to this class in run
public function start(){
$this->server->start();
unregister_tick_function(array($this->server, "tick"));
$this->__destruct();
unset($this->server);
return $this->restart;
}

View File

@ -29,7 +29,7 @@ class Async extends Thread {
/**
* Provide a passthrough to call_user_func_array
**/
public function __construct($method, $params){
public function __construct($method, $params = array()){
$this->method = $method;
$this->params = $params;
$this->result = null;
@ -40,15 +40,17 @@ class Async extends Thread {
* The smallest thread in the world
**/
public function run(){
if (($this->result=call_user_func_array($this->method, $this->params))) {
if(($this->result=call_user_func_array($this->method, $this->params))){
return true;
} else return false;
}else{
return false;
}
}
/**
* Static method to create your threads from functions ...
**/
public static function call($method, $params){
public static function call($method, $params = array()){
$thread = new Async($method, $params);
if($thread->start()){
return $thread;

View File

@ -1,35 +0,0 @@
<?php
/*
-
/ \
/ \
/ PocketMine \
/ MP \
|\ @shoghicp /|
|. \ / .|
| .. \ / .. |
| .. | .. |
| .. | .. |
\ | /
\ | /
\ | /
\ | /
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
*/
$fp = fopen(dirname(__FILE__)."/../../logs/console.in","wb");
while(true){
$l = fgets(STDIN);
fwrite($fp, $l);
if(strtolower(trim($l)) === "stop" and isset($argv[1]) and trim($argv[1]) == "1"){
die();
}
}

View File

@ -26,7 +26,5 @@ if not "%PHPOUTPUT%"=="1" (
echo [ERROR] Couldn't find PHP binary in PATH.
ping 127.0.0.1 -n 3 -w 1000>nul
) else (
START /B CMD /C CALL php PocketMine-MP.php
START /B /WAIT php src/common/input.php 1
ping 127.0.0.1 -n 5 -w 1000>nul
START /B /WAIT php PocketMine-MP.php
)

View File

@ -1,3 +1,2 @@
#!/bin/bash
php PocketMine-MP.php &
cat > logs/console.in
php PocketMine-MP.php