Use objects instead of resources as handle representation

This also adds proper get_gc handlers in order to resolve potenial cycles
This commit is contained in:
Bob Weinand 2017-05-07 13:14:26 +02:00
parent 2b5a298f82
commit ad904731ba
7 changed files with 1337 additions and 1830 deletions

3068
php_uv.c

File diff suppressed because it is too large Load Diff

View File

@ -63,23 +63,9 @@ typedef struct {
extern zend_module_entry uv_module_entry; extern zend_module_entry uv_module_entry;
#define phpext_uv_ptr &uv_module_entry #define phpext_uv_ptr &uv_module_entry
ZEND_BEGIN_MODULE_GLOBALS(uv)
uv_loop_t *default_loop;
ZEND_END_MODULE_GLOBALS(uv)
#ifdef ZTS
#ifdef COMPILE_DL_UV
ZEND_TSRMLS_CACHE_EXTERN()
#endif
#define UV_G(v) TSRMG(uv_globals_id, zend_uv_globals *, v)
#else
#define UV_G(v) (uv_globals.v)
#endif
extern zend_class_entry *uv_class_entry; extern zend_class_entry *uv_class_entry;
enum php_uv_lock_type{ enum php_uv_lock_type {
IS_UV_RWLOCK = 1, IS_UV_RWLOCK = 1,
IS_UV_RWLOCK_RD = 2, IS_UV_RWLOCK_RD = 2,
IS_UV_RWLOCK_WR = 3, IS_UV_RWLOCK_WR = 3,
@ -145,11 +131,11 @@ typedef struct {
} php_uv_cb_t; } php_uv_cb_t;
typedef struct { typedef struct {
int in_free; zend_object std;
#ifdef ZTS #ifdef ZTS
void ***thread_ctx; void ***thread_ctx;
#endif #endif
zend_resource *resource_id;
int type; int type;
uv_os_sock_t sock; uv_os_sock_t sock;
union { union {
@ -176,14 +162,15 @@ typedef struct {
uv_signal_t signal; uv_signal_t signal;
} uv; } uv;
char *buffer; char *buffer;
zend_resource *fs_fd;
zend_resource *fs_fd_alt;
php_uv_cb_t *callback[PHP_UV_CB_MAX]; php_uv_cb_t *callback[PHP_UV_CB_MAX];
zval gc_data[PHP_UV_CB_MAX * 2];
zval fs_fd;
zval fs_fd_alt;
} php_uv_t; } php_uv_t;
typedef struct { typedef struct {
int is_ipv4; zend_object std;
zend_resource *resource_id;
union { union {
struct sockaddr_in ipv4; struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6; struct sockaddr_in6 ipv6;
@ -191,9 +178,10 @@ typedef struct {
} php_uv_sockaddr_t; } php_uv_sockaddr_t;
typedef struct { typedef struct {
zend_object std;
int locked; int locked;
enum php_uv_lock_type type; enum php_uv_lock_type type;
zend_resource *resource_id;
union { union {
uv_rwlock_t rwlock; uv_rwlock_t rwlock;
uv_mutex_t mutex; uv_mutex_t mutex;
@ -202,23 +190,21 @@ typedef struct {
} php_uv_lock_t; } php_uv_lock_t;
typedef struct { typedef struct {
zend_resource *resource_id; zend_object std;
int fd; int fd;
zend_resource *stream; zend_resource *stream;
int flags; int flags;
} php_uv_stdio_t; } php_uv_stdio_t;
#define PHP_UV_RESOURCE_NAME "uv" typedef struct {
#define PHP_UV_SOCKADDR_RESOURCE_NAME "uv_sockaddr" zend_object std;
#define PHP_UV_LOOP_RESOURCE_NAME "uv_loop"
#define PHP_UV_ARES_RESOURCE_NAME "uv_ares"
#define PHP_UV_LOCK_RESOURCE_NAME "uv_lock"
#define PHP_UV_MUTEX_RESOURCE_NAME "uv_mutex"
#define PHP_UV_STDIO_RESOURCE_NAME "uv_stdio"
uv_loop_t loop;
#define PHP_UV_LIST_INSERT(type, handle) Z_RES_P(zend_list_insert(type, handle)) size_t gc_buffer_size;
zval *gc_buffer;
} php_uv_loop_t;
/* File/directory stat mode constants*/ /* File/directory stat mode constants*/
#ifdef PHP_WIN32 #ifdef PHP_WIN32
@ -233,4 +219,18 @@ typedef struct {
#endif #endif
#endif #endif
ZEND_BEGIN_MODULE_GLOBALS(uv)
php_uv_loop_t *default_loop;
ZEND_END_MODULE_GLOBALS(uv)
#ifdef ZTS
#ifdef COMPILE_DL_UV
ZEND_TSRMLS_CACHE_EXTERN()
#endif
#define UV_G(v) TSRMG(uv_globals_id, zend_uv_globals *, v)
#else
#define UV_G(v) (uv_globals.v)
#endif
#endif /* PHP_UV_H */ #endif /* PHP_UV_H */

View File

@ -34,7 +34,7 @@ class TcpServer
public function close() public function close()
{ {
if (get_resource_type($this->tcp) === 'uv') { if ($this->tcp instanceof UV) {
uv_close($this->tcp); uv_close($this->tcp);
} }
} }
@ -65,4 +65,4 @@ uv_run($loop, UV::RUN_DEFAULT);
OK OK
OK OK
OK OK
OK OK

View File

@ -4,4 +4,5 @@ Check for uv_ip4_addr
<?php <?php
var_dump(uv_ip4_addr("0.0.0.0",0)); var_dump(uv_ip4_addr("0.0.0.0",0));
--EXPECTF-- --EXPECTF--
resource(%d) of type (uv_sockaddr) object(UVSockAddrIPv4)#1 (0) {
}

View File

@ -4,4 +4,5 @@ Check for uv_ip6_addr
<?php <?php
var_dump(uv_ip6_addr("::0",0)); var_dump(uv_ip6_addr("::0",0));
--EXPECTF-- --EXPECTF--
resource(%d) of type (uv_sockaddr) object(UVSockAddrIPv6)#1 (0) {
}

View File

@ -19,4 +19,6 @@ fwrite($fd, 'hello');
--EXPECTF-- --EXPECTF--
Warning: uv_poll_init(): invalid resource passed, this resource is not supported in %s on line %d Warning: uv_poll_init(): invalid resource passed, this resource is not supported in %s on line %d
Fatal error: uv_poll_init(): uv_poll_init failed in %s on line %d Warning: uv_poll_init(): uv_poll_init failed in %s on line %d
Warning: uv_poll_start() expects parameter 1 to be UVPoll, boolean given in %s on line %d

21
uv.c
View File

@ -19,20 +19,8 @@
#include "php_uv.h" #include "php_uv.h"
#include <fcntl.h> #include <fcntl.h>
void php_uv_init(TSRMLS_D); void php_uv_init(zend_class_entry *uv_class_entry)
zend_class_entry *uv_class_entry;
/* TODO: will be add soon */
static zend_function_entry php_uv_methods[] = {
{NULL, NULL, NULL}
};
static int php_uv_class_init(TSRMLS_D)
{ {
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "UV", php_uv_methods);
uv_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_class_constant_long(uv_class_entry, "RUN_DEFAULT", sizeof("RUN_DEFAULT")-1, UV_RUN_DEFAULT TSRMLS_CC); zend_declare_class_constant_long(uv_class_entry, "RUN_DEFAULT", sizeof("RUN_DEFAULT")-1, UV_RUN_DEFAULT TSRMLS_CC);
zend_declare_class_constant_long(uv_class_entry, "RUN_ONCE", sizeof("RUN_ONCE")-1, UV_RUN_ONCE TSRMLS_CC); zend_declare_class_constant_long(uv_class_entry, "RUN_ONCE", sizeof("RUN_ONCE")-1, UV_RUN_ONCE TSRMLS_CC);
zend_declare_class_constant_long(uv_class_entry, "RUN_NOWAIT", sizeof("RUN_NOWAIT")-1, UV_RUN_NOWAIT TSRMLS_CC); zend_declare_class_constant_long(uv_class_entry, "RUN_NOWAIT", sizeof("RUN_NOWAIT")-1, UV_RUN_NOWAIT TSRMLS_CC);
@ -198,11 +186,4 @@ static int php_uv_class_init(TSRMLS_D)
#define PHP_UV_ERRNO_GEN(name, msg_notused) zend_declare_class_constant_long(uv_class_entry, ZEND_STRL(#name), UV_##name); #define PHP_UV_ERRNO_GEN(name, msg_notused) zend_declare_class_constant_long(uv_class_entry, ZEND_STRL(#name), UV_##name);
UV_ERRNO_MAP(PHP_UV_ERRNO_GEN) UV_ERRNO_MAP(PHP_UV_ERRNO_GEN)
#undef PHP_UV_ERRNO_GEN #undef PHP_UV_ERRNO_GEN
return 0;
}
void php_uv_init(TSRMLS_D)
{
php_uv_class_init(TSRMLS_C);
} }