mirror of
https://github.com/php/php-src.git
synced 2024-09-23 02:47:26 +00:00
Move code out of mysqlnd_conn::connect to mysqlnd_net::connect.
Thus mysqlnd_conn::connect() does less of what it should not do - think about the transport level.
This commit is contained in:
parent
37cbcf3850
commit
1fc65ed8bb
@ -450,12 +450,8 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
|
|||||||
TSRMLS_DC)
|
TSRMLS_DC)
|
||||||
{
|
{
|
||||||
char *transport = NULL, *errstr = NULL;
|
char *transport = NULL, *errstr = NULL;
|
||||||
char *hashed_details = NULL;
|
int transport_len, errcode = 0, host_len;
|
||||||
int transport_len, hashed_details_len, errcode = 0, host_len;
|
|
||||||
unsigned int streams_options = ENFORCE_SAFE_MODE;
|
|
||||||
unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT;
|
|
||||||
zend_bool self_alloced = FALSE;
|
zend_bool self_alloced = FALSE;
|
||||||
struct timeval tv;
|
|
||||||
zend_bool unix_socket = FALSE;
|
zend_bool unix_socket = FALSE;
|
||||||
const MYSQLND_CHARSET * charset;
|
const MYSQLND_CHARSET * charset;
|
||||||
zend_bool reconnect = FALSE;
|
zend_bool reconnect = FALSE;
|
||||||
@ -535,89 +531,22 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
|
|||||||
PACKET_INIT(auth_packet, PROT_AUTH_PACKET, php_mysql_packet_auth *, FALSE);
|
PACKET_INIT(auth_packet, PROT_AUTH_PACKET, php_mysql_packet_auth *, FALSE);
|
||||||
PACKET_INIT_ALLOCA(ok_packet, PROT_OK_PACKET);
|
PACKET_INIT_ALLOCA(ok_packet, PROT_OK_PACKET);
|
||||||
|
|
||||||
if (conn->persistent) {
|
|
||||||
hashed_details_len = spprintf(&hashed_details, 0, "%p", conn);
|
|
||||||
DBG_INF_FMT("hashed_details=%s", hashed_details);
|
|
||||||
}
|
|
||||||
|
|
||||||
CONN_SET_STATE(conn, CONN_ALLOCED);
|
CONN_SET_STATE(conn, CONN_ALLOCED);
|
||||||
conn->net->packet_no = conn->net->compressed_envelope_packet_no = 0;
|
|
||||||
|
|
||||||
if (conn->net->options.timeout_connect) {
|
|
||||||
tv.tv_sec = conn->net->options.timeout_connect;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
}
|
|
||||||
if (conn->persistent) {
|
if (conn->persistent) {
|
||||||
conn->scheme = pestrndup(transport, transport_len, 1);
|
conn->scheme = pestrndup(transport, transport_len, 1);
|
||||||
mnd_efree(transport);
|
mnd_efree(transport);
|
||||||
} else {
|
} else {
|
||||||
conn->scheme = transport;
|
conn->scheme = transport;
|
||||||
}
|
}
|
||||||
conn->scheme_len = strlen(conn->scheme);
|
conn->scheme_len = transport_len;
|
||||||
DBG_INF(conn->scheme);
|
DBG_INF(conn->scheme);
|
||||||
conn->net->stream = php_stream_xport_create(conn->scheme, transport_len, streams_options, streams_flags,
|
if (FAIL == conn->net->m.connect(conn->net, conn->scheme, transport_len, conn->persistent, &errstr, &errcode TSRMLS_CC)) {
|
||||||
hashed_details,
|
goto err;
|
||||||
(conn->net->options.timeout_connect) ? &tv : NULL,
|
}
|
||||||
NULL /*ctx*/, &errstr, &errcode);
|
|
||||||
DBG_INF_FMT("stream=%p", conn->net->stream);
|
DBG_INF_FMT("stream=%p", conn->net->stream);
|
||||||
|
|
||||||
if (errstr || !conn->net->stream) {
|
|
||||||
if (hashed_details) {
|
|
||||||
mnd_efree(hashed_details);
|
|
||||||
}
|
|
||||||
errcode = CR_CONNECTION_ERROR;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hashed_details) {
|
|
||||||
/*
|
|
||||||
If persistent, the streams register it in EG(persistent_list).
|
|
||||||
This is unwanted. ext/mysql or ext/mysqli are responsible to clean,
|
|
||||||
whatever they have to.
|
|
||||||
*/
|
|
||||||
zend_rsrc_list_entry *le;
|
|
||||||
|
|
||||||
if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_len + 1,
|
|
||||||
(void*) &le) == SUCCESS) {
|
|
||||||
/*
|
|
||||||
in_free will let streams code skip destructing - big HACK,
|
|
||||||
but STREAMS suck big time regarding persistent streams.
|
|
||||||
Just not compatible for extensions that need persistency.
|
|
||||||
*/
|
|
||||||
conn->net->stream->in_free = 1;
|
|
||||||
zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_len + 1);
|
|
||||||
conn->net->stream->in_free = 0;
|
|
||||||
}
|
|
||||||
#if ZEND_DEBUG
|
|
||||||
/* Shut-up the streams, they don't know what they are doing */
|
|
||||||
conn->net->stream->__exposed = 1;
|
|
||||||
#endif
|
|
||||||
mnd_efree(hashed_details);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conn->net->options.timeout_read) {
|
|
||||||
/* should always happen because read_timeout cannot be set via API */
|
|
||||||
conn->net->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout);
|
|
||||||
}
|
|
||||||
if (conn->net->options.timeout_read)
|
|
||||||
{
|
|
||||||
tv.tv_sec = conn->net->options.timeout_read;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
php_stream_set_option(conn->net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!unix_socket) {
|
|
||||||
/* Set TCP_NODELAY */
|
|
||||||
mysqlnd_set_sock_no_delay(conn->net->stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
unsigned int buf_size;
|
|
||||||
buf_size = MYSQLND_G(net_read_buffer_size); /* this is long, cast to unsigned int*/
|
|
||||||
conn->m->set_client_option(conn, MYSQLND_OPT_NET_READ_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (FAIL == PACKET_READ_ALLOCA(greet_packet, conn)) {
|
if (FAIL == PACKET_READ_ALLOCA(greet_packet, conn)) {
|
||||||
DBG_ERR("Error while reading greeting packet");
|
DBG_ERR("Error while reading greeting packet");
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
|
||||||
|
@ -230,6 +230,7 @@ typedef struct st_mysqlnd_read_buffer {
|
|||||||
|
|
||||||
struct st_mysqlnd_net_methods
|
struct st_mysqlnd_net_methods
|
||||||
{
|
{
|
||||||
|
enum_func_status (*connect)(MYSQLND_NET * net, const char * const scheme, size_t scheme_len, zend_bool persistent, char **errstr, int * errcode TSRMLS_DC);
|
||||||
enum_func_status (*stream_read)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC);
|
enum_func_status (*stream_read)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC);
|
||||||
size_t (*stream_write)(MYSQLND * const conn, const zend_uchar * const buf, size_t count TSRMLS_DC);
|
size_t (*stream_write)(MYSQLND * const conn, const zend_uchar * const buf, size_t count TSRMLS_DC);
|
||||||
enum_func_status (*set_client_option)(MYSQLND_NET * const net, enum_mysqlnd_option option, const char * const value TSRMLS_DC);
|
enum_func_status (*set_client_option)(MYSQLND_NET * const net, enum_mysqlnd_option option, const char * const value TSRMLS_DC);
|
||||||
|
@ -2290,6 +2290,95 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] =
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_net::connect */
|
||||||
|
static enum_func_status
|
||||||
|
MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const scheme, size_t scheme_len, zend_bool persistent, char **errstr, int * errcode TSRMLS_DC)
|
||||||
|
{
|
||||||
|
unsigned int streams_options = ENFORCE_SAFE_MODE;
|
||||||
|
unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT;
|
||||||
|
char * hashed_details = NULL;
|
||||||
|
int hashed_details_len = 0;
|
||||||
|
struct timeval tv;
|
||||||
|
DBG_ENTER("mysqlnd_net::connect");
|
||||||
|
|
||||||
|
if (persistent) {
|
||||||
|
hashed_details_len = spprintf(&hashed_details, 0, "%p", net);
|
||||||
|
DBG_INF_FMT("hashed_details=%s", hashed_details);
|
||||||
|
}
|
||||||
|
|
||||||
|
net->packet_no = net->compressed_envelope_packet_no = 0;
|
||||||
|
|
||||||
|
if (net->options.timeout_connect) {
|
||||||
|
tv.tv_sec = net->options.timeout_connect;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
net->stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags,
|
||||||
|
hashed_details, (net->options.timeout_connect) ? &tv : NULL,
|
||||||
|
NULL /*ctx*/, errstr, errcode);
|
||||||
|
|
||||||
|
|
||||||
|
if (*errstr || !net->stream) {
|
||||||
|
if (hashed_details) {
|
||||||
|
efree(hashed_details);
|
||||||
|
}
|
||||||
|
*errcode = CR_CONNECTION_ERROR;
|
||||||
|
DBG_RETURN(FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashed_details) {
|
||||||
|
/*
|
||||||
|
If persistent, the streams register it in EG(persistent_list).
|
||||||
|
This is unwanted. ext/mysql or ext/mysqli are responsible to clean,
|
||||||
|
whatever they have to.
|
||||||
|
*/
|
||||||
|
zend_rsrc_list_entry *le;
|
||||||
|
|
||||||
|
if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_len + 1,
|
||||||
|
(void*) &le) == SUCCESS) {
|
||||||
|
/*
|
||||||
|
in_free will let streams code skip destructing - big HACK,
|
||||||
|
but STREAMS suck big time regarding persistent streams.
|
||||||
|
Just not compatible for extensions that need persistency.
|
||||||
|
*/
|
||||||
|
net->stream->in_free = 1;
|
||||||
|
zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_len + 1);
|
||||||
|
net->stream->in_free = 0;
|
||||||
|
}
|
||||||
|
#if ZEND_DEBUG
|
||||||
|
/* Shut-up the streams, they don't know what they are doing */
|
||||||
|
net->stream->__exposed = 1;
|
||||||
|
#endif
|
||||||
|
efree(hashed_details);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!net->options.timeout_read) {
|
||||||
|
/* should always happen because read_timeout cannot be set via API */
|
||||||
|
net->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout);
|
||||||
|
}
|
||||||
|
if (net->options.timeout_read)
|
||||||
|
{
|
||||||
|
tv.tv_sec = net->options.timeout_read;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(scheme, "tcp://", sizeof("tcp://") - 1)) {
|
||||||
|
/* TCP -> Set TCP_NODELAY */
|
||||||
|
mysqlnd_set_sock_no_delay(net->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned int buf_size = MYSQLND_G(net_read_buffer_size); /* this is long, cast to unsigned int*/
|
||||||
|
net->m.set_client_option(net, MYSQLND_OPT_NET_READ_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DBG_RETURN(PASS);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
/* {{{ mysqlnd_net::set_client_option */
|
/* {{{ mysqlnd_net::set_client_option */
|
||||||
static enum_func_status
|
static enum_func_status
|
||||||
MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mysqlnd_option option, const char * const value TSRMLS_DC)
|
MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mysqlnd_option option, const char * const value TSRMLS_DC)
|
||||||
@ -2368,6 +2457,7 @@ mysqlnd_net_init(zend_bool persistent TSRMLS_DC)
|
|||||||
DBG_INF_FMT("persistent=%d", persistent);
|
DBG_INF_FMT("persistent=%d", persistent);
|
||||||
net->persistent = persistent;
|
net->persistent = persistent;
|
||||||
|
|
||||||
|
net->m.connect = MYSQLND_METHOD(mysqlnd_net, connect);
|
||||||
net->m.stream_read = MYSQLND_METHOD(mysqlnd_net, read_from_stream);
|
net->m.stream_read = MYSQLND_METHOD(mysqlnd_net, read_from_stream);
|
||||||
net->m.stream_write = MYSQLND_METHOD(mysqlnd_net, stream_write);
|
net->m.stream_write = MYSQLND_METHOD(mysqlnd_net, stream_write);
|
||||||
net->m.set_client_option = MYSQLND_METHOD(mysqlnd_net, set_client_option);
|
net->m.set_client_option = MYSQLND_METHOD(mysqlnd_net, set_client_option);
|
||||||
|
Loading…
Reference in New Issue
Block a user