Author: ahristov
Date: 2007-02-27 13:20:18 +0100 (Tue, 27 Feb 2007)
New Revision: 73
Modified:
trunk/ext/mysqli/mysqlnd/mysqlnd.c
trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
Log:
Fix a bug in mysqlnd_prepare(), statements with no result
sets do not send EOF of metadata, no metadata sent at all.
Bring balance back to the universe. mysqlndext is a bit different
in the object handling than mysqli, it does not put another layer
on top of MYSQLND, MYSQLND_RES, MYSQLND_STMT, thus it can clean
easily. However, mysqli have MY_MYSQL, MY_STMT and so on, which
make things complicated. The real problem was that mysqlnd_kill()
closes the connection but the connection handle should stay alive,
and as the connection reference counter wasn't increased in the
stmt constructor, then mysqlnd_stmt_close() was freeing prematurely
the connection, but in the mysqli world, the resource destructor will
take care of it, not to leak.
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-02-27 12:06:18 UTC (rev 72)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd.c 2007-02-27 12:20:18 UTC (rev 73)
@@ -1701,6 +1701,9 @@
_mysqlnd_close(MYSQLND *conn TSRMLS_DC)
{
enum_func_status ret;
+
+
+
switch (conn->state) {
case CONN_READY:
ret = mysqlnd_simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST,
@@ -1727,9 +1730,15 @@
*/
break;
}
+ /*
+ We hold one reference, and every other object which needs the
+ connection does increase it by 1.
+ */
conn->state = CONN_QUIT_SENT;
- conn->m->free_contents(conn TSRMLS_CC);
- conn->m->dtor(conn TSRMLS_CC);
+ if (!--conn->references) {
+ conn->m->free_contents(conn TSRMLS_CC);
+ conn->m->dtor(conn TSRMLS_CC);
+ }
return ret;
}
/* }}} */
@@ -2266,6 +2275,7 @@
ret->persistent = persistent;
ret->m = & mysqlnd_connection_methods;
+ ret->references = 1;
return ret;
}
Modified: trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c
===================================================================
--- trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c 2007-02-27 12:06:18 UTC (rev 72)
+++ trunk/ext/mysqli/mysqlnd/mysqlnd_ps.c 2007-02-27 12:20:18 UTC (rev 73)
@@ -247,7 +247,6 @@
static enum_func_status
_mysqlnd_stmt_prepare(MYSQLND_STMT * const stmt, const char * const query, unsigned int
query_len TSRMLS_DC)
{
- enum_func_status ret;
MYSQLND_RES *result = NULL;
SET_ERROR_AFF_ROWS(stmt);
@@ -266,7 +265,7 @@
return FAIL;
}
- if (stmt->param_count && FAIL == (ret = mysqlnd_stmt_skip_metadata(stmt
TSRMLS_CC))) {
+ if (stmt->param_count && FAIL == mysqlnd_stmt_skip_metadata(stmt TSRMLS_CC))
{
memset(stmt, 0, sizeof(MYSQLND_STMT));
stmt->state = MYSQLND_STMT_INITTED;
return FAIL;
@@ -290,9 +289,9 @@
result->conn = stmt->conn;
stmt->result = result;
+ return mysqlnd_stmt_prepare_read_eof(stmt TSRMLS_CC);
}
-
- return mysqlnd_stmt_prepare_read_eof(stmt TSRMLS_CC);
+ return PASS;
}
/* }}} */
@@ -1053,15 +1052,6 @@
stmt->cmd_buffer.buffer = NULL;
}
- /*
- result->conn is an address if this is an unbuffered query.
- In this case, decrement the reference counter in the connection
- object and if needed free the latter. If quit_sent is no
- */
- if (stmt->conn) {
- --stmt->conn->references;
- }
-#if A0
if (stmt->conn && (!(--stmt->conn->references)) &&
stmt->conn->state == CONN_QUIT_SENT) {
/*
No multithreading issues as we don't share the connection :)
@@ -1071,7 +1061,6 @@
stmt->conn->m->dtor(stmt->conn TSRMLS_CC);
stmt->conn = NULL;
}
-#endif
}
/* }}} */
| Thread |
|---|
| • PHP mysqlnd svn commit: r73 - trunk/ext/mysqli/mysqlnd | ahristov | 27 Feb |