@@ -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}
107107static 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
166193static void php_mrloop_readv_cb (void * data , int res )
167194{
@@ -261,25 +288,29 @@ static int php_mrloop_tcp_server_recv(void *conn, int fd, ssize_t nbytes, char *
261288 array_init (& args [1 ]);
262289 add_assoc_string (& args [1 ], "client_addr" , (char * )client -> addr );
263290 add_assoc_long (& args [1 ], "client_port" , client -> port );
291+ add_assoc_long (& args [1 ], "client_fd" , client -> fd );
264292
265293 MRLOOP_G (tcp_cb )-> fci .retval = & result ;
266294 MRLOOP_G (tcp_cb )-> fci .param_count = 2 ;
267295 MRLOOP_G (tcp_cb )-> fci .params = args ;
268296
269- if (zend_call_function (& MRLOOP_G (tcp_cb )-> fci , & MRLOOP_G (tcp_cb )-> fci_cache ) == FAILURE ||
270- Z_TYPE (result ) != IS_STRING )
297+ if (zend_call_function (& MRLOOP_G (tcp_cb )-> fci , & MRLOOP_G (tcp_cb )-> fci_cache ) == FAILURE )
271298 {
272299 PHP_MRLOOP_THROW ("There is an error in your callback" );
273300 zval_ptr_dtor (& result );
274301
275302 return 1 ;
276303 }
277304
278- client -> iov .iov_base = Z_STRVAL (result );
279- client -> iov .iov_len = Z_STRLEN (result );
305+ if (Z_TYPE (result ) == IS_STRING )
306+ {
307+ client -> iov .iov_base = Z_STRVAL (result );
308+ client -> iov .iov_len = Z_STRLEN (result );
309+
310+ mr_writev (loop , client -> fd , & (client -> iov ), 1 );
311+ mr_flush (loop );
312+ }
280313
281- mr_writev (loop , client -> fd , & (client -> iov ), 1 );
282- mr_flush (loop );
283314 zval_ptr_dtor (& result );
284315
285316 return 1 ;
@@ -629,3 +660,36 @@ static void php_mrloop_add_write_stream(INTERNAL_FUNCTION_PARAMETERS)
629660
630661 return ;
631662}
663+ static void php_mrloop_writev (INTERNAL_FUNCTION_PARAMETERS )
664+ {
665+ zend_long fd ;
666+ zend_string * contents ;
667+ php_iovec_t iov ;
668+ php_mrloop_t * this ;
669+ zval * obj ;
670+ size_t nbytes ;
671+
672+ obj = getThis ();
673+
674+ ZEND_PARSE_PARAMETERS_START (2 , 2 )
675+ Z_PARAM_LONG (fd )
676+ Z_PARAM_STR (contents )
677+ ZEND_PARSE_PARAMETERS_END ();
678+
679+ this = PHP_MRLOOP_OBJ (obj );
680+
681+ if (fcntl ((int )fd , F_GETFD ) < 0 )
682+ {
683+ PHP_MRLOOP_THROW ("Detected invalid file descriptor" );
684+ mr_stop (this -> loop );
685+
686+ return ;
687+ }
688+
689+ nbytes = ZSTR_LEN (contents );
690+ iov .iov_base = ZSTR_VAL (contents );
691+ iov .iov_len = nbytes ;
692+
693+ mr_writev (this -> loop , fd , & iov , 1 );
694+ mr_flush (this -> loop );
695+ }
0 commit comments