diff options
-rw-r--r-- | ext/mysqli/mysqli.c | 53 | ||||
-rw-r--r-- | ext/mysqli/mysqli_api.c | 7 | ||||
-rw-r--r-- | ext/mysqli/mysqli_nonapi.c | 57 | ||||
-rw-r--r-- | ext/mysqli/php_mysqli_structs.h | 4 |
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 |