summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/mysqli/mysqli.c53
-rw-r--r--ext/mysqli/mysqli_api.c7
-rw-r--r--ext/mysqli/mysqli_nonapi.c57
-rw-r--r--ext/mysqli/php_mysqli_structs.h4
4 files changed, 36 insertions, 85 deletions
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 00e8ac8efd..5551063082 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -70,50 +70,25 @@ typedef struct _mysqli_prop_handler {
static int le_pmysqli;
-static int php_mysqli_persistent_on_rshut(zend_rsrc_list_entry *le TSRMLS_DC)
-{
- if (le->type == le_pmysqli) {
- mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
- HashPosition pos;
- MYSQL **mysql;
- ulong idx;
- dtor_func_t pDestructor = plist->used_links.pDestructor;
- plist->used_links.pDestructor = NULL; /* Don't call pDestructor now */
-
- zend_hash_internal_pointer_reset_ex(&plist->used_links, &pos);
- while (SUCCESS == zend_hash_get_current_data_ex(&plist->used_links, (void **)&mysql, &pos)) {
- zend_hash_get_current_key_ex(&plist->used_links, NULL, NULL, &idx, FALSE, &pos);
- /* Make it free */
- zend_hash_next_index_insert(&plist->free_links, mysql, sizeof(MYSQL *), NULL);
- /* First move forward */
- zend_hash_move_forward_ex(&plist->used_links, &pos);
- /* The delete, because del will free memory, but we need it's ->nextItem */
- zend_hash_index_del(&plist->used_links, idx);
- }
-
- /* restore pDestructor, which should be php_mysqli_dtor_p_elements() */
- plist->used_links.pDestructor = pDestructor;
- }
- return ZEND_HASH_APPLY_KEEP;
-}
/* Destructor for mysqli entries in free_links/used_links */
void php_mysqli_dtor_p_elements(void *data)
{
- MYSQL **mysql = (MYSQL **) data;
+ MYSQL *mysql = (MYSQL *) data;
TSRMLS_FETCH();
#if defined(HAVE_MYSQLND)
- mysqlnd_end_psession(*mysql);
+ mysqlnd_end_psession(mysql);
#endif
- mysqli_close(*mysql, MYSQLI_CLOSE_IMPLICIT);
+ mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT);
}
+/* le_pmysqli dtor*/
ZEND_RSRC_DTOR_FUNC(php_mysqli_dtor)
{
if (rsrc->ptr) {
mysqli_plist_entry *plist = (mysqli_plist_entry *) rsrc->ptr;
- zend_hash_destroy(&plist->free_links);
- zend_hash_destroy(&plist->used_links);
+ zend_ptr_stack_clean(&plist->free_links, php_mysqli_dtor_p_elements, 0);
+ zend_ptr_stack_destroy(&plist->free_links);
free(plist);
}
}
@@ -222,6 +197,8 @@ static void mysqli_objects_free_storage(void *object TSRMLS_DC)
}
/* }}} */
+/* mysqli_link_free_storage partly doubles the work of PHP_FUNCTION(mysqli_close) */
+
/* {{{ mysqli_link_free_storage
*/
static void mysqli_link_free_storage(void *object TSRMLS_DC)
@@ -235,6 +212,19 @@ static void mysqli_link_free_storage(void *object TSRMLS_DC)
if (mysql->mysql) {
if (!mysql->persistent) {
mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
+ } else {
+ zend_rsrc_list_entry *le;
+ if (zend_hash_find(&EG(persistent_list), mysql->hash_key, strlen(mysql->hash_key) + 1, (void **)&le) == SUCCESS) {
+ if (Z_TYPE_P(le) == php_le_pmysqli()) {
+ mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
+
+ zend_ptr_stack_push(&plist->free_links, mysql->mysql);
+
+ MyG(num_links)--;
+ MyG(num_active_persistent)--;
+ MyG(num_inactive_persistent)++;
+ }
+ }
}
}
php_clear_mysql(mysql);
@@ -854,7 +844,6 @@ PHP_RINIT_FUNCTION(mysqli)
PHP_RSHUTDOWN_FUNCTION(mysqli)
{
/* check persistent connections, move used to free */
- zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysqli_persistent_on_rshut TSRMLS_CC);
#if !defined(HAVE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
mysql_thread_end();
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index b4948acdbb..d857706a4e 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -563,13 +563,8 @@ PHP_FUNCTION(mysqli_close)
if (zend_hash_find(&EG(persistent_list), mysql->hash_key, strlen(mysql->hash_key) + 1, (void **)&le) == SUCCESS) {
if (Z_TYPE_P(le) == php_le_pmysqli()) {
mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
- dtor_func_t pDestructor = plist->used_links.pDestructor;
+ zend_ptr_stack_push(&plist->free_links, mysql->mysql);
- plist->used_links.pDestructor = NULL; /* Don't call pDestructor now */
- zend_hash_index_del(&plist->used_links, mysql->hash_index);
- plist->used_links.pDestructor = pDestructor; /* Restore the destructor */
-
- zend_hash_next_index_insert(&plist->free_links, &mysql->mysql, sizeof(MYSQL *), NULL);
MyG(num_links)--;
MyG(num_active_persistent)--;
MyG(num_inactive_persistent)++;
diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c
index 918594ad76..87b33f4389 100644
--- a/ext/mysqli/mysqli_nonapi.c
+++ b/ext/mysqli/mysqli_nonapi.c
@@ -109,37 +109,18 @@ PHP_FUNCTION(mysqli_connect)
port, SAFE_STR(username), SAFE_STR(dbname),
SAFE_STR(passwd));
+ mysql->hash_key = hash_key;
+
/* check if we can reuse exisiting connection ... */
if (zend_hash_find(&EG(persistent_list), hash_key, hash_len + 1, (void **)&le) == SUCCESS) {
if (Z_TYPE_P(le) == php_le_pmysqli()) {
plist = (mysqli_plist_entry *) le->ptr;
do {
- if (zend_hash_num_elements(&plist->free_links)) {
- HashPosition pos;
- MYSQL **free_mysql;
- ulong idx;
- dtor_func_t pDestructor = plist->free_links.pDestructor;
-
- zend_hash_internal_pointer_reset_ex(&plist->free_links, &pos);
- if (SUCCESS != zend_hash_get_current_data_ex(&plist->free_links,
- (void **)&free_mysql, &pos)) {
- break;
- }
- if (HASH_KEY_IS_LONG != zend_hash_get_current_key_ex(&plist->free_links, NULL,
- NULL, &idx, FALSE, &pos)) {
- break;
- }
- plist->free_links.pDestructor = NULL; /* Don't call pDestructor now */
- if (SUCCESS != zend_hash_index_del(&plist->free_links, idx)) {
- plist->used_links.pDestructor = pDestructor; /* Restore the destructor */
- break;
- }
- plist->free_links.pDestructor = pDestructor; /* Restore the destructor */
- mysql->mysql = *free_mysql;
+ if (zend_ptr_stack_num_elements(&plist->free_links)) {
+ mysql->mysql = zend_ptr_stack_pop(&plist->free_links);
MyG(num_inactive_persistent)--;
- MyG(num_active_persistent)++;
/* reset variables */
/* todo: option for ping or change_user */
#if G0
@@ -150,16 +131,14 @@ PHP_FUNCTION(mysqli_connect)
#ifdef HAVE_MYSQLND
mysqlnd_restart_psession(mysql->mysql);
#endif
- idx = zend_hash_next_free_element(&plist->used_links);
- if (SUCCESS != zend_hash_next_index_insert(&plist->used_links, &free_mysql,
- sizeof(MYSQL *), NULL)) {
- php_mysqli_dtor_p_elements(free_mysql);
- MyG(num_links)--;
- break;
- }
- mysql->hash_index = idx;
- mysql->hash_key = hash_key;
+ MyG(num_active_persistent)++;
goto end;
+ } else {
+#if defined(HAVE_MYSQLND)
+ mysqlnd_end_psession(mysql->mysql);
+#endif
+ mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
+ mysql->mysql = NULL;
}
}
} while (0);
@@ -169,8 +148,7 @@ PHP_FUNCTION(mysqli_connect)
le.type = php_le_pmysqli();
le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry));
- zend_hash_init(&plist->free_links, MAX(2, MyG(max_persistent)), NULL, php_mysqli_dtor_p_elements, 1);
- zend_hash_init(&plist->used_links, MAX(2, MyG(max_persistent)), NULL, php_mysqli_dtor_p_elements, 1);
+ zend_ptr_stack_init(&plist->free_links, 1);
zend_hash_update(&EG(persistent_list), hash_key, hash_len + 1, (void *)&le, sizeof(le), NULL);
}
}
@@ -244,18 +222,9 @@ end:
/* store persistent connection */
if (persistent && new_connection) {
- /* save persistent connection */
- ulong hash_index = zend_hash_next_free_element(&plist->used_links);
- if (SUCCESS != zend_hash_next_index_insert(&plist->used_links, &mysql->mysql,
- sizeof(MYSQL *), NULL)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't store persistent connection");
- } else {
- mysql->hash_index = hash_index;
- }
MyG(num_active_persistent)++;
}
- mysql->hash_key = hash_key;
MyG(num_links)++;
#if !defined(HAVE_MYSQLND)
@@ -274,7 +243,7 @@ end:
err:
efree(mysql);
- if (persistent) {
+ if (hash_key) {
efree(hash_key);
}
RETVAL_FALSE;
diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h
index 5ded00066f..b09ac92e5f 100644
--- a/ext/mysqli/php_mysqli_structs.h
+++ b/ext/mysqli/php_mysqli_structs.h
@@ -91,7 +91,6 @@ typedef struct {
zval *li_read;
php_stream *li_stream;
zend_bool persistent;
- unsigned long hash_index; /* Used when persistent, hold the index in plist->used_links */
unsigned int multi_query;
} MY_MYSQL;
@@ -136,8 +135,7 @@ typedef struct {
#endif
typedef struct {
- HashTable free_links;
- HashTable used_links;
+ zend_ptr_stack free_links;
} mysqli_plist_entry;
#ifdef PHP_WIN32