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;
#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;
enum php_uv_lock_type{
enum php_uv_lock_type {
IS_UV_RWLOCK = 1,
IS_UV_RWLOCK_RD = 2,
IS_UV_RWLOCK_WR = 3,
@ -145,11 +131,11 @@ typedef struct {
} php_uv_cb_t;
typedef struct {
int in_free;
zend_object std;
#ifdef ZTS
void ***thread_ctx;
#endif
zend_resource *resource_id;
int type;
uv_os_sock_t sock;
union {
@ -176,14 +162,15 @@ typedef struct {
uv_signal_t signal;
} uv;
char *buffer;
zend_resource *fs_fd;
zend_resource *fs_fd_alt;
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;
typedef struct {
int is_ipv4;
zend_resource *resource_id;
zend_object std;
union {
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
@ -191,9 +178,10 @@ typedef struct {
} php_uv_sockaddr_t;
typedef struct {
zend_object std;
int locked;
enum php_uv_lock_type type;
zend_resource *resource_id;
union {
uv_rwlock_t rwlock;
uv_mutex_t mutex;
@ -202,23 +190,21 @@ typedef struct {
} php_uv_lock_t;
typedef struct {
zend_resource *resource_id;
zend_object std;
int fd;
zend_resource *stream;
int flags;
} php_uv_stdio_t;
#define PHP_UV_RESOURCE_NAME "uv"
#define PHP_UV_SOCKADDR_RESOURCE_NAME "uv_sockaddr"
#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"
typedef struct {
zend_object std;
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*/
#ifdef PHP_WIN32
@ -233,4 +219,18 @@ typedef struct {
#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 */

View File

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

View File

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

View File

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

View File

@ -19,4 +19,6 @@ fwrite($fd, 'hello');
--EXPECTF--
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 <fcntl.h>
void php_uv_init(TSRMLS_D);
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)
void php_uv_init(zend_class_entry *uv_class_entry)
{
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_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);
@ -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);
UV_ERRNO_MAP(PHP_UV_ERRNO_GEN)
#undef PHP_UV_ERRNO_GEN
return 0;
}
void php_uv_init(TSRMLS_D)
{
php_uv_class_init(TSRMLS_C);
}