Skip to content

Commit

Permalink
Solve #2659, add task_use_object, add task flags constants
Browse files Browse the repository at this point in the history
  • Loading branch information
twose committed Jul 5, 2019
1 parent 7d1810c commit aa01317
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 55 deletions.
4 changes: 4 additions & 0 deletions include/server.h
Expand Up @@ -434,6 +434,10 @@ struct _swServer
* asynchronous reloading
*/
uint32_t reload_async :1;
/**
* use task object
*/
uint32_t task_use_object :1;
/**
* enable coroutine in task worker
*/
Expand Down
107 changes: 52 additions & 55 deletions swoole_server.cc
Expand Up @@ -565,6 +565,15 @@ void swoole_server_init(int module_number)
SW_REGISTER_LONG_CONSTANT("SWOOLE_DISPATCH_RESULT_DISCARD_PACKET", SW_DISPATCH_RESULT_DISCARD_PACKET);
SW_REGISTER_LONG_CONSTANT("SWOOLE_DISPATCH_RESULT_CLOSE_CONNECTION", SW_DISPATCH_RESULT_CLOSE_CONNECTION);
SW_REGISTER_LONG_CONSTANT("SWOOLE_DISPATCH_RESULT_USERFUNC_FALLBACK", SW_DISPATCH_RESULT_USERFUNC_FALLBACK);

SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_TMPFILE", SW_TASK_TMPFILE);
SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_SERIALIZE", SW_TASK_SERIALIZE);
SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_NONBLOCK", SW_TASK_NONBLOCK);
SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_CALLBACK", SW_TASK_CALLBACK);
SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_WAITALL", SW_TASK_WAITALL);
SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_COROUTINE", SW_TASK_COROUTINE);
SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_PEEK", SW_TASK_PEEK);
SW_REGISTER_LONG_CONSTANT("SWOOLE_TASK_NOREPLY", SW_TASK_NOREPLY);
}

zend_fcall_info_cache* php_swoole_server_get_fci_cache(swServer *serv, int server_fd, int event_type)
Expand Down Expand Up @@ -1107,14 +1116,7 @@ void php_swoole_server_register_callbacks(swServer *serv)
*/
if (server_callbacks[SW_SERVER_CB_onTask] != NULL)
{
if (serv->task_enable_coroutine)
{
serv->onTask = php_swoole_onTaskCo;
}
else
{
serv->onTask = php_swoole_onTask;
}
serv->onTask = php_swoole_onTask;
serv->onFinish = php_swoole_onFinish;
}
if (server_callbacks[SW_SERVER_CB_onWorkerError] != NULL)
Expand Down Expand Up @@ -1277,31 +1279,60 @@ int php_swoole_onPacket(swServer *serv, swEventData *req)
return SW_OK;
}

static sw_inline void php_swoole_create_task_object(zval *ztask, swServer *serv, swEventData *req, zval *zdata)
{
object_init_ex(ztask, swoole_server_task_ce);
swoole_set_object(ztask, serv);

swDataHead *info = (swDataHead *) swoole_get_property(ztask, 0);
*info = req->info;

zend_update_property_long(swoole_server_task_ce, ztask, ZEND_STRL("worker_id"), (zend_long) req->info.reactor_id);
zend_update_property_long(swoole_server_task_ce, ztask, ZEND_STRL("id"), (zend_long) req->info.fd);
zend_update_property(swoole_server_task_ce, ztask, ZEND_STRL("data"), zdata);
zend_update_property_long(swoole_server_task_ce, ztask, ZEND_STRL("flags"), (zend_long) swTask_type(req));
}

