@@ -485,6 +485,7 @@ PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS,
485485 subscribeCallback * cb ;
486486 subscribeContext * sctx = (subscribeContext * )ctx ;
487487 zval * z_tmp , z_resp ;
488+ int i ;
488489
489490 ALLOC_HASHTABLE (subs );
490491 zend_hash_init (subs , 0 , NULL , ht_free_subs , 0 );
@@ -515,13 +516,21 @@ PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS,
515516 zval_dtor (& z_resp );
516517 }
517518
519+ if (strcasecmp (sctx -> kw , "ssubscribe" ) == 0 ) {
520+ i = REDIS_SSUBSCRIBE_IDX ;
521+ } else if (strcasecmp (sctx -> kw , "psubscribe" ) == 0 ) {
522+ i = REDIS_PSUBSCRIBE_IDX ;
523+ } else {
524+ i = REDIS_SUBSCRIBE_IDX ;
525+ }
526+
518527 efree (sctx );
519528
520- if (redis_sock -> subs ) {
529+ if (redis_sock -> subs [ i ] ) {
521530 zend_string * zkey ;
522531
523532 ZEND_HASH_FOREACH_STR_KEY_PTR (subs , zkey , cb ) {
524- zend_hash_update_mem (redis_sock -> subs , zkey , cb , sizeof (* cb ));
533+ zend_hash_update_mem (redis_sock -> subs [ i ] , zkey , cb , sizeof (* cb ));
525534 } ZEND_HASH_FOREACH_END ();
526535 zend_hash_destroy (subs );
527536 efree (subs );
@@ -530,9 +539,9 @@ PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS,
530539 return SUCCESS ;
531540 }
532541
533- redis_sock -> subs = subs ;
542+ redis_sock -> subs [ i ] = subs ;
534543 /* Multibulk response, {[pattern], type, channel, payload } */
535- while (redis_sock -> subs ) {
544+ while (redis_sock -> subs [ i ] ) {
536545 zval z_ret , z_args [4 ], * z_type , * z_chan , * z_pat = NULL , * z_data ;
537546 HashTable * ht_tab ;
538547 int tab_idx = 1 , is_pmsg = 0 ;
@@ -551,9 +560,10 @@ PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS,
551560 }
552561
553562 // Check for message or pmessage
554- if (!strncmp (Z_STRVAL_P (z_type ), "message" , 7 ) ||
555- !strncmp (Z_STRVAL_P (z_type ), "pmessage" , 8 ))
556- {
563+ if (zend_string_equals_literal_ci (Z_STR_P (z_type ), "message" ) ||
564+ zend_string_equals_literal_ci (Z_STR_P (z_type ), "pmessage" ) ||
565+ zend_string_equals_literal_ci (Z_STR_P (z_type ), "smessage" )
566+ ) {
557567 is_pmsg = * Z_STRVAL_P (z_type )== 'p' ;
558568 } else {
559569 zval_dtor (& z_resp );
@@ -574,7 +584,7 @@ PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS,
574584 goto failure ;
575585 }
576586
577- if ((cb = zend_hash_str_find_ptr (redis_sock -> subs , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ))) == NULL ) {
587+ if ((cb = zend_hash_str_find_ptr (redis_sock -> subs [ i ] , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ))) == NULL ) {
578588 goto failure ;
579589 }
580590
@@ -624,6 +634,18 @@ PHP_REDIS_API int redis_unsubscribe_response(INTERNAL_FUNCTION_PARAMETERS,
624634{
625635 subscribeContext * sctx = (subscribeContext * )ctx ;
626636 zval * z_chan , z_ret , z_resp ;
637+ int i ;
638+
639+ if (strcasecmp (sctx -> kw , "sunsubscribe" ) == 0 ) {
640+ i = REDIS_SSUBSCRIBE_IDX ;
641+ } else if (strcasecmp (sctx -> kw , "punsubscribe" ) == 0 ) {
642+ i = REDIS_PSUBSCRIBE_IDX ;
643+ } else {
644+ i = REDIS_SUBSCRIBE_IDX ;
645+ }
646+ if (!sctx -> argc && redis_sock -> subs [i ]) {
647+ sctx -> argc = zend_hash_num_elements (redis_sock -> subs [i ]);
648+ }
627649
628650 array_init (& z_ret );
629651
@@ -639,12 +661,12 @@ PHP_REDIS_API int redis_unsubscribe_response(INTERNAL_FUNCTION_PARAMETERS,
639661 return FAILURE ;
640662 }
641663
642- if (!redis_sock -> subs ||
643- !zend_hash_str_exists (redis_sock -> subs , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ))
664+ if (!redis_sock -> subs [ i ] ||
665+ !zend_hash_str_exists (redis_sock -> subs [ i ] , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ))
644666 ) {
645667 add_assoc_bool_ex (& z_ret , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ), 0 );
646668 } else {
647- zend_hash_str_del (redis_sock -> subs , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ));
669+ zend_hash_str_del (redis_sock -> subs [ i ] , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ));
648670 add_assoc_bool_ex (& z_ret , Z_STRVAL_P (z_chan ), Z_STRLEN_P (z_chan ), 1 );
649671 }
650672
@@ -653,10 +675,10 @@ PHP_REDIS_API int redis_unsubscribe_response(INTERNAL_FUNCTION_PARAMETERS,
653675
654676 efree (sctx );
655677
656- if (redis_sock -> subs && !zend_hash_num_elements (redis_sock -> subs )) {
657- zend_hash_destroy (redis_sock -> subs );
658- efree (redis_sock -> subs );
659- redis_sock -> subs = NULL ;
678+ if (redis_sock -> subs [ i ] && !zend_hash_num_elements (redis_sock -> subs [ i ] )) {
679+ zend_hash_destroy (redis_sock -> subs [ i ] );
680+ efree (redis_sock -> subs [ i ] );
681+ redis_sock -> subs [ i ] = NULL ;
660682 }
661683
662684 RETVAL_ZVAL (& z_ret , 0 , 1 );
@@ -3300,6 +3322,8 @@ free_reply_callbacks(RedisSock *redis_sock)
33003322 */
33013323PHP_REDIS_API void redis_free_socket (RedisSock * redis_sock )
33023324{
3325+ int i ;
3326+
33033327 if (redis_sock -> prefix ) {
33043328 zend_string_release (redis_sock -> prefix );
33053329 }
@@ -3315,10 +3339,12 @@ PHP_REDIS_API void redis_free_socket(RedisSock *redis_sock)
33153339 if (redis_sock -> host ) {
33163340 zend_string_release (redis_sock -> host );
33173341 }
3318- if (redis_sock -> subs ) {
3319- zend_hash_destroy (redis_sock -> subs );
3320- efree (redis_sock -> subs );
3321- redis_sock -> subs = NULL ;
3342+ for (i = 0 ; i < REDIS_SUBS_BUCKETS ; ++ i ) {
3343+ if (redis_sock -> subs [i ]) {
3344+ zend_hash_destroy (redis_sock -> subs [i ]);
3345+ efree (redis_sock -> subs [i ]);
3346+ redis_sock -> subs [i ] = NULL ;
3347+ }
33223348 }
33233349 redis_sock_free_auth (redis_sock );
33243350 free_reply_callbacks (redis_sock );
0 commit comments