Skip to content

Commit 688b0e1

Browse files
author
ace411
committed
feat: add stream support to writev() function
- add support for PHP streams to writev() function - replace generic stream-related control flow with PHP_STREAM_TO_FD macro
1 parent c2928e3 commit 688b0e1

File tree

3 files changed

+28
-60
lines changed

3 files changed

+28
-60
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class Mrloop
5555
callable $callback,
5656
): void
5757
public tcpServer(int $port, callable $callback): void
58-
public writev(int $fd, string $message): void
58+
public writev(int|resource $fd, string $message): void
5959
public static parseHttpRequest(string $request, int $headerlimit = 100): iterable
6060
public static parseHttpResponse(string $response, int $headerlimit = 100): iterable
6161
public addTimer(float $interval, callable $callback): void
@@ -290,7 +290,7 @@ The example above will produce output similar to that in the snippet to follow.
290290
### `Mrloop::writev`
291291

292292
```php
293-
public Mrloop::writev(int $fd, string $contents): void
293+
public Mrloop::writev(int|resource $fd, string $contents): void
294294
```
295295

296296
Performs vectorized non-blocking write operation on a specified file descriptor.

mrloop_arginfo.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
5151
ZEND_END_ARG_INFO()
5252

5353
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Mrloop_writev, 0, 0, 2)
54-
ZEND_ARG_TYPE_INFO(0, fd, IS_LONG, 0)
54+
ZEND_ARG_TYPE_INFO(0, fd, IS_LONG | IS_RESOURCE, 0)
5555
ZEND_ARG_TYPE_INFO(0, contents, IS_STRING, 0)
5656
ZEND_END_ARG_INFO()
5757

src/loop.c

+25-57
Original file line numberDiff line numberDiff line change
@@ -549,32 +549,7 @@ static void php_mrloop_add_read_stream(INTERNAL_FUNCTION_PARAMETERS)
549549
this = PHP_MRLOOP_OBJ(obj);
550550

551551
// convert resource to PHP stream
552-
if ((stream = (php_stream *)zend_fetch_resource_ex(res, NULL, php_file_le_stream())))
553-
{
554-
// extract file descriptor from resource stream
555-
if (php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void *)&fd, 1) == FAILURE || fd < 0)
556-
{
557-
PHP_MRLOOP_THROW("Passed resource without file descriptor");
558-
RETURN_NULL();
559-
560-
close(fd);
561-
562-
return;
563-
}
564-
}
565-
566-
// set non-blocking mode
567-
if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0)
568-
{
569-
close(fd);
570-
571-
char *error = strerror(errno);
572-
PHP_MRLOOP_THROW(error);
573-
574-
mr_stop(this->loop);
575-
576-
return;
577-
}
552+
PHP_STREAM_TO_FD(stream, res, fd);
578553

579554
fnbytes = (size_t)(nbytes_null == true ? DEFAULT_STREAM_BUFF_LEN : nbytes);
580555

@@ -618,30 +593,7 @@ static void php_mrloop_add_write_stream(INTERNAL_FUNCTION_PARAMETERS)
618593

619594
this = PHP_MRLOOP_OBJ(obj);
620595

621-
if ((stream = (php_stream *)zend_fetch_resource_ex(res, NULL, php_file_le_stream())))
622-
{
623-
if (php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void *)&fd, 1) == FAILURE || fd < 0)
624-
{
625-
PHP_MRLOOP_THROW("Passed resource without file descriptor");
626-
RETURN_NULL();
627-
628-
close(fd);
629-
630-
return;
631-
}
632-
}
633-
634-
if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0)
635-
{
636-
close(fd);
637-
638-
char *error = strerror(errno);
639-
PHP_MRLOOP_THROW(error);
640-
641-
mr_stop(this->loop);
642-
643-
return;
644-
}
596+
PHP_STREAM_TO_FD(stream, res, fd);
645597

646598
nbytes = ZSTR_LEN(contents);
647599
iov = emalloc(sizeof(php_iovec_t));
@@ -662,28 +614,44 @@ static void php_mrloop_add_write_stream(INTERNAL_FUNCTION_PARAMETERS)
662614
}
663615
static void php_mrloop_writev(INTERNAL_FUNCTION_PARAMETERS)
664616
{
665-
zend_long fd;
666617
zend_string *contents;
667618
php_iovec_t iov;
668619
php_mrloop_t *this;
669-
zval *obj;
620+
zval *obj, *res;
670621
size_t nbytes;
622+
php_stream *stream;
623+
int fd;
671624

672625
obj = getThis();
626+
fd = -1;
673627

674628
ZEND_PARSE_PARAMETERS_START(2, 2)
675-
Z_PARAM_LONG(fd)
629+
Z_PARAM_ZVAL(res)
676630
Z_PARAM_STR(contents)
677631
ZEND_PARSE_PARAMETERS_END();
678632

679633
this = PHP_MRLOOP_OBJ(obj);
680634

681-
if (fcntl((int)fd, F_GETFD) < 0)
635+
if (Z_TYPE_P(res) == IS_RESOURCE)
682636
{
683-
PHP_MRLOOP_THROW("Detected invalid file descriptor");
684-
mr_stop(this->loop);
637+
PHP_STREAM_TO_FD(stream, res, fd);
638+
}
639+
else if (Z_TYPE_P(res) == IS_LONG)
640+
{
641+
fd = Z_LVAL_P(res);
685642

686-
return;
643+
if (fcntl(fd, F_GETFD) < 0)
644+
{
645+
PHP_MRLOOP_THROW("Detected invalid file descriptor");
646+
mr_stop(this->loop);
647+
648+
return;
649+
}
650+
}
651+
else
652+
{
653+
PHP_MRLOOP_THROW("Detected invalid file descriptor");
654+
RETURN_NULL();
687655
}
688656

689657
nbytes = ZSTR_LEN(contents);

0 commit comments

Comments
 (0)