]> granicus.if.org Git - php/commitdiff
Sync with bzr
authorAndrey Hristov <andrey@php.net>
Tue, 15 Jul 2008 13:12:27 +0000 (13:12 +0000)
committerAndrey Hristov <andrey@php.net>
Tue, 15 Jul 2008 13:12:27 +0000 (13:12 +0000)
ext/mysql/php_mysql.c
ext/mysqli/mysqli.c
ext/mysqlnd/mysqlnd.c
ext/mysqlnd/mysqlnd_palloc.c
ext/mysqlnd/mysqlnd_ps.c
ext/mysqlnd/mysqlnd_wireprotocol.c

index bb30952b00ed6f6f7a8482ca4030b9c3eabb7e71..d808255e37d5bb148f3aca0da75e766cf8e79581 100644 (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(mysql)
@@ -531,7 +543,9 @@ PHP_RSHUTDOWN_FUNCTION(mysql)
        if (MySG(connect_error)!=NULL) {
                efree(MySG(connect_error));
        }
+
 #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));
 #endif
 
@@ -572,6 +586,7 @@ PHP_MINFO_FUNCTION(mysql)
                }
        }
 #endif
+
        php_info_print_table_end();
 
        DISPLAY_INI_ENTRIES();
@@ -644,7 +659,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                passwd = MySG(default_password);
        
                /* 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),
                                                                        &user, &user_len, UG(utf8_conv), &passwd, &passwd_len, UG(utf8_conv),
                                                                        &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_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);
        }
 
@@ -714,7 +731,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                        /* create the link */
                        mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
                        mysql->active_result_id = 0;
-                       mysql->multi_query = 1;
+                       mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
 #ifndef MYSQL_USE_MYSQLND
                        mysql->conn = mysql_init(NULL);
 #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");
                        }
 
-                       if (connect_timeout != -1)
+                       if (connect_timeout != -1) {
                                mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
+                       }
 #ifndef MYSQL_USE_MYSQLND
                        if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
 #else
@@ -778,6 +796,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                        }
                        mysql = (php_mysql_conn *) le->ptr;
                        mysql->active_result_id = 0;
+                       mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
                        /* ensure that the link did not die */
                        if (mysql_ping(mysql->conn)) {
                                if (mysql_errno(mysql->conn) == 2006) {
index 1fe06770f2bb05673967c2beb0c31fc2ec8393cf..7cfa6714c0bb2dcc719e04edb2ae8ad102d2f7ec 100644 (file)
@@ -94,12 +94,8 @@ static int le_pmysqli;
 /* Destructor for mysqli entries in free_links/used_links */
 void php_mysqli_dtor_p_elements(void *data)
 {
-       MYSQL *mysql = (MYSQL *) data;
-#if defined(MYSQLI_USE_MYSQLND)
        TSRMLS_FETCH();
-
-       mysqlnd_end_psession(mysql);
-#endif
+       MYSQL *mysql = (MYSQL *) data;
        mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT);
 }
 
@@ -903,6 +899,12 @@ PHP_MINIT_FUNCTION(mysqli)
 #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;
 }
 /* }}} */
@@ -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(mysqli)
@@ -975,6 +997,7 @@ PHP_RSHUTDOWN_FUNCTION(mysqli)
                efree(MyG(error_msg));
        }
 #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));
 #endif
        return SUCCESS;
index cd21ebed56d078483a66f2c4b65089fd27cd93b1..fb57ca70f54409bd277b9e890f54abaf86008bf9 100644 (file)
@@ -451,7 +451,11 @@ PHPAPI void _mysqlnd_restart_psession(MYSQLND *conn, MYSQLND_THD_ZVAL_PCACHE *ca
                mnd_pefree(conn->last_message, conn->persistent);
                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;
 }
 /* }}} */
@@ -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)
 {
        DBG_ENTER("_mysqlnd_end_psession");
-       /*
-         BEWARE!!!! This will have a problem with a query 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;
-       }
+       /* The thd zval cache is always freed on request shutdown, so this has happened already */
+       mysqlnd_palloc_free_thd_cache_reference(&conn->zval_cache);
        DBG_VOID_RETURN;
 }
 /* }}} */
index cff217eaaeb949bcfbd07fd9268a85e771b2fe9e..f64dd17ada7a7db931fbca8159e30a702c7632b0 100644 (file)
@@ -172,7 +172,7 @@ MYSQLND_THD_ZVAL_PCACHE* _mysqlnd_palloc_get_thd_cache_reference(MYSQLND_THD_ZVA
        if (cache) {
                ++cache->references;
                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);
        }
        DBG_RETURN(cache);
@@ -189,13 +189,43 @@ MYSQLND_THD_ZVAL_PCACHE* _mysqlnd_palloc_get_thd_cache_reference(MYSQLND_THD_ZVA
   constructor of the cache.
 */
 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)
 {
+       MYSQLND_ZVAL_PCACHE *global_cache;
+       mysqlnd_zval **p;
+
        DBG_ENTER("mysqlnd_palloc_free_thd_cache");
-       DBG_INF_FMT("cache=%p", cache);
+       DBG_INF_FMT("thd_cache=%p", thd_cache);
 
-       mnd_free(cache->gc_list.ptr_line);
-       mnd_free(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;
 }
@@ -508,43 +538,9 @@ PHPAPI MYSQLND_THD_ZVAL_PCACHE * _mysqlnd_palloc_rinit(MYSQLND_ZVAL_PCACHE * cac
 /* {{{ _mysqlnd_palloc_rshutdown */
 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_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);
-
        DBG_VOID_RETURN;
 }
 /* }}} */
index acacee22ef768d071d645ce4ccb01470d1edae2a..30154bfe5461e1133544c2b6bf704d97906acd09 100644 (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->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.
                  Because it has already been copied. See
index 4816a4fb37f591cd2d0c334d3f591437f27fa7de..c59e1b216cbb2ee2a05c3e663f3803055a561ed1 100644 (file)
@@ -690,8 +690,6 @@ size_t php_mysqlnd_auth_write(void *_packet, MYSQLND *conn TSRMLS_DC)
                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);
        p+= 4;