- rename mysqlnd.c to mysqlnd_connection.c
This commit is contained in:
Andrey Hristov 2015-11-12 13:04:58 +01:00
parent c24d452f60
commit abc8c00072
4 changed files with 258 additions and 258 deletions

View file

@ -6,10 +6,10 @@ if (PHP_MYSQLND != "no") {
if (CHECK_LIB("ws2_32.lib", "mysqlnd")) {
mysqlnd_source =
"mysqlnd.c " +
"mysqlnd_alloc.c " +
"mysqlnd_auth.c " +
"mysqlnd_block_alloc.c " +
"mysqlnd_connection.c " +
"mysqlnd_charset.c " +
"mysqlnd_commands.c " +
"mysqlnd_debug.c " +

View file

@ -18,7 +18,7 @@ fi
dnl If some extension uses mysqlnd it will get compiled in PHP core
if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes"; then
mysqlnd_ps_sources="mysqlnd_ps.c mysqlnd_ps_codec.c"
mysqlnd_base_sources="mysqlnd.c mysqlnd_alloc.c mysqlnd_charset.c mysqlnd_wireprotocol.c \
mysqlnd_base_sources="mysqlnd_connection.c mysqlnd_alloc.c mysqlnd_charset.c mysqlnd_wireprotocol.c \
mysqlnd_loaddata.c mysqlnd_reverse_api.c mysqlnd_vio.c mysqlnd_protocol_frame_codec.c \
mysqlnd_statistics.c mysqlnd_driver.c mysqlnd_ext_plugin.c mysqlnd_auth.c \
mysqlnd_result.c mysqlnd_result_meta.c mysqlnd_debug.c mysqlnd_commands.c \

View file

@ -224,14 +224,14 @@ PHPAPI zend_ulong mysqlnd_old_escape_string(char * newstr, const char * escapest
/* PS */
#define mysqlnd_stmt_init(conn) ((conn)->data)->m->stmt_init(((conn)->data))
#define mysqlnd_stmt_store_result(stmt) (!mysqlnd_stmt_field_count((stmt)) ? PASS:((stmt)->m->store_result((stmt))? PASS:FAIL))
#define mysqlnd_stmt_get_result(stmt) (stmt)->m->get_result((stmt))
#define mysqlnd_stmt_more_results(stmt) (stmt)->m->more_results((stmt))
#define mysqlnd_stmt_next_result(stmt) (stmt)->m->next_result((stmt))
#define mysqlnd_stmt_data_seek(stmt, row) (stmt)->m->seek_data((stmt), (row))
#define mysqlnd_stmt_prepare(stmt, q, qlen) (stmt)->m->prepare((stmt), (q), (qlen))
#define mysqlnd_stmt_execute(stmt) (stmt)->m->execute((stmt))
#define mysqlnd_stmt_init(conn) ((conn)->data)->m->stmt_init(((conn)->data))
#define mysqlnd_stmt_store_result(stmt) (!mysqlnd_stmt_field_count((stmt)) ? PASS:((stmt)->m->store_result((stmt))? PASS:FAIL))
#define mysqlnd_stmt_get_result(stmt) (stmt)->m->get_result((stmt))
#define mysqlnd_stmt_more_results(stmt) (stmt)->m->more_results((stmt))
#define mysqlnd_stmt_next_result(stmt) (stmt)->m->next_result((stmt))
#define mysqlnd_stmt_data_seek(stmt, row) (stmt)->m->seek_data((stmt), (row))
#define mysqlnd_stmt_prepare(stmt, q, qlen) (stmt)->m->prepare((stmt), (q), (qlen))
#define mysqlnd_stmt_execute(stmt) (stmt)->m->execute((stmt))
#define mysqlnd_stmt_send_long_data(stmt,p,d,l) (stmt)->m->send_long_data((stmt), (p), (d), (l))
#define mysqlnd_stmt_alloc_param_bind(stmt) (stmt)->m->alloc_parameter_bind((stmt))
#define mysqlnd_stmt_free_param_bind(stmt,bind) (stmt)->m->free_parameter_bind((stmt), (bind))
@ -245,10 +245,10 @@ PHPAPI zend_ulong mysqlnd_old_escape_string(char * newstr, const char * escapest
#define mysqlnd_stmt_param_metadata(stmt) (stmt)->m->get_parameter_metadata((stmt))
#define mysqlnd_stmt_result_metadata(stmt) (stmt)->m->get_result_metadata((stmt))
#define mysqlnd_stmt_free_result(stmt) (stmt)->m->free_result((stmt))
#define mysqlnd_stmt_close(stmt, implicit) (stmt)->m->dtor((stmt), (implicit))
#define mysqlnd_stmt_reset(stmt) (stmt)->m->reset((stmt))
#define mysqlnd_stmt_flush(stmt) (stmt)->m->flush((stmt))
#define mysqlnd_stmt_free_result(stmt) (stmt)->m->free_result((stmt))
#define mysqlnd_stmt_close(stmt, implicit) (stmt)->m->dtor((stmt), (implicit))
#define mysqlnd_stmt_reset(stmt) (stmt)->m->reset((stmt))
#define mysqlnd_stmt_flush(stmt) (stmt)->m->flush((stmt))
#define mysqlnd_stmt_attr_get(stmt, attr, value) (stmt)->m->get_attribute((stmt), (attr), (value))
@ -261,8 +261,8 @@ PHPAPI zend_ulong mysqlnd_old_escape_string(char * newstr, const char * escapest
PHPAPI void _mysqlnd_get_client_stats(zval *return_value ZEND_FILE_LINE_DC);
/* double check the class name to avoid naming conflicts when using these: */
#define MYSQLND_METHOD(class, method) php_##class##_##method##_pub
#define MYSQLND_METHOD_PRIVATE(class, method) php_##class##_##method##_priv
#define MYSQLND_METHOD(class, method) mysqlnd_##class##_##method##_pub
#define MYSQLND_METHOD_PRIVATE(class, method) mysqlnd_##class##_##method##_priv
ZEND_BEGIN_MODULE_GLOBALS(mysqlnd)
char * debug; /* The actual string */

View file

@ -830,54 +830,6 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn_handle,
/* }}} */
/* {{{ mysqlnd_connect */
PHPAPI MYSQLND * mysqlnd_connection_connect(MYSQLND * conn_handle,
const char * const host,
const char * const user,
const char * const passwd, unsigned int passwd_len,
const char * const db, unsigned int db_len,
unsigned int port,
const char * const sock_or_pipe,
unsigned int mysql_flags,
unsigned int client_api_flags
)
{
enum_func_status ret = FAIL;
zend_bool self_alloced = FALSE;
MYSQLND_CSTRING hostname = { host, host? strlen(host) : 0 };
MYSQLND_CSTRING username = { user, user? strlen(user) : 0 };
MYSQLND_CSTRING password = { passwd, passwd_len };
MYSQLND_CSTRING database = { db, db_len };
MYSQLND_CSTRING socket_or_pipe = { sock_or_pipe, sock_or_pipe? strlen(sock_or_pipe) : 0 };
DBG_ENTER("mysqlnd_connect");
DBG_INF_FMT("host=%s user=%s db=%s port=%u flags=%u", host? host:"", user? user:"", db? db:"", port, mysql_flags);
if (!conn_handle) {
self_alloced = TRUE;
if (!(conn_handle = mysqlnd_connection_init(client_api_flags, FALSE, NULL))) {
/* OOM */
DBG_RETURN(NULL);
}
}
ret = conn_handle->m->connect(conn_handle, hostname, username, password, database, port, socket_or_pipe, mysql_flags);
if (ret == FAIL) {
if (self_alloced) {
/*
We have alloced, thus there are no references to this
object - we are free to kill it!
*/
conn_handle->m->dtor(conn_handle);
}
DBG_RETURN(NULL);
}
DBG_RETURN(conn_handle);
}
/* }}} */
/* {{{ mysqlnd_conn_data::query */
/*
If conn->error_info->error_no is not zero, then we had an error.
@ -965,198 +917,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn, enum_mys
/* }}} */
#include "php_network.h"
/* {{{ mysqlnd_stream_array_to_fd_set */
MYSQLND ** mysqlnd_stream_array_check_for_readiness(MYSQLND ** conn_array)
{
int cnt = 0;
MYSQLND **p = conn_array, **p_p;
MYSQLND **ret = NULL;
while (*p) {
const enum mysqlnd_connection_state conn_state = GET_CONNECTION_STATE(&((*p)->data->state));
if (conn_state <= CONN_READY || conn_state == CONN_QUIT_SENT) {
cnt++;
}
p++;
}
if (cnt) {
MYSQLND **ret_p = ret = ecalloc(cnt + 1, sizeof(MYSQLND *));
p_p = p = conn_array;
while (*p) {
const enum mysqlnd_connection_state conn_state = GET_CONNECTION_STATE(&((*p)->data->state));
if (conn_state <= CONN_READY || conn_state == CONN_QUIT_SENT) {
*ret_p = *p;
*p = NULL;
ret_p++;
} else {
*p_p = *p;
p_p++;
}
p++;
}
*ret_p = NULL;
}
return ret;
}
/* }}} */
/* {{{ mysqlnd_stream_array_to_fd_set */
static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, php_socket_t * max_fd)
{
php_socket_t this_fd;
php_stream *stream = NULL;
unsigned int cnt = 0;
MYSQLND **p = conn_array;
DBG_ENTER("mysqlnd_stream_array_to_fd_set");
while (*p) {
/* get the fd.
* NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag
* when casting. It is only used here so that the buffered data warning
* is not displayed.
* */
stream = (*p)->data->vio->data->m.get_stream((*p)->data->vio);
DBG_INF_FMT("conn=%llu stream=%p", (*p)->data->thread_id, stream);
if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && ZEND_VALID_SOCKET(this_fd)) {
PHP_SAFE_FD_SET(this_fd, fds);
if (this_fd > *max_fd) {
*max_fd = this_fd;
}
cnt++;
}
p++;
}
DBG_RETURN(cnt ? 1 : 0);
}
/* }}} */
/* {{{ mysqlnd_stream_array_from_fd_set */
static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds)
{
php_socket_t this_fd;
php_stream *stream = NULL;
int ret = 0;
zend_bool disproportion = FALSE;
MYSQLND **fwd = conn_array, **bckwd = conn_array;
DBG_ENTER("mysqlnd_stream_array_from_fd_set");
while (*fwd) {
stream = (*fwd)->data->vio->data->m.get_stream((*fwd)->data->vio);
DBG_INF_FMT("conn=%llu stream=%p", (*fwd)->data->thread_id, stream);
if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && ZEND_VALID_SOCKET(this_fd)) {
if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
if (disproportion) {
*bckwd = *fwd;
}
bckwd++;
fwd++;
ret++;
continue;
}
}
disproportion = TRUE;
fwd++;
}
*bckwd = NULL;/* NULL-terminate the list */
DBG_RETURN(ret);
}
/* }}} */
#ifndef PHP_WIN32
#define php_select(m, r, w, e, t) select(m, r, w, e, t)
#else
#include "win32/select.h"
#endif
/* {{{ mysqlnd_poll */
PHPAPI enum_func_status
mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, int * desc_num)
{
struct timeval tv;
struct timeval *tv_p = NULL;
fd_set rfds, wfds, efds;
php_socket_t max_fd = 0;
int retval, sets = 0;
int set_count, max_set_count = 0;
DBG_ENTER("_mysqlnd_poll");
if (sec < 0 || usec < 0) {
php_error_docref(NULL, E_WARNING, "Negative values passed for sec and/or usec");
DBG_RETURN(FAIL);
}
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
if (r_array != NULL) {
*dont_poll = mysqlnd_stream_array_check_for_readiness(r_array);
set_count = mysqlnd_stream_array_to_fd_set(r_array, &rfds, &max_fd);
if (set_count > max_set_count) {
max_set_count = set_count;
}
sets += set_count;
}
if (e_array != NULL) {
set_count = mysqlnd_stream_array_to_fd_set(e_array, &efds, &max_fd);
if (set_count > max_set_count) {
max_set_count = set_count;
}
sets += set_count;
}
if (!sets) {
php_error_docref(NULL, E_WARNING, *dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
DBG_ERR_FMT(*dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
DBG_RETURN(FAIL);
}
PHP_SAFE_MAX_FD(max_fd, max_set_count);
/* Solaris + BSD do not like microsecond values which are >= 1 sec */
if (usec > 999999) {
tv.tv_sec = sec + (usec / 1000000);
tv.tv_usec = usec % 1000000;
} else {
tv.tv_sec = sec;
tv.tv_usec = usec;
}
tv_p = &tv;
retval = php_select(max_fd + 1, &rfds, &wfds, &efds, tv_p);
if (retval == -1) {
php_error_docref(NULL, E_WARNING, "unable to select [%d]: %s (max_fd=%d)",
errno, strerror(errno), max_fd);
DBG_RETURN(FAIL);
}
if (r_array != NULL) {
mysqlnd_stream_array_from_fd_set(r_array, &rfds);
}
if (e_array != NULL) {
mysqlnd_stream_array_from_fd_set(e_array, &efds);
}
*desc_num = retval;
DBG_RETURN(PASS);
}
/* }}} */
/* {{{ mysqlnd_conn_data::list_method */
MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_conn_data, list_method)(MYSQLND_CONN_DATA * conn, const char * const query, const char * const achtung_wild, const char * const par1)
@ -2209,7 +1969,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,
/* {{{ mysqlnd_conn_data::get_connection_stats */
static void
MYSQLND_METHOD(mysqlnd_conn_data, get_connection_stats)(const MYSQLND_CONN_DATA * const conn,
zval * return_value ZEND_FILE_LINE_DC)
zval * return_value ZEND_FILE_LINE_DC)
{
DBG_ENTER("mysqlnd_conn_data::get_connection_stats");
mysqlnd_fill_stats_hash(conn->stats, mysqlnd_stats_values_names, return_value ZEND_FILE_LINE_CC);
@ -2702,7 +2462,7 @@ MYSQLND_METHOD(mysqlnd_conn, close)(MYSQLND * conn_handle, const enum_connection
*/
ret = conn->m->send_close(conn);
/* do it after free_reference/dtor and we might crash */
/* If we do it after free_reference/dtor then we might crash */
conn->m->local_tx_end(conn, this_func, ret);
conn_handle->m->dtor(conn_handle);
@ -2720,6 +2480,246 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn)
MYSQLND_CLASS_METHODS_END;
#include "php_network.h"
/* {{{ mysqlnd_stream_array_to_fd_set */
MYSQLND ** mysqlnd_stream_array_check_for_readiness(MYSQLND ** conn_array)
{
int cnt = 0;
MYSQLND **p = conn_array, **p_p;
MYSQLND **ret = NULL;
while (*p) {
const enum mysqlnd_connection_state conn_state = GET_CONNECTION_STATE(&((*p)->data->state));
if (conn_state <= CONN_READY || conn_state == CONN_QUIT_SENT) {
cnt++;
}
p++;
}
if (cnt) {
MYSQLND **ret_p = ret = ecalloc(cnt + 1, sizeof(MYSQLND *));
p_p = p = conn_array;
while (*p) {
const enum mysqlnd_connection_state conn_state = GET_CONNECTION_STATE(&((*p)->data->state));
if (conn_state <= CONN_READY || conn_state == CONN_QUIT_SENT) {
*ret_p = *p;
*p = NULL;
ret_p++;
} else {
*p_p = *p;
p_p++;
}
p++;
}
*ret_p = NULL;
}
return ret;
}
/* }}} */
/* {{{ mysqlnd_stream_array_to_fd_set */
static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, php_socket_t * max_fd)
{
php_socket_t this_fd;
php_stream *stream = NULL;
unsigned int cnt = 0;
MYSQLND **p = conn_array;
DBG_ENTER("mysqlnd_stream_array_to_fd_set");
while (*p) {
/* get the fd.
* NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag
* when casting. It is only used here so that the buffered data warning
* is not displayed.
* */
stream = (*p)->data->vio->data->m.get_stream((*p)->data->vio);
DBG_INF_FMT("conn=%llu stream=%p", (*p)->data->thread_id, stream);
if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && ZEND_VALID_SOCKET(this_fd)) {
PHP_SAFE_FD_SET(this_fd, fds);
if (this_fd > *max_fd) {
*max_fd = this_fd;
}
cnt++;
}
p++;
}
DBG_RETURN(cnt ? 1 : 0);
}
/* }}} */
/* {{{ mysqlnd_stream_array_from_fd_set */
static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds)
{
php_socket_t this_fd;
php_stream *stream = NULL;
int ret = 0;
zend_bool disproportion = FALSE;
MYSQLND **fwd = conn_array, **bckwd = conn_array;
DBG_ENTER("mysqlnd_stream_array_from_fd_set");
while (*fwd) {
stream = (*fwd)->data->vio->data->m.get_stream((*fwd)->data->vio);
DBG_INF_FMT("conn=%llu stream=%p", (*fwd)->data->thread_id, stream);
if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && ZEND_VALID_SOCKET(this_fd)) {
if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
if (disproportion) {
*bckwd = *fwd;
}
bckwd++;
fwd++;
ret++;
continue;
}
}
disproportion = TRUE;
fwd++;
}
*bckwd = NULL;/* NULL-terminate the list */
DBG_RETURN(ret);
}
/* }}} */
#ifndef PHP_WIN32
#define php_select(m, r, w, e, t) select(m, r, w, e, t)
#else
#include "win32/select.h"
#endif
/* {{{ mysqlnd_poll */
PHPAPI enum_func_status
mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, int * desc_num)
{
struct timeval tv;
struct timeval *tv_p = NULL;
fd_set rfds, wfds, efds;
php_socket_t max_fd = 0;
int retval, sets = 0;
int set_count, max_set_count = 0;
DBG_ENTER("_mysqlnd_poll");
if (sec < 0 || usec < 0) {
php_error_docref(NULL, E_WARNING, "Negative values passed for sec and/or usec");
DBG_RETURN(FAIL);
}
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
if (r_array != NULL) {
*dont_poll = mysqlnd_stream_array_check_for_readiness(r_array);
set_count = mysqlnd_stream_array_to_fd_set(r_array, &rfds, &max_fd);
if (set_count > max_set_count) {
max_set_count = set_count;
}
sets += set_count;
}
if (e_array != NULL) {
set_count = mysqlnd_stream_array_to_fd_set(e_array, &efds, &max_fd);
if (set_count > max_set_count) {
max_set_count = set_count;
}
sets += set_count;
}
if (!sets) {
php_error_docref(NULL, E_WARNING, *dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
DBG_ERR_FMT(*dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
DBG_RETURN(FAIL);
}
PHP_SAFE_MAX_FD(max_fd, max_set_count);
/* Solaris + BSD do not like microsecond values which are >= 1 sec */
if (usec > 999999) {
tv.tv_sec = sec + (usec / 1000000);
tv.tv_usec = usec % 1000000;
} else {
tv.tv_sec = sec;
tv.tv_usec = usec;
}
tv_p = &tv;
retval = php_select(max_fd + 1, &rfds, &wfds, &efds, tv_p);
if (retval == -1) {
php_error_docref(NULL, E_WARNING, "unable to select [%d]: %s (max_fd=%d)",
errno, strerror(errno), max_fd);
DBG_RETURN(FAIL);
}
if (r_array != NULL) {
mysqlnd_stream_array_from_fd_set(r_array, &rfds);
}
if (e_array != NULL) {
mysqlnd_stream_array_from_fd_set(e_array, &efds);
}
*desc_num = retval;
DBG_RETURN(PASS);
}
/* }}} */
/* {{{ mysqlnd_connect */
PHPAPI MYSQLND * mysqlnd_connection_connect(MYSQLND * conn_handle,
const char * const host,
const char * const user,
const char * const passwd, unsigned int passwd_len,
const char * const db, unsigned int db_len,
unsigned int port,
const char * const sock_or_pipe,
unsigned int mysql_flags,
unsigned int client_api_flags
)
{
enum_func_status ret = FAIL;
zend_bool self_alloced = FALSE;
MYSQLND_CSTRING hostname = { host, host? strlen(host) : 0 };
MYSQLND_CSTRING username = { user, user? strlen(user) : 0 };
MYSQLND_CSTRING password = { passwd, passwd_len };
MYSQLND_CSTRING database = { db, db_len };
MYSQLND_CSTRING socket_or_pipe = { sock_or_pipe, sock_or_pipe? strlen(sock_or_pipe) : 0 };
DBG_ENTER("mysqlnd_connect");
DBG_INF_FMT("host=%s user=%s db=%s port=%u flags=%u", host? host:"", user? user:"", db? db:"", port, mysql_flags);
if (!conn_handle) {
self_alloced = TRUE;
if (!(conn_handle = mysqlnd_connection_init(client_api_flags, FALSE, NULL))) {
/* OOM */
DBG_RETURN(NULL);
}
}
ret = conn_handle->m->connect(conn_handle, hostname, username, password, database, port, socket_or_pipe, mysql_flags);
if (ret == FAIL) {
if (self_alloced) {
/*
We have alloced, thus there are no references to this
object - we are free to kill it!
*/
conn_handle->m->dtor(conn_handle);
}
DBG_RETURN(NULL);
}
DBG_RETURN(conn_handle);
}
/* }}} */
/* {{{ mysqlnd_connection_init */
PHPAPI MYSQLND *
mysqlnd_connection_init(const size_t client_flags, const zend_bool persistent, struct st_mysqlnd_object_factory_methods * object_factory)