projects
/
awesomized
/
libmemcached
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
|
github
raw
|
inline
| side by side
Refactor: move ntohll to a separate helper library
[awesomized/libmemcached]
/
libmemcached
/
memcached_connect.c
diff --git
a/libmemcached/memcached_connect.c
b/libmemcached/memcached_connect.c
index c2e03ac38e7a4279512f84c0c096e63545769f1c..833ad0efba97f9b9eb126d7f177ab1bb4147aff9 100644
(file)
--- a/
libmemcached/memcached_connect.c
+++ b/
libmemcached/memcached_connect.c
@@
-81,12
+81,13
@@
static memcached_return set_socket_options(memcached_server_st *ptr)
}
#endif
}
#endif
+ if (ptr->root->flags & MEM_NO_BLOCK)
{
int error;
struct linger linger;
linger.l_onoff= 1;
{
int error;
struct linger linger;
linger.l_onoff= 1;
- linger.l_linger=
MEMCACHED_DEFAULT_TIMEOUT;
+ linger.l_linger=
0; /* By default on close() just drop the socket */
error= setsockopt(ptr->fd, SOL_SOCKET, SO_LINGER,
&linger, (socklen_t)sizeof(struct linger));
WATCHPOINT_ASSERT(error == 0);
error= setsockopt(ptr->fd, SOL_SOCKET, SO_LINGER,
&linger, (socklen_t)sizeof(struct linger));
WATCHPOINT_ASSERT(error == 0);
@@
-121,7
+122,7
@@
static memcached_return set_socket_options(memcached_server_st *ptr)
}
/* For the moment, not getting a nonblocking mode will not be fatal */
}
/* For the moment, not getting a nonblocking mode will not be fatal */
- if (
ptr->root->flags & MEM_NO_BLOCK
)
+ if (
(ptr->root->flags & MEM_NO_BLOCK) || ptr->root->connect_timeout
)
{
int flags;
{
int flags;
@@
-152,14
+153,15
@@
static memcached_return unix_socket_connect(memcached_server_st *ptr)
servAddr.sun_family= AF_UNIX;
strcpy(servAddr.sun_path, ptr->hostname); /* Copy filename */
servAddr.sun_family= AF_UNIX;
strcpy(servAddr.sun_path, ptr->hostname); /* Copy filename */
- addrlen=
strlen(servAddr.sun_path) + sizeof(servAddr.sun_family
);
+ addrlen=
(socklen_t) (strlen(servAddr.sun_path) + sizeof(servAddr.sun_family)
);
test_connect:
if (connect(ptr->fd,
(struct sockaddr *)&servAddr,
sizeof(servAddr)) < 0)
{
test_connect:
if (connect(ptr->fd,
(struct sockaddr *)&servAddr,
sizeof(servAddr)) < 0)
{
- switch (errno) {
+ switch (errno)
+ {
case EINPROGRESS:
case EALREADY:
case EINTR:
case EINPROGRESS:
case EALREADY:
case EINTR:
@@
-184,16
+186,7
@@
static memcached_return network_connect(memcached_server_st *ptr)
{
struct addrinfo *use;
{
struct addrinfo *use;
- if (ptr->root->server_failure_limit != 0)
- {
- if (ptr->server_failure_counter >= ptr->root->server_failure_limit)
- {
- memcached_server_remove(ptr);
- return MEMCACHED_FAILURE;
- }
- }
-
- if (ptr->sockaddr_inited ||
+ if (!ptr->sockaddr_inited ||
(!(ptr->root->flags & MEM_USE_CACHE_LOOKUPS)))
{
memcached_return rc;
(!(ptr->root->flags & MEM_USE_CACHE_LOOKUPS)))
{
memcached_return rc;
@@
-208,6
+201,13
@@
static memcached_return network_connect(memcached_server_st *ptr)
/* Create the socket */
while (use != NULL)
{
/* Create the socket */
while (use != NULL)
{
+ /* Memcache server does not support IPV6 in udp mode, so skip if not ipv4 */
+ if (ptr->type == MEMCACHED_CONNECTION_UDP && use->ai_family != AF_INET)
+ {
+ use= use->ai_next;
+ continue;
+ }
+
if ((ptr->fd= socket(use->ai_family,
use->ai_socktype,
use->ai_protocol)) < 0)
if ((ptr->fd= socket(use->ai_family,
use->ai_socktype,
use->ai_protocol)) < 0)
@@
-219,7
+219,7
@@
static memcached_return network_connect(memcached_server_st *ptr)
(void)set_socket_options(ptr);
(void)set_socket_options(ptr);
- int flags;
+ int flags
= 0
;
if (ptr->root->connect_timeout)
{
flags= fcntl(ptr->fd, F_GETFL, 0);
if (ptr->root->connect_timeout)
{
flags= fcntl(ptr->fd, F_GETFL, 0);
@@
-235,7
+235,9
@@
static memcached_return network_connect(memcached_server_st *ptr)
if (errno == EINPROGRESS || /* nonblocking mode - first return, */
errno == EALREADY) /* nonblocking mode - subsequent returns */
{
if (errno == EINPROGRESS || /* nonblocking mode - first return, */
errno == EALREADY) /* nonblocking mode - subsequent returns */
{
- struct pollfd fds[1] = { [0].fd = ptr->fd, [0].events = POLLOUT };
+ struct pollfd fds[1];
+ fds[0].fd = ptr->fd;
+ fds[0].events = POLLOUT;
int error= poll(fds, 1, ptr->root->connect_timeout);
if (error != 1 || fds[0].revents & POLLERR)
int error= poll(fds, 1, ptr->root->connect_timeout);
if (error != 1 || fds[0].revents & POLLERR)
@@
-243,9
+245,9
@@
static memcached_return network_connect(memcached_server_st *ptr)
if (fds[0].revents & POLLERR)
{
int err;
if (fds[0].revents & POLLERR)
{
int err;
-
in
t len = sizeof (err);
+
socklen_
t len = sizeof (err);
(void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
(void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
- ptr->cached_errno=
errno
;
+ ptr->cached_errno=
(err == 0) ? errno : err
;
}
(void)close(ptr->fd);
}
(void)close(ptr->fd);
@@
-267,7
+269,7
@@
static memcached_return network_connect(memcached_server_st *ptr)
if (ptr->fd != -1)
{
/* restore flags */
if (ptr->fd != -1)
{
/* restore flags */
- if (ptr->root->connect_timeout && (
flags & O_NON
BLOCK) == 0)
+ if (ptr->root->connect_timeout && (
ptr->root->flags & MEM_NO_
BLOCK) == 0)
(void)fcntl(ptr->fd, F_SETFL, flags & ~O_NONBLOCK);
WATCHPOINT_ASSERT(ptr->cursor_active == 0);
(void)fcntl(ptr->fd, F_SETFL, flags & ~O_NONBLOCK);
WATCHPOINT_ASSERT(ptr->cursor_active == 0);
@@
-289,6
+291,8
@@
static memcached_return network_connect(memcached_server_st *ptr)
ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
}
ptr->server_failure_counter+= 1;
ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
}
ptr->server_failure_counter+= 1;
+ if (ptr->cached_errno == 0)
+ return MEMCACHED_TIMEOUT;
return MEMCACHED_ERRNO; /* The last error should be from connect() */
}
return MEMCACHED_ERRNO; /* The last error should be from connect() */
}
@@
-302,14
+306,30
@@
memcached_return memcached_connect(memcached_server_st *ptr)
memcached_return rc= MEMCACHED_NO_SERVERS;
LIBMEMCACHED_MEMCACHED_CONNECT_START();
memcached_return rc= MEMCACHED_NO_SERVERS;
LIBMEMCACHED_MEMCACHED_CONNECT_START();
- if (ptr->root->retry_timeout)
+ /* both retry_timeout and server_failure_limit must be set in order to delay retrying a server on error. */
+ WATCHPOINT_ASSERT(ptr->root);
+ if (ptr->root->retry_timeout && ptr->root->server_failure_limit)
{
struct timeval next_time;
gettimeofday(&next_time, NULL);
{
struct timeval next_time;
gettimeofday(&next_time, NULL);
+
+ /* if we've had too many consecutive errors on this server, mark it dead. */
+ if (ptr->server_failure_counter > ptr->root->server_failure_limit)
+ {
+ ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
+ ptr->server_failure_counter= 0;
+ }
+
if (next_time.tv_sec < ptr->next_retry)
if (next_time.tv_sec < ptr->next_retry)
- return MEMCACHED_TIMEOUT;
+ {
+ if (memcached_behavior_get(ptr->root, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS))
+ run_distribution(ptr->root);
+
+ return MEMCACHED_SERVER_MARKED_DEAD;
+ }
}
}
+
/* We need to clean up the multi startup piece */
switch (ptr->type)
{
/* We need to clean up the multi startup piece */
switch (ptr->type)
{