3636
3737static int le_redis_sock ;
3838static int le_redis_multi_access_type ;
39+ int le_redis_multi_head ;
40+ int le_redis_multi_current ;
41+ int le_redis_pipeline_head ;
42+ int le_redis_pipeline_current ;
3943
4044static zend_class_entry * redis_ce ;
4145static zend_class_entry * redis_exception_ce ;
@@ -274,6 +278,30 @@ PHP_MINIT_FUNCTION(redis)
274278 redis_multi_access_type_name , module_number
275279 );
276280
281+ le_redis_multi_head = zend_register_list_destructors_ex (
282+ redis_destructor_multi_access ,
283+ NULL ,
284+ redis_multi_access_type_name , module_number
285+ );
286+
287+ le_redis_multi_current = zend_register_list_destructors_ex (
288+ redis_destructor_multi_access ,
289+ NULL ,
290+ redis_multi_access_type_name , module_number
291+ );
292+
293+ le_redis_pipeline_head = zend_register_list_destructors_ex (
294+ redis_destructor_multi_access ,
295+ NULL ,
296+ redis_multi_access_type_name , module_number
297+ );
298+
299+ le_redis_pipeline_current = zend_register_list_destructors_ex (
300+ redis_destructor_multi_access ,
301+ NULL ,
302+ redis_multi_access_type_name , module_number
303+ );
304+
277305 add_constant_long (redis_ce , "REDIS_NOT_FOUND" , REDIS_NOT_FOUND );
278306 add_constant_long (redis_ce , "REDIS_STRING" , REDIS_STRING );
279307 add_constant_long (redis_ce , "REDIS_SET" , REDIS_SET );
@@ -336,6 +364,10 @@ PHP_METHOD(Redis, __construct)
336364 add_property_resource (object , "multi_flag" , id );
337365
338366 set_flag (object , REDIS_ATOMIC );
367+ set_multi_head (object , NULL );
368+ set_multi_current (object , NULL );
369+ set_pipeline_head (object , NULL );
370+ set_pipeline_current (object , NULL );
339371
340372}
341373/* }}} */
@@ -361,6 +393,7 @@ PHPAPI void set_flag(zval *object, int new_flag)
361393 add_property_resource (object , "multi_flag" , id );
362394
363395}
396+
364397/* {{{ proto boolean Redis::connect(string host, int port [, int timeout])
365398 */
366399PHP_METHOD (Redis , connect )
@@ -3973,7 +4006,7 @@ PHP_METHOD(Redis, multi)
39734006 RETURN_FALSE ;
39744007 }
39754008
3976- current = NULL ;
4009+ set_multi_current ( getThis (), NULL ); /* current = NULL; */
39774010
39784011 IF_MULTI () {
39794012 cmd_len = redis_cmd_format (& cmd , "*1" _NL "$5" _NL "MULTI" _NL );
@@ -3996,7 +4029,7 @@ PHP_METHOD(Redis, multi)
39964029 RETURN_FALSE ;
39974030 }
39984031 IF_PIPELINE () {
3999- free_reply_callbacks ();
4032+ free_reply_callbacks (getThis () );
40004033 RETURN_ZVAL (getThis (), 1 , 0 );
40014034 }
40024035}
@@ -4052,7 +4085,7 @@ PHPAPI int redis_sock_read_multibulk_pipeline_reply(INTERNAL_FUNCTION_PARAMETERS
40524085 efree (z_tab );
40534086
40544087 /* free allocated function/request memory */
4055- free_reply_callbacks ();
4088+ free_reply_callbacks (getThis () );
40564089
40574090 return 0 ;
40584091
@@ -4090,25 +4123,28 @@ PHPAPI int redis_sock_read_multibulk_multi_reply(INTERNAL_FUNCTION_PARAMETERS,
40904123}
40914124
40924125void
4093- free_reply_callbacks () {
4126+ free_reply_callbacks (zval * z_this ) {
40944127
40954128 fold_item * fi ;
4129+ fold_item * head = get_multi_head (z_this );
40964130 for (fi = head ; fi ; ) {
40974131 fold_item * fi_next = fi -> next ;
40984132 free (fi );
40994133 fi = fi_next ;
41004134 }
4101- head = current = NULL ;
4135+ set_multi_head (z_this , NULL );
4136+ set_multi_current (z_this , NULL );
41024137
41034138
41044139 request_item * ri ;
4105- for (ri = head_request ; ri ; ) {
4140+ for (ri = get_pipeline_head ( z_this ) ; ri ; ) {
41064141 struct request_item * ri_next = ri -> next ;
41074142 free (ri -> request_str );
41084143 free (ri );
41094144 ri = ri_next ;
41104145 }
4111- current_request = head_request = NULL ;
4146+ set_pipeline_head (z_this , NULL );
4147+ set_pipeline_current (z_this , NULL );
41124148
41134149}
41144150
@@ -4142,10 +4178,10 @@ PHP_METHOD(Redis, exec)
41424178
41434179 if (redis_sock_read_multibulk_multi_reply (INTERNAL_FUNCTION_PARAM_PASSTHRU , redis_sock TSRMLS_CC ) < 0 ) {
41444180 zval_dtor (return_value );
4145- free_reply_callbacks ();
4181+ free_reply_callbacks (object );
41464182 RETURN_FALSE ;
41474183 }
4148- free_reply_callbacks ();
4184+ free_reply_callbacks (object );
41494185 set_flag (object , REDIS_ATOMIC );
41504186 }
41514187
@@ -4156,41 +4192,41 @@ PHP_METHOD(Redis, exec)
41564192 int offset = 0 ;
41574193
41584194 /* compute the total request size */
4159- for (ri = head_request ; ri ; ri = ri -> next ) {
4195+ for (ri = get_pipeline_head ( object ) ; ri ; ri = ri -> next ) {
41604196 total += ri -> request_size ;
41614197 }
41624198 if (total ) {
41634199 request = malloc (total );
41644200 }
41654201
41664202 /* concatenate individual elements one by one in the target buffer */
4167- for (ri = head_request ; ri ; ri = ri -> next ) {
4203+ for (ri = get_pipeline_head ( object ) ; ri ; ri = ri -> next ) {
41684204 memcpy (request + offset , ri -> request_str , ri -> request_size );
41694205 offset += ri -> request_size ;
41704206 }
41714207
41724208 if (request != NULL ) {
41734209 if (redis_sock_write (redis_sock , request , total ) < 0 ) {
41744210 free (request );
4175- free_reply_callbacks ();
4211+ free_reply_callbacks (object );
41764212 set_flag (object , REDIS_ATOMIC );
41774213 RETURN_FALSE ;
41784214 }
41794215 free (request );
41804216 } else {
41814217 set_flag (object , REDIS_ATOMIC );
4182- free_reply_callbacks ();
4218+ free_reply_callbacks (object );
41834219 array_init (return_value ); /* empty array when no command was run. */
41844220 return ;
41854221 }
41864222
41874223 if (redis_sock_read_multibulk_pipeline_reply (INTERNAL_FUNCTION_PARAM_PASSTHRU , redis_sock TSRMLS_CC ) < 0 ) {
41884224 set_flag (object , REDIS_ATOMIC );
4189- free_reply_callbacks ();
4225+ free_reply_callbacks (object );
41904226 RETURN_FALSE ;
41914227 }
41924228 set_flag (object , REDIS_ATOMIC );
4193- free_reply_callbacks ();
4229+ free_reply_callbacks (object );
41944230 }
41954231}
41964232
@@ -4202,9 +4238,12 @@ PHPAPI int redis_sock_read_multibulk_multi_reply_loop(INTERNAL_FUNCTION_PARAMETE
42024238 RedisSock * redis_sock , zval * z_tab , int numElems TSRMLS_DC )
42034239{
42044240
4241+ fold_item * head = get_multi_head (getThis ());
4242+ fold_item * current = get_multi_current (getThis ());
42054243 for (current = head ; current ; current = current -> next ) {
42064244 fold_this_item (INTERNAL_FUNCTION_PARAM_PASSTHRU , current , redis_sock , z_tab TSRMLS_CC );
42074245 }
4246+ set_multi_current (getThis (), current );
42084247 return 0 ;
42094248}
42104249
@@ -4229,7 +4268,7 @@ PHP_METHOD(Redis, pipeline)
42294268 We need the response format of the n - 1 command. So, we can delete when n > 2, the { 1 .. n - 2} commands
42304269 */
42314270
4232- free_reply_callbacks ();
4271+ free_reply_callbacks (getThis () );
42334272
42344273 RETURN_ZVAL (getThis (), 1 , 0 );
42354274}
0 commit comments