Skip to content

Commit 8fa85af

Browse files
committed
redis_object
1 parent 388e4a8 commit 8fa85af

File tree

4 files changed

+110
-75
lines changed

4 files changed

+110
-75
lines changed

common.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,18 @@ typedef struct {
680680
} RedisSock;
681681
/* }}} */
682682

683+
#if (PHP_MAJOR_VERSION < 7)
684+
typedef struct {
685+
zend_object std;
686+
RedisSock *sock;
687+
} redis_object;
688+
#else
689+
typedef struct {
690+
RedisSock *sock;
691+
zend_object std;
692+
} redis_object;
693+
#endif
694+
683695
void
684696
free_reply_callbacks(zval *z_this, RedisSock *redis_sock);
685697

redis.c

Lines changed: 89 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@
4242
#define R_SUB_CALLBACK_FT_TYPE 2
4343
#define R_SUB_CLOSURE_TYPE 3
4444

45-
int le_redis_sock;
46-
4745
#ifdef PHP_SESSION
4846
extern ps_module ps_mod_redis;
4947
extern ps_module ps_mod_redis_cluster;
@@ -426,36 +424,90 @@ static int send_discard_static(RedisSock *redis_sock TSRMLS_DC) {
426424
return result;
427425
}
428426

429-
/**
430-
* redis_destructor_redis_sock
431-
*/
432-
static void redis_destructor_redis_sock(zend_resource * rsrc TSRMLS_DC)
427+
#if (PHP_MAJOR_VERSION < 7)
428+
void
429+
free_redis_object(void *object TSRMLS_DC)
430+
{
431+
redis_object *redis = (redis_object *)object;
432+
433+
zend_object_std_dtor(&redis->std TSRMLS_CC);
434+
if (redis->sock) {
435+
redis_sock_disconnect(redis->sock TSRMLS_CC);
436+
redis_free_socket(redis->sock);
437+
}
438+
efree(redis);
439+
}
440+
441+
zend_object_value
442+
create_redis_object(zend_class_entry *ce TSRMLS_DC)
443+
{
444+
zend_object_value retval;
445+
redis_object *redis = ecalloc(1, sizeof(redis_object));
446+
447+
memset(redis, 0, sizeof(redis_object));
448+
zend_object_std_init(&redis->std, ce TSRMLS_CC);
449+
450+
#if PHP_VERSION_ID < 50399
451+
zval *tmp;
452+
zend_hash_copy(redis->std.properties, &ce->default_properties,
453+
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
454+
#endif
455+
456+
retval.handle = zend_objects_store_put(redis,
457+
(zend_objects_store_dtor_t)zend_objects_destroy_object,
458+
(zend_objects_free_object_storage_t)free_redis_object,
459+
NULL TSRMLS_CC);
460+
retval.handlers = zend_get_std_object_handlers();
461+
462+
return retval;
463+
}
464+
#else
465+
zend_object_handlers redis_object_handlers;
466+
467+
void
468+
free_redis_object(zend_object *object)
469+
{
470+
redis_object *redis = (redis_object *)((char *)(object) - XtOffsetOf(redis_object, std));
471+
472+
zend_object_std_dtor(&redis->std TSRMLS_CC);
473+
if (redis->sock) {
474+
redis_sock_disconnect(redis->sock TSRMLS_CC);
475+
redis_free_socket(redis->sock);
476+
}
477+
}
478+
479+
zend_object *
480+
create_redis_object(zend_class_entry *ce TSRMLS_DC)
433481
{
434-
RedisSock *redis_sock = (RedisSock *) rsrc->ptr;
435-
redis_sock_disconnect(redis_sock TSRMLS_CC);
436-
redis_free_socket(redis_sock);
482+
redis_object *redis = ecalloc(1, sizeof(redis_object) + zend_object_properties_size(ce));
483+
484+
redis->sock = NULL;
485+
486+
zend_object_std_init(&redis->std, ce TSRMLS_CC);
487+
object_properties_init(&redis->std, ce);
488+
489+
memcpy(&redis_object_handlers, zend_get_std_object_handlers(), sizeof(redis_object_handlers));
490+
redis_object_handlers.offset = XtOffsetOf(redis_object, std);
491+
redis_object_handlers.free_obj = free_redis_object;
492+
redis->std.handlers = &redis_object_handlers;
493+
494+
return &redis->std;
437495
}
496+
#endif
438497

439498
static zend_always_inline int
440499
redis_sock_get_instance(zval *id, RedisSock **redis_sock TSRMLS_DC, int no_throw)
441500
{
442-
zval *socket;
443-
int resource_type = 0;
501+
redis_object *redis;
444502

445-
if (Z_TYPE_P(id) == IS_OBJECT &&
446-
(socket = zend_hash_str_find(Z_OBJPROP_P(id), "socket", sizeof("socket") - 1)) != NULL
447-
) {
503+
if (Z_TYPE_P(id) == IS_OBJECT) {
448504
#if (PHP_MAJOR_VERSION < 7)
449-
*redis_sock = (RedisSock *)zend_list_find(Z_LVAL_P(socket), &resource_type);
505+
redis = (redis_object *)zend_objects_get_address(id TSRMLS_CC);
450506
#else
451-
*redis_sock = NULL;
452-
453-
if (Z_RES_P(socket) != NULL) {
454-
*redis_sock = (RedisSock *)Z_RES_P(socket)->ptr;
455-
resource_type = Z_RES_P(socket)->type;
456-
}
507+
redis = (redis_object *)((char *)Z_OBJ_P(id) - XtOffsetOf(redis_object, std));
457508
#endif
458-
if (*redis_sock && resource_type == le_redis_sock) {
509+
if (redis->sock) {
510+
*redis_sock = redis->sock;
459511
return 0;
460512
}
461513
}
@@ -580,6 +632,7 @@ PHP_MINIT_FUNCTION(redis)
580632
/* Redis class */
581633
INIT_CLASS_ENTRY(redis_class_entry, "Redis", redis_functions);
582634
redis_ce = zend_register_internal_class(&redis_class_entry TSRMLS_CC);
635+
redis_ce->create_object = create_redis_object;
583636

584637
/* RedisArray class */
585638
INIT_CLASS_ENTRY(redis_array_class_entry, "RedisArray", redis_array_functions);
@@ -616,12 +669,6 @@ PHP_MINIT_FUNCTION(redis)
616669
#endif
617670
);
618671

619-
le_redis_sock = zend_register_list_destructors_ex(
620-
redis_destructor_redis_sock,
621-
NULL,
622-
redis_sock_name, module_number
623-
);
624-
625672
/* Add shared class constants to Redis and RedisCluster objects */
626673
add_class_constants(redis_ce, 0 TSRMLS_CC);
627674
add_class_constants(redis_cluster_ce, 1 TSRMLS_CC);
@@ -737,13 +784,15 @@ PHP_METHOD(Redis, pconnect)
737784
}
738785
/* }}} */
739786

740-
PHP_REDIS_API int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
741-
zval *object, *socket;
787+
PHP_REDIS_API int
788+
redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
789+
{
790+
zval *object;
742791
char *host = NULL, *persistent_id = NULL;
743792
zend_long port = -1, retry_interval = 0;
744793
strlen_t host_len, persistent_id_len;
745794
double timeout = 0.0;
746-
RedisSock *redis_sock = NULL;
795+
redis_object *redis;
747796

748797
#ifdef ZTS
749798
/* not sure how in threaded mode this works so disabled persistence at
@@ -779,40 +828,24 @@ PHP_REDIS_API int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
779828
port = 6379;
780829
}
781830

782-
/* if there is a redis sock already we have to remove it from the list */
783-
if (redis_sock_get(object, &redis_sock TSRMLS_CC, 1) >= 0) {
784-
if ((socket = zend_hash_str_find(Z_OBJPROP_P(object), "socket", sizeof("socket") - 1)) == NULL)
785-
{
786-
/* maybe there is a socket but the id isn't known.. what to do? */
787-
} else {
788-
/* The refcount should be decreased and destructor invoked */
789831
#if (PHP_MAJOR_VERSION < 7)
790-
zend_list_delete(Z_LVAL_P(socket));
832+
redis = (redis_object *)zend_objects_get_address(object TSRMLS_CC);
791833
#else
792-
zend_list_close(Z_RES_P(socket));
834+
redis = (redis_object *)((char *)Z_OBJ_P(object) - XtOffsetOf(redis_object, std));
793835
#endif
794-
}
836+
/* if there is a redis sock already we have to remove it */
837+
if (redis->sock) {
838+
redis_sock_disconnect(redis->sock TSRMLS_CC);
839+
redis_free_socket(redis->sock);
795840
}
796841

797-
redis_sock = redis_sock_create(host, host_len, port, timeout, persistent,
842+
redis->sock = redis_sock_create(host, host_len, port, timeout, persistent,
798843
persistent_id, retry_interval, 0);
799844

800-
if (redis_sock_server_open(redis_sock, 1 TSRMLS_CC) < 0) {
801-
redis_free_socket(redis_sock);
845+
if (redis_sock_server_open(redis->sock, 1 TSRMLS_CC) < 0) {
846+
redis_free_socket(redis->sock);
802847
return FAILURE;
803848
}
804-
#if (PHP_MAJOR_VERSION < 7)
805-
int id;
806-
#if PHP_VERSION_ID >= 50400
807-
id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC);
808-
#else
809-
id = zend_list_insert(redis_sock, le_redis_sock);
810-
#endif
811-
add_property_resource(object, "socket", id);
812-
#else
813-
zval *id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC);
814-
add_property_resource(object, "socket", Z_RES_P(id));
815-
#endif
816849

817850
return SUCCESS;
818851
}

redis_array_impl.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
#define PHPREDIS_INDEX_NAME "__phpredis_array_index__"
2828

29-
extern int le_redis_sock;
3029
extern zend_class_entry *redis_ce;
3130

3231
RedisArray*
@@ -36,7 +35,7 @@ ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b
3635
char *host, *p;
3736
short port;
3837
zval *zpData, z_cons, z_ret;
39-
RedisSock *redis_sock = NULL;
38+
redis_object *redis;
4039

4140
/* function calls on the Redis object */
4241
ZVAL_STRINGL(&z_cons, "__construct", 11);
@@ -72,29 +71,21 @@ ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b
7271
call_user_function(&redis_ce->function_table, &ra->redis[i], &z_cons, &z_ret, 0, NULL);
7372
zval_dtor(&z_ret);
7473

74+
#if (PHP_MAJOR_VERSION < 7)
75+
redis = (redis_object *)zend_objects_get_address(&ra->redis[i] TSRMLS_CC);
76+
#else
77+
redis = (redis_object *)((char *)Z_OBJ_P(&ra->redis[i]) - XtOffsetOf(redis_object, std));
78+
#endif
79+
7580
/* create socket */
76-
redis_sock = redis_sock_create(host, host_len, port, ra->connect_timeout, ra->pconnect, NULL, retry_interval, b_lazy_connect);
81+
redis->sock = redis_sock_create(host, host_len, port, ra->connect_timeout, ra->pconnect, NULL, retry_interval, b_lazy_connect);
7782

7883
if (!b_lazy_connect)
7984
{
8085
/* connect */
81-
redis_sock_server_open(redis_sock, 1 TSRMLS_CC);
86+
redis_sock_server_open(redis->sock, 1 TSRMLS_CC);
8287
}
8388

84-
/* attach */
85-
#if (PHP_MAJOR_VERSION < 7)
86-
int id;
87-
#if PHP_VERSION_ID >= 50400
88-
id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC);
89-
#else
90-
id = zend_list_insert(redis_sock, le_redis_sock);
91-
#endif
92-
add_property_resource(&ra->redis[i], "socket", id);
93-
#else
94-
zval *id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC);
95-
add_property_resource(&ra->redis[i], "socket", Z_RES_P(id));
96-
#endif
97-
9889
ra->count = ++i;
9990
}
10091

redis_array_impl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <stdint.h>
88
#endif
99

10-
#include "common.h"
1110
#include "redis_array.h"
1211

1312
RedisArray *ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b_lazy_connect TSRMLS_DC);

0 commit comments

Comments
 (0)