Skip to content

Commit a765f8d

Browse files
committed
redis_array_object
1 parent 4cd06b2 commit a765f8d

File tree

4 files changed

+107
-51
lines changed

4 files changed

+107
-51
lines changed

redis.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
#define R_SUB_CLOSURE_TYPE 3
4444

4545
int le_redis_sock;
46-
extern int le_redis_array;
4746

4847
#ifdef PHP_SESSION
4948
extern ps_module ps_mod_redis;
@@ -583,24 +582,15 @@ PHP_MINIT_FUNCTION(redis)
583582
redis_ce = zend_register_internal_class(&redis_class_entry TSRMLS_CC);
584583

585584
/* RedisArray class */
586-
INIT_CLASS_ENTRY(redis_array_class_entry, "RedisArray",
587-
redis_array_functions);
588-
redis_array_ce = zend_register_internal_class(&redis_array_class_entry
589-
TSRMLS_CC);
585+
INIT_CLASS_ENTRY(redis_array_class_entry, "RedisArray", redis_array_functions);
586+
redis_array_ce = zend_register_internal_class(&redis_array_class_entry TSRMLS_CC);
587+
redis_array_ce->create_object = create_redis_array_object;
590588

591589
/* RedisCluster class */
592-
INIT_CLASS_ENTRY(redis_cluster_class_entry, "RedisCluster",
593-
redis_cluster_functions);
594-
redis_cluster_ce = zend_register_internal_class(&redis_cluster_class_entry
595-
TSRMLS_CC);
590+
INIT_CLASS_ENTRY(redis_cluster_class_entry, "RedisCluster", redis_cluster_functions);
591+
redis_cluster_ce = zend_register_internal_class(&redis_cluster_class_entry TSRMLS_CC);
596592
redis_cluster_ce->create_object = create_cluster_context;
597593