static int php_swoole_onTask(swServer *serv, swEventData *req)
{
sw_atomic_fetch_sub(&serv->stats->tasking_num, 1);

zval *zserv = (zval *) serv->ptr2;
zval *zdata = php_swoole_task_unpack(req);

if (zdata == NULL)
{
return SW_ERR;
}
sw_atomic_fetch_sub(&serv->stats->tasking_num, 1);

zval args[4];
zval retval;
uint32_t argc;
zval argv[4];

args[0] = *zserv;
ZVAL_LONG(&args[1], (zend_long) req->info.fd);
ZVAL_LONG(&args[2], (zend_long) req->info.reactor_id);
args[3] = *zdata;

if (serv->task_enable_coroutine || serv->task_use_object)
{
argc = 2;
argv[0] = *zserv;
php_swoole_create_task_object(&argv[1], serv, req, zdata);
}
else
{
argc = 4;
argv[0] = *zserv;
ZVAL_LONG(&argv[1], (zend_long) req->info.fd);
ZVAL_LONG(&argv[2], (zend_long) req->info.reactor_id);
argv[3] = *zdata;
}

if (UNEXPECTED(!zend::function::call(server_callbacks[SW_SERVER_CB_onTask], 4, args, &retval, false)))
if (UNEXPECTED(!zend::function::call(server_callbacks[SW_SERVER_CB_onTask], argc, argv, &retval, serv->task_enable_coroutine)))
{
php_swoole_error(E_WARNING, "%s->onTask handler error", SW_Z_OBJCE_NAME_VAL_P(zserv));
}

if (argc == 2)
{
zval_ptr_dtor(&argv[1]);
}
sw_zval_free(zdata);

if (!ZVAL_IS_NULL(&retval))
Expand All @@ -1313,45 +1344,6 @@ static int php_swoole_onTask(swServer *serv, swEventData *req)
return SW_OK;
}

static int php_swoole_onTaskCo(swServer *serv, swEventData *req)
{
zval *zserv = (zval *) serv->ptr2;

sw_atomic_fetch_sub(&serv->stats->tasking_num, 1);

zval *zdata = php_swoole_task_unpack(req);
if (zdata == NULL)
{
return SW_ERR;
}

zval ztask;
object_init_ex(&ztask, swoole_server_task_ce);
swoole_set_object(&ztask, serv);

swDataHead *info = (swDataHead *) swoole_get_property(&ztask, 0);
*info = req->info;

zend_update_property_long(swoole_server_task_ce, &ztask, ZEND_STRL("worker_id"), (long) req->info.reactor_id);
zend_update_property_long(swoole_server_task_ce, &ztask, ZEND_STRL("id"), (long) req->info.fd);
zend_update_property(swoole_server_task_ce, &ztask, ZEND_STRL("data"), zdata);
zend_update_property_long(swoole_server_task_ce, &ztask, ZEND_STRL("flags"), (long) swTask_type(req));

zval args[2];
args[0] = *zserv;
args[1] = ztask;

if (UNEXPECTED(PHPCoroutine::create(server_callbacks[SW_SERVER_CB_onTask], 2, args) < 0))
{
php_swoole_error(E_WARNING, "%s->onTaskCo handler error", ZSTR_VAL(swoole_server_ce->name));
}

zval_ptr_dtor(&ztask);
sw_zval_free(zdata);

return SW_OK;
}

static int php_swoole_onFinish(swServer *serv, swEventData *req)
{
zval *zserv = (zval *) serv->ptr2;
Expand Down Expand Up @@ -2257,6 +2249,11 @@ static PHP_METHOD(swoole_server, set)
{
serv->enable_delay_receive = zval_is_true(v);
}
//task use object
if (php_swoole_array_get_value(vht, "task_use_object", v))
{
serv->task_use_object = zval_is_true(v);
}
//task coroutine
if (php_swoole_array_get_value(vht, "task_enable_coroutine", v))
{
Expand Down
40 changes: 40 additions & 0 deletions tests/swoole_http_server/task_use_object.phpt
@@ -0,0 +1,40 @@
--TEST--
swoole_http_server: bug Github#2368
--SKIPIF--
<?php
require __DIR__ . '/../include/skipif.inc'; ?>
--FILE--
<?php
require __DIR__ . '/../include/bootstrap.php';
$server = new Swoole\Http\Server('127.0.0.1', get_one_free_port());
$server->set([
'log_file' => '/dev/null',
'task_worker_num' => 1,
'task_use_object' => true
]);
$server->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) use ($server) {
$response->end("Hello Swoole\n");
});
$server->on('managerStart', function (Swoole\Http\Server $server) {
$server->task('');
});
$server->on('task', function ($_, Swoole\Server\Task $task) use ($server) {
var_dump(func_num_args());
var_dump(func_get_args()[1]);
Assert::eq($task->flags & SWOOLE_TASK_NOREPLY, SWOOLE_TASK_NOREPLY);
$server->shutdown();
});
$server->start();
?>
--EXPECTF--
int(2)
object(Swoole\Server\Task)#%d (%d) {
["data"]=>
string(0) ""
["id"]=>
int(0)
["worker_id"]=>
int(0)
["flags"]=>
int(%d)
}

0 comments on commit aa01317

Please sign in to comment.