@@ -63,18 +63,19 @@ extern zend_class_entry *redis_exception_ce;
6363
6464extern int le_redis_pconnect ;
6565
66- static zend_llist *
66+ static ConnectionPool *
6767redis_sock_get_connection_pool (RedisSock * redis_sock TSRMLS_DC )
6868{
6969 zend_string * persistent_id = strpprintf (0 , "phpredis_%s:%d" , ZSTR_VAL (redis_sock -> host ), redis_sock -> port );
7070 zend_resource * le = zend_hash_find_ptr (& EG (persistent_list ), persistent_id );
7171 if (!le ) {
72- zend_llist * list = pecalloc (1 , sizeof (* list ) + sizeof (* le ), 1 );
73- zend_llist_init (list , sizeof (php_stream * ), NULL , 1 );
74- le = (zend_resource * )((char * )list + sizeof (* list ));
72+ ConnectionPool * p = pecalloc (1 , sizeof (* p ) + sizeof (* le ), 1 );
73+ zend_llist_init (& p -> list , sizeof (php_stream * ), NULL , 1 );
74+ le = (zend_resource * )((char * )p + sizeof (* p ));
7575 le -> type = le_redis_pconnect ;
76- le -> ptr = list ;
76+ le -> ptr = p ;
7777 zend_hash_str_update_mem (& EG (persistent_list ), ZSTR_VAL (persistent_id ), ZSTR_LEN (persistent_id ), le , sizeof (* le ));
78+ p -> nb_active = 0 ;
7879 }
7980 zend_string_release (persistent_id );
8081 return le -> ptr ;
@@ -1765,8 +1766,8 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
17651766 zend_string * persistent_id = NULL ;
17661767 char host [1024 ];
17671768 const char * fmtstr = "%s:%d" ;
1768- int host_len , usocket = 0 , err = 0 ;
1769- int tcp_flag = 1 ;
1769+ int host_len , usocket = 0 , err = 0 , tcp_flag = 1 ;
1770+ ConnectionPool * p = NULL ;
17701771#if (PHP_MAJOR_VERSION < 7 )
17711772 char * estr = NULL ;
17721773#else
@@ -1796,16 +1797,23 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
17961797
17971798 if (redis_sock -> persistent ) {
17981799 if (INI_INT ("redis.pconnect.pooling_enabled" )) {
1799- zend_llist * list = redis_sock_get_connection_pool (redis_sock TSRMLS_CC );
1800- if (zend_llist_count (list ) > 0 ) {
1801- redis_sock -> stream = * (php_stream * * )zend_llist_get_last (list );
1802- zend_llist_remove_tail (list );
1800+ p = redis_sock_get_connection_pool (redis_sock TSRMLS_CC );
1801+ if (zend_llist_count (& p -> list ) > 0 ) {
1802+ redis_sock -> stream = * (php_stream * * )zend_llist_get_last (& p -> list );
1803+ zend_llist_remove_tail (& p -> list );
18031804 /* Check socket liveness using 0 second timeout */
18041805 if (php_stream_set_option (redis_sock -> stream , PHP_STREAM_OPTION_CHECK_LIVENESS , 0 , NULL ) == PHP_STREAM_OPTION_RETURN_OK ) {
18051806 redis_sock -> status = REDIS_SOCK_STATUS_CONNECTED ;
18061807 return SUCCESS ;
18071808 }
18081809 php_stream_pclose (redis_sock -> stream );
1810+ p -> nb_active -- ;
1811+ }
1812+
1813+ int limit = INI_INT ("redis.pconnect.connection_limit" );
1814+ if (limit > 0 && p -> nb_active >= limit ) {
1815+ redis_sock_set_err (redis_sock , "Connection limit reached" , sizeof ("Connection limit reached" ) - 1 );
1816+ return FAILURE ;
18091817 }
18101818
18111819 gettimeofday (& tv , NULL );
@@ -1847,6 +1855,8 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
18471855 return FAILURE ;
18481856 }
18491857
1858+ if (p ) p -> nb_active ++ ;
1859+
18501860 /* Attempt to set TCP_NODELAY/TCP_KEEPALIVE if we're not using a unix socket. */
18511861 if (!usocket ) {
18521862 php_netstream_data_t * sock = (php_netstream_data_t * )redis_sock -> stream -> abstract ;
@@ -1902,11 +1912,15 @@ redis_sock_disconnect(RedisSock *redis_sock, int force TSRMLS_DC)
19021912 return FAILURE ;
19031913 } else if (redis_sock -> stream ) {
19041914 if (redis_sock -> persistent ) {
1915+ ConnectionPool * p = NULL ;
1916+ if (INI_INT ("redis.pconnect.pooling_enabled" )) {
1917+ p = redis_sock_get_connection_pool (redis_sock TSRMLS_CC );
1918+ }
19051919 if (force ) {
19061920 php_stream_pclose (redis_sock -> stream );
1907- } else if (INI_INT ( "redis.pconnect.pooling_enabled" )) {
1908- zend_llist * list = redis_sock_get_connection_pool ( redis_sock TSRMLS_CC );
1909- zend_llist_prepend_element (list , & redis_sock -> stream );
1921+ if (p ) p -> nb_active -- ;
1922+ } else if ( p ) {
1923+ zend_llist_prepend_element (& p -> list , & redis_sock -> stream );
19101924 }
19111925 } else {
19121926 php_stream_close (redis_sock -> stream );
0 commit comments