Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpredis/phpredis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavlo Yatsukhnenko <yatsukhnenko@gmail.com>2019-02-22 23:25:15 +0300
committermichael-grunder <michael.grunder@gmail.com>2019-03-19 23:35:41 +0300
commitb826234556be01c2cf9494be9b489bc2443c57f5 (patch)
tree0d5e865d02575bc0295ca93f9cc10e1253ce348f /library.c
parentc56ffc51b38d27d16760be0d778f50ff5d424b5d (diff)
Connection limit for pool.
Diffstat (limited to 'library.c')
-rw-r--r--library.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/library.c b/library.c
index 36d34d9f..61703208 100644
--- a/library.c
+++ b/library.c
@@ -45,18 +45,19 @@ extern zend_class_entry *redis_exception_ce;
extern int le_redis_pconnect;
-static zend_llist *
+static ConnectionPool *
redis_sock_get_connection_pool(RedisSock *redis_sock TSRMLS_DC)
{
zend_string *persistent_id = strpprintf(0, "phpredis_%s:%d", ZSTR_VAL(redis_sock->host), redis_sock->port);
zend_resource *le = zend_hash_find_ptr(&EG(persistent_list), persistent_id);
if (!le) {
- zend_llist *list = pecalloc(1, sizeof(*list) + sizeof(*le), 1);
- zend_llist_init(list, sizeof(php_stream *), NULL, 1);
- le = (zend_resource *)((char *)list + sizeof(*list));
+ ConnectionPool *p = pecalloc(1, sizeof(*p) + sizeof(*le), 1);
+ zend_llist_init(&p->list, sizeof(php_stream *), NULL, 1);
+ le = (zend_resource *)((char *)p + sizeof(*p));
le->type = le_redis_pconnect;
- le->ptr = list;
+ le->ptr = p;
zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(persistent_id), ZSTR_LEN(persistent_id), le, sizeof(*le));
+ p->nb_active = 0;
}
zend_string_release(persistent_id);
return le->ptr;
@@ -1691,8 +1692,11 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
zend_string *persistent_id = NULL;
char host[1024];
const char *fmtstr = "%s:%d";
- int host_len, usocket = 0, err = 0;
- int tcp_flag = 1;
+ int host_len, usocket = 0, err = 0, tcp_flag = 1;
+ ConnectionPool *p = NULL;
+#if (PHP_MAJOR_VERSION < 7)
+ char *estr = NULL;
+#else
zend_string *estr = NULL;
if (redis_sock->stream != NULL) {
@@ -1718,16 +1722,23 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
if (redis_sock->persistent) {
if (INI_INT("redis.pconnect.pooling_enabled")) {
- zend_llist *list = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
- if (zend_llist_count(list) > 0) {
- redis_sock->stream = *(php_stream **)zend_llist_get_last(list);
- zend_llist_remove_tail(list);
+ p = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
+ if (zend_llist_count(&p->list) > 0) {
+ redis_sock->stream = *(php_stream **)zend_llist_get_last(&p->list);
+ zend_llist_remove_tail(&p->list);
/* Check socket liveness using 0 second timeout */
if (php_stream_set_option(redis_sock->stream, PHP_STREAM_OPTION_CHECK_LIVENESS, 0, NULL) == PHP_STREAM_OPTION_RETURN_OK) {
redis_sock->status = REDIS_SOCK_STATUS_CONNECTED;
return SUCCESS;
}
php_stream_pclose(redis_sock->stream);
+ p->nb_active--;
+ }
+
+ int limit = INI_INT("redis.pconnect.connection_limit");
+ if (limit > 0 && p->nb_active >= limit) {
+ redis_sock_set_err(redis_sock, "Connection limit reached", sizeof("Connection limit reached") - 1);
+ return FAILURE;
}
gettimeofday(&tv, NULL);
@@ -1764,6 +1775,8 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
return FAILURE;
}
+ if (p) p->nb_active++;
+
/* Attempt to set TCP_NODELAY/TCP_KEEPALIVE if we're not using a unix socket. */
if (!usocket) {
php_netstream_data_t *sock = (php_netstream_data_t*)redis_sock->stream->abstract;
@@ -1819,11 +1832,15 @@ redis_sock_disconnect(RedisSock *redis_sock, int force TSRMLS_DC)
return FAILURE;
} else if (redis_sock->stream) {
if (redis_sock->persistent) {
+ ConnectionPool *p = NULL;
+ if (INI_INT("redis.pconnect.pooling_enabled")) {
+ p = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
+ }
if (force) {
php_stream_pclose(redis_sock->stream);
- } else if (INI_INT("redis.pconnect.pooling_enabled")) {
- zend_llist *list = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
- zend_llist_prepend_element(list, &redis_sock->stream);
+ if (p) p->nb_active--;
+ } else if (p) {
+ zend_llist_prepend_element(&p->list, &redis_sock->stream);
}
} else {
php_stream_close(redis_sock->stream);