Sync with bzr

This commit is contained in:
Andrey Hristov 2008-07-15 13:12:27 +00:00
parent 6cf169b16c
commit 73dfa53ca8
6 changed files with 94 additions and 62 deletions

View file

@ -514,6 +514,18 @@ PHP_RINIT_FUNCTION(mysql)
} }
/* }}} */ /* }}} */
#ifdef MYSQL_USE_MYSQLND
static int php_mysql_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
{
if (le->type == le_plink) {
mysqlnd_end_psession(((php_mysql_conn *) le->ptr)->conn);
}
return ZEND_HASH_APPLY_KEEP;
} /* }}} */
#endif
/* {{{ PHP_RSHUTDOWN_FUNCTION /* {{{ PHP_RSHUTDOWN_FUNCTION
*/ */
PHP_RSHUTDOWN_FUNCTION(mysql) PHP_RSHUTDOWN_FUNCTION(mysql)
@ -531,7 +543,9 @@ PHP_RSHUTDOWN_FUNCTION(mysql)
if (MySG(connect_error)!=NULL) { if (MySG(connect_error)!=NULL) {
efree(MySG(connect_error)); efree(MySG(connect_error));
} }
#ifdef MYSQL_USE_MYSQLND #ifdef MYSQL_USE_MYSQLND
zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysql_persistent_helper TSRMLS_CC);
mysqlnd_palloc_rshutdown(MySG(mysqlnd_thd_zval_cache)); mysqlnd_palloc_rshutdown(MySG(mysqlnd_thd_zval_cache));
#endif #endif
@ -572,6 +586,7 @@ PHP_MINFO_FUNCTION(mysql)
} }
} }
#endif #endif
php_info_print_table_end(); php_info_print_table_end();
DISPLAY_INI_ENTRIES(); DISPLAY_INI_ENTRIES();
@ -644,7 +659,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
passwd = MySG(default_password); passwd = MySG(default_password);
/* mysql_pconnect does not support new_link parameter */ /* mysql_pconnect does not support new_link parameter */
if (persistent) { if (persistent) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s&s&s&l", &host_and_port, &host_len, UG(utf8_conv), if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s&s&s&l", &host_and_port, &host_len, UG(utf8_conv),
&user, &user_len, UG(utf8_conv), &passwd, &passwd_len, UG(utf8_conv), &user, &user_len, UG(utf8_conv), &passwd, &passwd_len, UG(utf8_conv),
&client_flags)==FAILURE) { &client_flags)==FAILURE) {
@ -663,6 +678,8 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
client_flags ^= CLIENT_LOCAL_FILES; client_flags ^= CLIENT_LOCAL_FILES;
} }
client_flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */
hashed_details_length = spprintf(&hashed_details, 0, "mysql_%s_%s_%s_%ld", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd), client_flags); hashed_details_length = spprintf(&hashed_details, 0, "mysql_%s_%s_%s_%ld", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd), client_flags);
} }
@ -714,7 +731,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
/* create the link */ /* create the link */
mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn)); mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
mysql->active_result_id = 0; mysql->active_result_id = 0;
mysql->multi_query = 1; mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
#ifndef MYSQL_USE_MYSQLND #ifndef MYSQL_USE_MYSQLND
mysql->conn = mysql_init(NULL); mysql->conn = mysql_init(NULL);
#else #else
@ -724,8 +741,9 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
mysql_options(mysql->conn, MYSQL_SET_CHARSET_NAME, "utf8"); mysql_options(mysql->conn, MYSQL_SET_CHARSET_NAME, "utf8");
} }
if (connect_timeout != -1) if (connect_timeout != -1) {
mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout); mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
}
#ifndef MYSQL_USE_MYSQLND #ifndef MYSQL_USE_MYSQLND
if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
#else #else
@ -778,6 +796,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
} }
mysql = (php_mysql_conn *) le->ptr; mysql = (php_mysql_conn *) le->ptr;
mysql->active_result_id = 0; mysql->active_result_id = 0;
mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
/* ensure that the link did not die */ /* ensure that the link did not die */
if (mysql_ping(mysql->conn)) { if (mysql_ping(mysql->conn)) {
if (mysql_errno(mysql->conn) == 2006) { if (mysql_errno(mysql->conn) == 2006) {

View file

@ -94,12 +94,8 @@ static int le_pmysqli;
/* Destructor for mysqli entries in free_links/used_links */ /* Destructor for mysqli entries in free_links/used_links */
void php_mysqli_dtor_p_elements(void *data) void php_mysqli_dtor_p_elements(void *data)
{ {
MYSQL *mysql = (MYSQL *) data;
#if defined(MYSQLI_USE_MYSQLND)
TSRMLS_FETCH(); TSRMLS_FETCH();
MYSQL *mysql = (MYSQL *) data;
mysqlnd_end_psession(mysql);
#endif
mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT); mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT);
} }
@ -903,6 +899,12 @@ PHP_MINIT_FUNCTION(mysqli)
#endif #endif
#endif #endif
REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_CS | CONST_PERSISTENT);
#ifdef SERVER_QUERY_WAS_SLOW
REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_CS | CONST_PERSISTENT);
#endif
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */
@ -962,6 +964,26 @@ PHP_RINIT_FUNCTION(mysqli)
} }
/* }}} */ /* }}} */
#ifdef MYSQLI_USE_MYSQLND
static void php_mysqli_persistent_helper_for_every(void *p)
{
TSRMLS_FETCH();
mysqlnd_end_psession((MYSQLND *) p);
} /* }}} */
static int php_mysqli_persistent_helper_once(zend_rsrc_list_entry *le TSRMLS_DC)
{
if (le->type == php_le_pmysqli()) {
mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
zend_ptr_stack_apply(&plist->free_links, php_mysqli_persistent_helper_for_every);
}
return ZEND_HASH_APPLY_KEEP;
} /* }}} */
#endif
/* {{{ PHP_RSHUTDOWN_FUNCTION /* {{{ PHP_RSHUTDOWN_FUNCTION
*/ */
PHP_RSHUTDOWN_FUNCTION(mysqli) PHP_RSHUTDOWN_FUNCTION(mysqli)
@ -975,6 +997,7 @@ PHP_RSHUTDOWN_FUNCTION(mysqli)
efree(MyG(error_msg)); efree(MyG(error_msg));
} }
#ifdef MYSQLI_USE_MYSQLND #ifdef MYSQLI_USE_MYSQLND
zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysqli_persistent_helper_once TSRMLS_CC);
mysqlnd_palloc_rshutdown(MyG(mysqlnd_thd_zval_cache)); mysqlnd_palloc_rshutdown(MyG(mysqlnd_thd_zval_cache));
#endif #endif
return SUCCESS; return SUCCESS;