598-
le_redis_array = zend_register_list_destructors_ex(
599-
redis_destructor_redis_array,
600-
NULL,
601-
"Redis Array", module_number
602-
);
603-
604594
/* RedisException class */
605595
INIT_CLASS_ENTRY(redis_exception_class_entry, "RedisException", NULL);
606596
redis_exception_ce = zend_register_internal_class_ex(

redis_array.c

Lines changed: 92 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ zend_function_entry redis_array_functions[] = {
9292
PHP_FE_END
9393
};
9494

95-
static void redis_array_free(RedisArray *ra) {
95+
static void
96+
redis_array_free(RedisArray *ra)
97+
{
9698
int i;
9799

98100
/* Redis objects */
@@ -116,46 +118,106 @@ static void redis_array_free(RedisArray *ra) {
116118
efree(ra);
117119
}
118120

119-
int le_redis_array;
120-
void redis_destructor_redis_array(zend_resource * rsrc TSRMLS_DC)
121+
#if (PHP_MAJOR_VERSION < 7)
122+
typedef struct {
123+
zend_object std;
124+
RedisArray *ra;
125+
} redis_array_object;
126+
127+
void
128+
free_redis_array_object(void *object TSRMLS_DC)
129+
{
130+
redis_array_object *obj = (redis_array_object *)object;
131+
132+
zend_object_std_dtor(&obj->std TSRMLS_CC);
133+
if (obj->ra) {
134+
if (obj->ra->prev) redis_array_free(obj->ra->prev);
135+
redis_array_free(obj->ra);
136+
}
137+
efree(obj);
138+
}
139+
140+
zend_object_value
141+
create_redis_array_object(zend_class_entry *ce TSRMLS_DC)
121142
{
122-
RedisArray *ra = (RedisArray*)rsrc->ptr;
143+
zend_object_value retval;
144+
redis_array_object *obj = ecalloc(1, sizeof(redis_array_object));
145+
memset(obj, 0, sizeof(redis_array_object));
123146

124-
/* Free previous ring if it's set */
125-
if(ra->prev) redis_array_free(ra->prev);
147+
zend_object_std_init(&obj->std, ce TSRMLS_CC);
126148

127-
/* Free parent array */
128-
redis_array_free(ra);
149+
#if PHP_VERSION_ID < 50399
150+
zval *tmp;
151+
zend_hash_copy(obj->std.properties, &ce->default_properties,
152+
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
153+
#endif
154+
155+
retval.handle = zend_objects_store_put(obj,
156+
(zend_objects_store_dtor_t)zend_objects_destroy_object,
157+
(zend_objects_free_object_storage_t)free_redis_array_object,
158+
NULL TSRMLS_CC);
159+
retval.handlers = zend_get_std_object_handlers();
160+
161+
return retval;
129162
}
163+
#else
164+
typedef struct {
165+
RedisArray *ra;
166+
zend_object std;
167+
} redis_array_object;
130168

169+
zend_object_handlers redis_array_object_handlers;
170+
171+
void
172+
free_redis_array_object(zend_object *object)
173+
{
174+
redis_array_object *obj = (redis_array_object *)((char *)(object) - XtOffsetOf(redis_array_object, std));
175+
176+
if (obj->ra) {
177+
if (obj->ra->prev) redis_array_free(obj->ra->prev);
178+
redis_array_free(obj->ra);
179+
}
180+
zend_object_std_dtor(&obj->std TSRMLS_CC);
181+
}
182+
183+
zend_object *
184+
create_redis_array_object(zend_class_entry *ce TSRMLS_DC)
185+
{
186+
redis_array_object *obj = ecalloc(1, sizeof(redis_array_object) + zend_object_properties_size(ce));
187+
188+
memset(obj, 0, sizeof(redis_array_object));
189+
zend_object_std_init(&obj->std, ce TSRMLS_CC);
190+
object_properties_init(&obj->std, ce);
191+
192+
memcpy(&redis_array_object_handlers, zend_get_std_object_handlers(), sizeof(redis_array_object_handlers));
193+
redis_array_object_handlers.offset = XtOffsetOf(redis_array_object, std);
194+
redis_array_object_handlers.free_obj = free_redis_array_object;
195+
obj->std.handlers = &redis_array_object_handlers;
196+
197+
return &obj->std;
198+
}
199+
#endif
131200

132201
/**
133202
* redis_array_get
134203
*/
135-
PHP_REDIS_API int redis_array_get(zval *id, RedisArray **ra TSRMLS_DC)
204+
PHP_REDIS_API int
205+
redis_array_get(zval *id, RedisArray **ra TSRMLS_DC)
136206
{
207+
redis_array_object *obj;
137208

138-
zval *socket;
139-
140-
if (Z_TYPE_P(id) != IS_OBJECT || (socket = zend_hash_str_find(Z_OBJPROP_P(id),
141-
"socket", sizeof("socket") - 1)) == NULL) {
142-
return -1;
143-
}
144-
209+
if (Z_TYPE_P(id) == IS_OBJECT) {
145210
#if (PHP_MAJOR_VERSION < 7)
146-
int resource_type;
147-
*ra = (RedisArray *)zend_list_find(Z_LVAL_P(socket), &resource_type);
148-
if (!*ra || resource_type != le_redis_array) {
211+
obj = (redis_array_object *)zend_objects_get_address(id TSRMLS_CC);
149212
#else
150-
if (Z_RES_P(socket) == NULL ||
151-
!(*ra = (RedisArray *)Z_RES_P(socket)->ptr) ||
152-
Z_RES_P(socket)->type != le_redis_array
153-
) {
213+
obj = (redis_array_object *)((char *)Z_OBJ_P(id) - XtOffsetOf(redis_array_object, std));
154214
#endif
155-
return -1;
215+
if (obj->ra) {
216+
*ra = obj->ra;
217+
return 0;
218+
}
156219
}
157-
158-
return 0;
220+
return -1;
159221
}
160222

161223
uint32_t rcrc32(const char *s, size_t sz) {
@@ -220,6 +282,7 @@ PHP_METHOD(RedisArray, __construct)
220282
long l_retry_interval = 0;
221283
zend_bool b_lazy_connect = 0;
222284
double d_connect_timeout = 0;
285+
redis_array_object *obj;
223286

224287
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &z0, &z_opts) == FAILURE) {
225288
RETURN_FALSE;
@@ -302,7 +365,6 @@ PHP_METHOD(RedisArray, __construct)
302365

303366
default:
304367
WRONG_PARAM_COUNT;
305-
break;
306368
}
307369
zval_dtor(&z_dist);
308370
zval_dtor(&z_fun);
@@ -312,17 +374,11 @@ PHP_METHOD(RedisArray, __construct)
312374
ra->connect_timeout = d_connect_timeout;
313375
if(ra->prev) ra->prev->auto_rehash = b_autorehash;
314376
#if (PHP_MAJOR_VERSION < 7)
315-
int id;
316-
#if PHP_VERSION_ID >= 50400
317-
id = zend_list_insert(ra, le_redis_array TSRMLS_CC);
318-
#else
319-
id = zend_list_insert(ra, le_redis_array);
320-
#endif
321-
add_property_resource(getThis(), "socket", id);
377+
obj = (redis_array_object *)zend_objects_get_address(getThis() TSRMLS_CC);
322378
#else
323-
zval *id = zend_list_insert(ra, le_redis_array TSRMLS_CC);
324-
add_property_resource(getThis(), "socket", Z_RES_P(id));
379+
obj = (redis_array_object *)((char *)Z_OBJ_P(getThis()) - XtOffsetOf(redis_array_object, std));
325380
#endif
381+
obj->ra = ra;
326382
}
327383
}
328384

redis_array.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,13 @@ typedef struct RedisArray_ {
5858

5959
uint32_t rcrc32(const char *s, size_t sz);
6060

61+
#if (PHP_MAJOR_VERSION < 7)
62+
zend_object_value create_redis_array_object(zend_class_entry *ce TSRMLS_DC);
63+
void free_redis_array_object(void *object TSRMLS_DC);
64+
#else
65+
zend_object *create_redis_array_object(zend_class_entry *ce TSRMLS_DC);
66+
void free_redis_array_object(zend_object *object);
67+
#endif
68+
6169

6270
#endif

redis_array_impl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,8 @@ ra_rehash_server(RedisArray *ra, zval *z_redis, const char *hostname, zend_bool
11761176
count = ra_rehash_scan(z_redis, &keys, &key_lens, "KEYS", "*" TSRMLS_CC);
11771177
}
11781178

1179+
if (count < 0) return;
1180+
11791181
/* callback */
11801182
if(z_cb && z_cb_cache) {
11811183
ZVAL_NULL(&z_ret);

0 commit comments

Comments
 (0)