diff options
author | stewart@willster.(none) <> | 2007-01-24 00:34:12 +1100 |
---|---|---|
committer | stewart@willster.(none) <> | 2007-01-24 00:34:12 +1100 |
commit | dbaab7f47450d6b01f09af2711a6e81596c8b4c0 (patch) | |
tree | a94630f8ac2d22dff04f2461a3d693fe898714c8 /storage | |
parent | adf40be13bd993cf118484c4f8d52e0ba5348b21 (diff) | |
parent | 5b886fa35848d1dc875d0d34d9a286a6514f0c9e (diff) | |
download | mariadb-git-dbaab7f47450d6b01f09af2711a6e81596c8b4c0.tar.gz |
Merge willster.(none):/home/stewart/Documents/MySQL/5.0/bug25487
into willster.(none):/home/stewart/Documents/MySQL/5.1/bug25567
Diffstat (limited to 'storage')
-rw-r--r-- | storage/ndb/include/mgmapi/mgmapi.h | 10 | ||||
-rw-r--r-- | storage/ndb/include/util/SocketClient.hpp | 4 | ||||
-rw-r--r-- | storage/ndb/src/common/transporter/Transporter.cpp | 8 | ||||
-rw-r--r-- | storage/ndb/src/common/util/SocketClient.cpp | 60 | ||||
-rw-r--r-- | storage/ndb/src/mgmapi/mgmapi.cpp | 13 |
5 files changed, 89 insertions, 6 deletions
diff --git a/storage/ndb/include/mgmapi/mgmapi.h b/storage/ndb/include/mgmapi/mgmapi.h index 171fdfa4053..42a6b53098f 100644 --- a/storage/ndb/include/mgmapi/mgmapi.h +++ b/storage/ndb/include/mgmapi/mgmapi.h @@ -545,6 +545,16 @@ extern "C" { const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz); /** + * Sets the number of seconds to wait for connect(2) during ndb_mgm_connect + * Default is no timeout + * + * @param handle NdbMgmHandle + * @param seconds number of seconds + * @return non-zero on success + */ + int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds); + + /** * Connects to a management server. Connectstring is set by * ndb_mgm_set_connectstring(). * diff --git a/storage/ndb/include/util/SocketClient.hpp b/storage/ndb/include/util/SocketClient.hpp index e1f1752e9a8..bb8d9b9ac41 100644 --- a/storage/ndb/include/util/SocketClient.hpp +++ b/storage/ndb/include/util/SocketClient.hpp @@ -23,6 +23,7 @@ class SocketClient { NDB_SOCKET_TYPE m_sockfd; struct sockaddr_in m_servaddr; + unsigned int m_connect_timeout_sec; unsigned short m_port; char *m_server_name; SocketAuthenticator *m_auth; @@ -34,6 +35,9 @@ public: m_port = port; m_servaddr.sin_port = htons(m_port); }; + void set_connect_timeout(unsigned int s) { + m_connect_timeout_sec= s; + } unsigned short get_port() { return m_port; }; char *get_server_name() { return m_server_name; }; int bind(const char* toaddress, unsigned short toport); diff --git a/storage/ndb/src/common/transporter/Transporter.cpp b/storage/ndb/src/common/transporter/Transporter.cpp index 339533c8d27..20b6be8ce26 100644 --- a/storage/ndb/src/common/transporter/Transporter.cpp +++ b/storage/ndb/src/common/transporter/Transporter.cpp @@ -79,9 +79,13 @@ Transporter::Transporter(TransporterRegistry &t_reg, if (isServer) m_socket_client= 0; else + { m_socket_client= new SocketClient(remoteHostName, s_port, new SocketAuthSimple("ndbd", "ndbd passwd")); + + m_socket_client->set_connect_timeout((m_timeOutMillis+999)/1000); + } DBUG_VOID_RETURN; } @@ -140,9 +144,9 @@ Transporter::connect_client() { } sockfd= m_socket_client->connect(); } - + return connect_client(sockfd); -} +} bool Transporter::connect_client(NDB_SOCKET_TYPE sockfd) { diff --git a/storage/ndb/src/common/util/SocketClient.cpp b/storage/ndb/src/common/util/SocketClient.cpp index bb059585863..ec35fd3eb90 100644 --- a/storage/ndb/src/common/util/SocketClient.cpp +++ b/storage/ndb/src/common/util/SocketClient.cpp @@ -26,6 +26,7 @@ SocketClient::SocketClient(const char *server_name, unsigned short port, SocketA m_port= port; m_server_name= server_name ? strdup(server_name) : 0; m_sockfd= NDB_INVALID_SOCKET; + m_connect_timeout_sec= 0; } SocketClient::~SocketClient() @@ -58,7 +59,7 @@ SocketClient::init() if (m_sockfd == NDB_INVALID_SOCKET) { return false; } - + DBUG_PRINT("info",("NDB_SOCKET: %d", m_sockfd)); return true; @@ -104,6 +105,13 @@ SocketClient::bind(const char* bindaddress, unsigned short localport) NDB_SOCKET_TYPE SocketClient::connect(const char *toaddress, unsigned short toport) { + fd_set rset, wset; + struct timeval tval; + int r; + bool use_timeout; + socklen_t len; + int flags; + if (m_sockfd == NDB_INVALID_SOCKET) { if (!init()) { @@ -127,14 +135,58 @@ SocketClient::connect(const char *toaddress, unsigned short toport) if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name)) return NDB_INVALID_SOCKET; } - - const int r = ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr)); - if (r == -1) { + + flags= fcntl(m_sockfd, F_GETFL, 0); + fcntl(m_sockfd, F_SETFL, flags | O_NONBLOCK); + + r= ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr)); + + if (r == 0) + goto done; // connected immediately. + + if (r < 0 && (errno != EINPROGRESS)) { + NDB_CLOSE_SOCKET(m_sockfd); + m_sockfd= NDB_INVALID_SOCKET; + return NDB_INVALID_SOCKET; + } + + FD_ZERO(&rset); + FD_SET(m_sockfd, &rset); + wset= rset; + tval.tv_sec= m_connect_timeout_sec; + tval.tv_usec= 0; + use_timeout= m_connect_timeout_sec; + + if ((r= select(m_sockfd+1, &rset, &wset, NULL, + use_timeout? &tval : NULL)) == 0) + { NDB_CLOSE_SOCKET(m_sockfd); m_sockfd= NDB_INVALID_SOCKET; return NDB_INVALID_SOCKET; } + if (FD_ISSET(m_sockfd, &rset) || FD_ISSET(m_sockfd, &wset)) + { + len= sizeof(r); + if (getsockopt(m_sockfd, SOL_SOCKET, SO_ERROR, &r, &len) < 0) + { + // Solaris got an error... different than others + NDB_CLOSE_SOCKET(m_sockfd); + m_sockfd= NDB_INVALID_SOCKET; + return NDB_INVALID_SOCKET; + } + } + else + { + // select error, probably m_sockfd not set. + NDB_CLOSE_SOCKET(m_sockfd); + m_sockfd= NDB_INVALID_SOCKET; + return NDB_INVALID_SOCKET; + } + +done: + fcntl(m_sockfd, F_SETFL, flags); + if (m_auth) { if (!m_auth->client_authenticate(m_sockfd)) { diff --git a/storage/ndb/src/mgmapi/mgmapi.cpp b/storage/ndb/src/mgmapi/mgmapi.cpp index bd58425c802..486d7fec1a1 100644 --- a/storage/ndb/src/mgmapi/mgmapi.cpp +++ b/storage/ndb/src/mgmapi/mgmapi.cpp @@ -93,6 +93,7 @@ struct ndb_mgm_handle { char last_error_desc[NDB_MGM_MAX_ERR_DESC_SIZE]; int read_timeout; int write_timeout; + unsigned int connect_timeout; NDB_SOCKET_TYPE socket; @@ -165,6 +166,7 @@ ndb_mgm_create_handle() h->socket = NDB_INVALID_SOCKET; h->read_timeout = 50000; h->write_timeout = 100; + h->connect_timeout = 0; h->cfg_i = -1; h->errstream = stdout; h->m_name = 0; @@ -432,6 +434,16 @@ int ndb_mgm_is_connected(NdbMgmHandle handle) return handle->connected; } +extern "C" +int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds) +{ + if(!handle) + return -1; + + handle->connect_timeout= seconds; + return 0; +} + /** * Connect to a management server */ @@ -462,6 +474,7 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries, Uint32 i; int binderror = 0; SocketClient s(0, 0); + s.set_connect_timeout(handle->connect_timeout); if (!s.init()) { fprintf(handle->errstream, |