View file

@ -451,7 +451,11 @@ PHPAPI void _mysqlnd_restart_psession(MYSQLND *conn, MYSQLND_THD_ZVAL_PCACHE *ca
mnd_pefree(conn->last_message, conn->persistent); mnd_pefree(conn->last_message, conn->persistent);
conn->last_message = NULL; conn->last_message = NULL;
} }
conn->zval_cache = cache; /*
The thd zval cache is always freed on request shutdown, so this has happened already.
Don't touch the old value! Get new reference
*/
conn->zval_cache = mysqlnd_palloc_get_thd_cache_reference(cache);
DBG_VOID_RETURN; DBG_VOID_RETURN;
} }
/* }}} */ /* }}} */
@ -461,16 +465,8 @@ PHPAPI void _mysqlnd_restart_psession(MYSQLND *conn, MYSQLND_THD_ZVAL_PCACHE *ca
PHPAPI void _mysqlnd_end_psession(MYSQLND *conn TSRMLS_DC) PHPAPI void _mysqlnd_end_psession(MYSQLND *conn TSRMLS_DC)
{ {
DBG_ENTER("_mysqlnd_end_psession"); DBG_ENTER("_mysqlnd_end_psession");
/* /* The thd zval cache is always freed on request shutdown, so this has happened already */
BEWARE!!!! This will have a problem with a query cache. mysqlnd_palloc_free_thd_cache_reference(&conn->zval_cache);
We need to move the data out of the zval cache before we end the psession.
Or we will use nirvana pointers!!
*/
if (conn->zval_cache) {
DBG_INF("Freeing zval cache reference");
mysqlnd_palloc_free_thd_cache_reference(&conn->zval_cache);
conn->zval_cache = NULL;
}
DBG_VOID_RETURN; DBG_VOID_RETURN;
} }
/* }}} */ /* }}} */

View file

@ -172,7 +172,7 @@ MYSQLND_THD_ZVAL_PCACHE* _mysqlnd_palloc_get_thd_cache_reference(MYSQLND_THD_ZVA
if (cache) { if (cache) {
++cache->references; ++cache->references;
DBG_INF_FMT("cache=%p new_refc=%d gc_list.canary1=%p gc_list.canary2=%p", DBG_INF_FMT("cache=%p new_refc=%d gc_list.canary1=%p gc_list.canary2=%p",
*cache, cache->references, cache->gc_list.canary1, cache->gc_list.canary2); cache, cache->references, cache->gc_list.canary1, cache->gc_list.canary2);
mysqlnd_palloc_get_cache_reference(cache->parent); mysqlnd_palloc_get_cache_reference(cache->parent);
} }
DBG_RETURN(cache); DBG_RETURN(cache);
@ -189,13 +189,43 @@ MYSQLND_THD_ZVAL_PCACHE* _mysqlnd_palloc_get_thd_cache_reference(MYSQLND_THD_ZVA
constructor of the cache. constructor of the cache.
*/ */
static static
void mysqlnd_palloc_free_thd_cache(MYSQLND_THD_ZVAL_PCACHE *cache TSRMLS_DC) void mysqlnd_palloc_free_thd_cache(MYSQLND_THD_ZVAL_PCACHE *thd_cache TSRMLS_DC)
{ {
DBG_ENTER("mysqlnd_palloc_free_thd_cache"); MYSQLND_ZVAL_PCACHE *global_cache;
DBG_INF_FMT("cache=%p", cache); mysqlnd_zval **p;
mnd_free(cache->gc_list.ptr_line); DBG_ENTER("mysqlnd_palloc_free_thd_cache");
mnd_free(cache); DBG_INF_FMT("thd_cache=%p", thd_cache);
if ((global_cache = thd_cache->parent)) {
/*
Keep in mind that for pthreads pthread_equal() should be used to be
fully standard compliant. However, the PHP code all-around, incl. the
the Zend MM uses direct comparison.
*/
p = thd_cache->gc_list.ptr_line;
while (p < thd_cache->gc_list.last_added) {
zval_dtor(&(*p)->zv);
p++;
}
p = thd_cache->gc_list.ptr_line;
LOCK_PCACHE(global_cache);
while (p < thd_cache->gc_list.last_added) {
(*p)->point_type = MYSQLND_POINTS_FREE;
*(--global_cache->free_list.last_added) = *p;
++global_cache->free_items;
#ifdef ZTS
memset(&((*p)->thread_id), 0, sizeof(THREAD_T));
#endif
p++;
}
UNLOCK_PCACHE(global_cache);
}
mnd_free(thd_cache->gc_list.ptr_line);
mnd_free(thd_cache);
DBG_VOID_RETURN; DBG_VOID_RETURN;
} }
@ -508,43 +538,9 @@ PHPAPI MYSQLND_THD_ZVAL_PCACHE * _mysqlnd_palloc_rinit(MYSQLND_ZVAL_PCACHE * cac
/* {{{ _mysqlnd_palloc_rshutdown */ /* {{{ _mysqlnd_palloc_rshutdown */
PHPAPI void _mysqlnd_palloc_rshutdown(MYSQLND_THD_ZVAL_PCACHE * thd_cache TSRMLS_DC) PHPAPI void _mysqlnd_palloc_rshutdown(MYSQLND_THD_ZVAL_PCACHE * thd_cache TSRMLS_DC)
{ {
MYSQLND_ZVAL_PCACHE *cache;
mysqlnd_zval **p;
DBG_ENTER("_mysqlnd_palloc_rshutdown"); DBG_ENTER("_mysqlnd_palloc_rshutdown");
DBG_INF_FMT("cache=%p", thd_cache); DBG_INF_FMT("cache=%p", thd_cache);
if (!thd_cache || !(cache = thd_cache->parent)) {
return;
}
/*
Keep in mind that for pthreads pthread_equal() should be used to be
fully standard compliant. However, the PHP code all-around, incl. the
the Zend MM uses direct comparison.
*/
p = thd_cache->gc_list.ptr_line;
while (p < thd_cache->gc_list.last_added) {
zval_dtor(&(*p)->zv);
p++;
}
p = thd_cache->gc_list.ptr_line;
LOCK_PCACHE(cache);
while (p < thd_cache->gc_list.last_added) {
(*p)->point_type = MYSQLND_POINTS_FREE;
*(--cache->free_list.last_added) = *p;
++cache->free_items;
#ifdef ZTS
memset(&((*p)->thread_id), 0, sizeof(THREAD_T));
#endif
p++;
}
UNLOCK_PCACHE(cache);
mysqlnd_palloc_free_thd_cache_reference(&thd_cache); mysqlnd_palloc_free_thd_cache_reference(&thd_cache);
DBG_VOID_RETURN; DBG_VOID_RETURN;
} }
/* }}} */ /* }}} */

View file

@ -582,7 +582,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const stmt TSRMLS_DC)
SET_ERROR_AFF_ROWS(stmt); SET_ERROR_AFF_ROWS(stmt);
SET_ERROR_AFF_ROWS(stmt->conn); SET_ERROR_AFF_ROWS(stmt->conn);
if (stmt->state > MYSQLND_STMT_PREPARED && stmt->field_count) { if (stmt->result && stmt->state > MYSQLND_STMT_PREPARED && stmt->field_count) {
/* /*
We don need to copy the data from the buffers which we will clean. We don need to copy the data from the buffers which we will clean.
Because it has already been copied. See Because it has already been copied. See

View file

@ -690,8 +690,6 @@ size_t php_mysqlnd_auth_write(void *_packet, MYSQLND *conn TSRMLS_DC)
packet->client_flags ^= CLIENT_LOCAL_FILES; packet->client_flags ^= CLIENT_LOCAL_FILES;
} }
/* don't allow multi_queries via connect parameter */
packet->client_flags ^= CLIENT_MULTI_STATEMENTS;
int4store(p, packet->client_flags); int4store(p, packet->client_flags);
p+= 4; p+= 4;