Skip to content

Commit 6d683da

Browse files
author
ace411
committed
feat: add futureTick() function
1 parent bc5fa79 commit 6d683da

File tree

6 files changed

+121
-2
lines changed

6 files changed

+121
-2
lines changed

README.md

+46
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class Mrloop
6060
public static parseHttpResponse(string $response, int $headerlimit = 100): iterable
6161
public addTimer(float $interval, callable $callback): void
6262
public addPeriodicTimer(float $interval, callable $callback): void
63+
public futureTick(callable $callback): void
6364
public addSignal(int $signal, callable $callback): void
6465
public run(): void
6566
public stop(): void
@@ -75,6 +76,7 @@ class Mrloop
7576
- [`Mrloop::parseHttpResponse`](#mrloopparsehttpresponse)
7677
- [`Mrloop::addTimer`](#mrloopaddtimer)
7778
- [`Mrloop::addPeriodicTimer`](#mrloopaddperiodictimer)
79+
- [`Mrloop::futureTick`](#mrloopfuturetick)
7880
- [`Mrloop::addSignal`](#mrloopaddsignal)
7981
- [`Mrloop::run`](#mrlooprun)
8082
- [`Mrloop::stop`](#mrloopstop)
@@ -641,6 +643,50 @@ Tick: 4
641643
Tick: 5
642644
```
643645

646+
### `Mrloop::futureTick`
647+
648+
```php
649+
public Mrloop::futureTick(callable $callback): void
650+
```
651+
652+
Schedules the execution of a specified action for the next event loop tick.
653+
654+
**Parameter(s)**
655+
656+
- **callback** (callable) - The function in which the action to be scheduled is defined.
657+
658+
**Return value(s)**
659+
660+
The function does not return anything.
661+
662+
```php
663+
use ringphp\Mrloop;
664+
665+
$loop = Mrloop::init();
666+
$tick = 0;
667+
668+
$loop->futureTick(
669+
function () use (&$tick) {
670+
echo \sprintf("Tick: %d\n", ++$tick);
671+
},
672+
);
673+
674+
$loop->futureTick(
675+
function () use (&$tick) {
676+
echo \sprintf("Tick: %d\n", ++$tick);
677+
},
678+
);
679+
680+
$loop->run();
681+
```
682+
683+
The example above will produce output similar to that in the snippet to follow.
684+
685+
```
686+
Tick: 1
687+
Tick: 2
688+
```
689+
644690
### `Mrloop::addSignal`
645691

646692
```php

mrloop_arginfo.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ ZEND_ARG_TYPE_INFO(0, fd, IS_LONG, 0)
5555
ZEND_ARG_TYPE_INFO(0, contents, IS_STRING, 0)
5656
ZEND_END_ARG_INFO()
5757

58+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Mrloop_futureTick, 0, 0, 1)
59+
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
60+
ZEND_END_ARG_INFO()
61+
5862
ZEND_METHOD(Mrloop, init);
5963
ZEND_METHOD(Mrloop, stop);
6064
ZEND_METHOD(Mrloop, run);
@@ -67,6 +71,7 @@ ZEND_METHOD(Mrloop, addReadStream);
6771
ZEND_METHOD(Mrloop, addWriteStream);
6872
ZEND_METHOD(Mrloop, parseHttpResponse);
6973
ZEND_METHOD(Mrloop, writev);
74+
ZEND_METHOD(Mrloop, futureTick);
7075

7176
static const zend_function_entry class_Mrloop_methods[] = {
7277
PHP_ME(Mrloop, init, arginfo_class_Mrloop_init, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
@@ -81,4 +86,5 @@ static const zend_function_entry class_Mrloop_methods[] = {
8186
PHP_ME(Mrloop, addWriteStream, arginfo_class_Mrloop_addWriteStream, ZEND_ACC_PUBLIC)
8287
PHP_ME(Mrloop, parseHttpResponse, arginfo_class_Mrloop_parseHttpResponse, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
8388
PHP_ME(Mrloop, writev, arginfo_class_Mrloop_writev, ZEND_ACC_PUBLIC)
84-
PHP_FE_END};
89+
PHP_ME(Mrloop, futureTick, arginfo_class_Mrloop_futureTick, ZEND_ACC_PUBLIC)
90+
PHP_FE_END};

php_mrloop.c

+7
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ PHP_METHOD(Mrloop, writev)
9191
}
9292
/* }}} */
9393

94+
/* {{{ proto void Mrloop::futureTick( callable callback ) */
95+
PHP_METHOD(Mrloop, futureTick)
96+
{
97+
php_mrloop_add_future_tick(INTERNAL_FUNCTION_PARAM_PASSTHRU);
98+
}
99+
/* }}} */
100+
94101
/* {{{ PHP_MINIT_FUNCTION */
95102
PHP_MINIT_FUNCTION(mrloop)
96103
{

src/loop.c

+28-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static int php_mrloop_timer_cb(void *data)
102102
zval_ptr_dtor(&result);
103103
efree(cb);
104104

105-
return type == PHP_MRLOOP_TIMER ? 0 : 1;
105+
return type == PHP_MRLOOP_TIMER || type == PHP_MRLOOP_FUTURE_TICK ? 0 : 1;
106106
}
107107
static void php_mrloop_add_timer(INTERNAL_FUNCTION_PARAMETERS)
108108
{
@@ -162,6 +162,33 @@ static void php_mrloop_add_periodic_timer(INTERNAL_FUNCTION_PARAMETERS)
162162

163163
return;
164164
}
165+
static void php_mrloop_add_future_tick(INTERNAL_FUNCTION_PARAMETERS)
166+
{
167+
zval *obj;
168+
php_mrloop_cb_t *cb;
169+
php_mrloop_t *this;
170+
zend_fcall_info fci;
171+
zend_fcall_info_cache fci_cache;
172+
173+
fci = empty_fcall_info;
174+
fci_cache = empty_fcall_info_cache;
175+
obj = getThis();
176+
177+
ZEND_PARSE_PARAMETERS_START(1, 1)
178+
Z_PARAM_FUNC(fci, fci_cache)
179+
ZEND_PARSE_PARAMETERS_END();
180+
181+
this = PHP_MRLOOP_OBJ(obj);
182+
cb = emalloc(sizeof(php_mrloop_cb_t));
183+
PHP_CB_TO_MRLOOP_CB(cb, fci, fci_cache);
184+
185+
cb->signal = PHP_MRLOOP_FUTURE_TICK;
186+
cb->data = this->loop;
187+
188+
mr_call_soon(this->loop, php_mrloop_timer_cb, cb);
189+
190+
return;
191+
}
165192

166193
static void php_mrloop_readv_cb(void *data, int res)
167194
{

src/loop.h

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define DEFAULT_HTTP_HEADER_LIMIT 100
2929
#define PHP_MRLOOP_TIMER 1
3030
#define PHP_MRLOOP_PERIODIC_TIMER 2
31+
#define PHP_MRLOOP_FUTURE_TICK 3
3132

3233
struct php_mrloop_t;
3334
struct php_mrloop_cb_t;
@@ -130,6 +131,8 @@ static int php_mrloop_timer_cb(void *data);
130131
static void php_mrloop_add_timer(INTERNAL_FUNCTION_PARAMETERS);
131132
/* executes a specified action in perpetuity with each successive execution occurring after a specified time interval */
132133
static void php_mrloop_add_periodic_timer(INTERNAL_FUNCTION_PARAMETERS);
134+
/* schedules the execution of a specified action for the next event loop tick */
135+
static void php_mrloop_add_future_tick(INTERNAL_FUNCTION_PARAMETERS);
133136

134137
/* mrloop-bound callback specified during invocation of vectorized read function */
135138
static void php_mrloop_readv_cb(void *data, int res);

tests/013.phpt

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
futureTick() schedules the execution of a specified action for the next event loop tick
3+
--FILE--
4+
<?php
5+
6+
use ringphp\Mrloop;
7+
8+
$loop = Mrloop::init();
9+
10+
$tick = 0;
11+
12+
$loop->futureTick(
13+
function () use (&$tick) {
14+
echo \sprintf("Tick: %d\n", ++$tick);
15+
},
16+
);
17+
18+
$loop->futureTick(
19+
function () use ($loop, &$tick) {
20+
echo \sprintf("Tick: %d\n", ++$tick);
21+
$loop->stop();
22+
},
23+
);
24+
25+
$loop->run();
26+
27+
?>
28+
--EXPECT--
29+
Tick: 1
30+
Tick: 2

0 commit comments

Comments
 (0)