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