# define TCP_KEEPIDLE 0
#endif
-static memcached_return_t connect_poll(org::libmemcached::Instance* server, const int connection_error)
+static memcached_return_t connect_poll(memcached_instance_st* server, const int connection_error)
{
struct pollfd fds[1];
fds[0].fd= server->fd;
if (server->root->poll_timeout == 0)
{
return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT,
- memcached_literal_param("The time to wait for a connection to be established was set to zero, which means it will always timeout (MEMCACHED_TIMEOUT)."));
+ memcached_literal_param("The time to wait for a connection to be established was set to zero which produces a timeout to every call to poll()."));
}
while (--loop_max) // Should only loop on cases of ERESTART or EINTR
int local_errno= get_socket_errno(); // We cache in case closesocket() modifies errno
switch (local_errno)
{
-#ifdef TARGET_OS_LINUX
+#ifdef __linux__
case ERESTART:
#endif
case EINTR:
default: // This should not happen
break;
-#if 0
- if (fds[0].revents & POLLERR)
- {
- int err;
- socklen_t len= sizeof(err);
- if (getsockopt(server->fd, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0)
- {
- if (err == 0)
- {
- // This should never happen, if it does? Punt.
- continue;
- }
- local_errno= err;
- }
- }
-#endif
}
assert_msg(server->fd != INVALID_SOCKET, "poll() was passed an invalid file descriptor");
}
}
- return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+ return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT, memcached_literal_param("(number_of == 0)"));
}
-#if 0
- server->revents(fds[0].revents);
-#endif
-
assert (number_of == 1);
if (fds[0].revents & POLLERR or
return memcached_set_errno(*server, errno, MEMCACHED_AT, memcached_literal_param("getsockopt() errored while looking up error state from poll()"));
}
- // We check the value to see what happened wth the socket.
+ // We check the value to see what happened with the socket.
if (err == 0) // Should not happen
{
return MEMCACHED_SUCCESS;
return memcached_set_errno(*server, connection_error, MEMCACHED_AT, memcached_literal_param("connect_poll() was exhausted"));
}
-static memcached_return_t set_hostinfo(org::libmemcached::Instance* server)
+static memcached_return_t set_hostinfo(memcached_instance_st* server)
{
assert(server->type != MEMCACHED_CONNECTION_UNIX_SOCKET);
server->clear_addrinfo();
- char str_port[MEMCACHED_NI_MAXSERV];
+ char str_port[MEMCACHED_NI_MAXSERV]= { 0 };
+ errno= 0;
int length= snprintf(str_port, MEMCACHED_NI_MAXSERV, "%u", uint32_t(server->port()));
- if (length >= MEMCACHED_NI_MAXSERV or length <= 0)
+ if (length >= MEMCACHED_NI_MAXSERV or length <= 0 or errno != 0)
{
return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT,
memcached_literal_param("snprintf(NI_MAXSERV)"));
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family= AF_INET;
+ hints.ai_family= AF_UNSPEC;
if (memcached_is_udp(server->root))
{
hints.ai_protocol= IPPROTO_UDP;
return MEMCACHED_SUCCESS;
}
-static inline void set_socket_nonblocking(org::libmemcached::Instance* server)
+static inline void set_socket_nonblocking(memcached_instance_st* server)
{
#if defined(_WIN32)
u_long arg= 1;
#endif
}
-static bool set_socket_options(org::libmemcached::Instance* server)
+static bool set_socket_options(memcached_instance_st* server)
{
assert_msg(server->fd != INVALID_SOCKET, "invalid socket was passed to set_socket_options()");
// If SOCK_CLOEXEC exists then we don't need to call the following
if (SOCK_CLOEXEC == 0)
{
- if (FD_CLOEXEC)
+ if (FD_CLOEXEC != 0)
{
int flags;
do
return true;
}
-static memcached_return_t unix_socket_connect(org::libmemcached::Instance* server)
+static memcached_return_t unix_socket_connect(memcached_instance_st* server)
{
#ifndef _WIN32
WATCHPOINT_ASSERT(server->fd == INVALID_SOCKET);
do {
int type= SOCK_STREAM;
- if (SOCK_CLOEXEC)
+ if (SOCK_CLOEXEC != 0)
{
type|= SOCK_CLOEXEC;
}
- if (SOCK_NONBLOCK)
+ if (SOCK_NONBLOCK != 0)
{
type|= SOCK_NONBLOCK;
}
memset(&servAddr, 0, sizeof (struct sockaddr_un));
servAddr.sun_family= AF_UNIX;
- strncpy(servAddr.sun_path, server->hostname(), sizeof(servAddr.sun_path)); /* Copy filename */
+ if (strlen(server->hostname()) >= sizeof(servAddr.sun_path)) {
+ return memcached_set_error(*server, MEMCACHED_UNIX_SOCKET_PATH_TOO_BIG, MEMCACHED_AT);
+ }
+ strncpy(servAddr.sun_path, server->hostname(), sizeof(servAddr.sun_path)-1); /* Copy filename */
if (connect(server->fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -1)
{
{
case EINPROGRESS:
case EALREADY:
+ case EAGAIN:
server->events(POLLOUT);
break;
#endif
}
-static memcached_return_t network_connect(org::libmemcached::Instance* server)
+static memcached_return_t network_connect(memcached_instance_st* server)
{
bool timeout_error_occured= false;
/* Create the socket */
while (server->address_info_next and server->fd == INVALID_SOCKET)
{
- /* Memcache server does not support IPV6 in udp mode, so skip if not ipv4 */
- if (memcached_is_udp(server->root) and server->address_info_next->ai_family != AF_INET)
- {
- server->address_info_next= server->address_info_next->ai_next;
- continue;
- }
-
int type= server->address_info_next->ai_socktype;
- if (SOCK_CLOEXEC)
+ if (SOCK_CLOEXEC != 0)
{
type|= SOCK_CLOEXEC;
}
- if (SOCK_NONBLOCK)
+ if (SOCK_NONBLOCK != 0)
{
type|= SOCK_NONBLOCK;
}
timeout_error_occured= true;
break;
- case EAGAIN:
#if EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
// Probably not running service
default:
+ memcached_set_errno(*server, local_error, MEMCACHED_AT);
break;
}
if (timeout_error_occured and server->state < MEMCACHED_SERVER_STATE_IN_PROGRESS)
{
- return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+ return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT,
+ memcached_literal_param("if (timeout_error_occured and server->state < MEMCACHED_SERVER_STATE_IN_PROGRESS)"));
}
return memcached_set_error(*server, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT); /* The last error should be from connect() */
Based on time/failure count fail the connect without trying. This prevents waiting in a state where
we get caught spending cycles just waiting.
*/
-static memcached_return_t backoff_handling(org::libmemcached::Instance* server, bool& in_timeout)
+static memcached_return_t backoff_handling(memcached_instance_st* server, bool& in_timeout)
{
struct timeval curr_time;
bool _gettime_success= (gettimeofday(&curr_time, NULL) == 0);
if (_gettime_success and server->next_retry < curr_time.tv_sec)
{
server->state= MEMCACHED_SERVER_STATE_NEW;
+ server->server_timeout_counter= 0;
}
else
{
return MEMCACHED_SUCCESS;
}
-static memcached_return_t _memcached_connect(org::libmemcached::Instance* server, const bool set_last_disconnected)
+static memcached_return_t _memcached_connect(memcached_instance_st* server, const bool set_last_disconnected)
{
assert(server);
if (server->fd != INVALID_SOCKET)
case MEMCACHED_CONNECTION_TCP:
rc= network_connect(server);
+#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT)
if (LIBMEMCACHED_WITH_SASL_SUPPORT)
{
if (server->fd != INVALID_SOCKET and server->root->sasl.callbacks)
}
}
}
+#endif
break;
case MEMCACHED_CONNECTION_UNIX_SOCKET:
return rc;
}
-memcached_return_t memcached_connect(org::libmemcached::Instance* server)
+memcached_return_t memcached_connect(memcached_instance_st* server)
{
return _memcached_connect(server, true);
}