0.8
* Adding support for CRC hash method
+ * Adding support for UNIX sockets
0.7 Tue Oct 30 09:24:05 PDT 2007
* Poved to poll() from select()
memcached_server_add.3: memcached_servers.pod\r
pod2man -c "libmemcached" -r "" -s 3 memcached_servers.pod > memcached_server_add.3\r
\r
+memcached_server_add_unix_socket.3: memcached_servers.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_servers.pod > memcached_server_add_unix_socket.3\r
+\r
memcached_server_push.3: memcached_servers.pod\r
pod2man -c "libmemcached" -r "" -s 3 memcached_servers.pod > memcached_server_push.3\r
\r
=head1 SEE ALSO
-memcached(1) libmemcached_examples(3) libmemcached(1) memcat(1) memcp(1) memflush(1) memrm(1) memslap(1) memstat(1) memcached_fetch(3) memcached_replace(3) memcached_server_list_free(3) libmemcached_examples(3) memcached_clone(3) memcached_free(3) memcached_server_add(3) memcached_server_push(3) memcached_add(3) memcached_get(3) memcached_server_count(3) memcached_servers_parse(3) memcached_create(3) memcached_increment(3) memcached_server_list(3) memcached_set(3) memcached_decrement(3) memcached_mget(3) memcached_server_list_append(3) memcached_strerror(3) memcached_delete(3) memcached_quit(3) memcached_server_list_count(3) memcached_verbosity(3)
+memcached(1) libmemcached_examples(3) libmemcached(1) memcat(1) memcp(1) memflush(1) memrm(1) memslap(1) memstat(1) memcached_fetch(3) memcached_replace(3) memcached_server_list_free(3) libmemcached_examples(3) memcached_clone(3) memcached_free(3) memcached_server_add(3) memcached_server_push(3) memcached_add(3) memcached_get(3) memcached_server_count(3) memcached_servers_parse(3) memcached_create(3) memcached_increment(3) memcached_server_list(3) memcached_set(3) memcached_decrement(3) memcached_mget(3) memcached_server_list_append(3) memcached_strerror(3) memcached_delete(3) memcached_quit(3) memcached_server_list_count(3) memcached_verbosity(3) memcached_server_add_unix_socket(3)
=cut
char *hostname,
unsigned int port);
+ memcached_return
+ memcached_server_add_unix_socket (memcached_st *ptr,
+ char *hostname,
+ unsigned int port);
+
memcached_return
memcached_server_push (memcached_st *ptr,
memcached_server_st *list);
structure. This server will be placed at the end. Duplicate servers are
allowed, so duplication is not checked.
+memcached_server_add_unix_socket() pushes a single UNIX socket into the
+C<memcached_st> structure. This UNIX socket will be placed at the end.
+Duplicate servers are allowed, so duplication is not checked.
+
memcached_server_push() pushes an array of C<memcached_server_st> into
the C<memcached_st> structure. These servers will be placed at the
end. Duplicate servers are allowed, so duplication is not checked. A
MEMCACHED_VALUE,
MEMCACHED_STAT,
MEMCACHED_ERRNO,
+ MEMCACHED_FAIL_UNIX_SOCKET,
+ MEMCACHED_NOT_SUPPORTED,
MEMCACHED_MAXIMUM_RETURN, /* Always add new error code before */
} memcached_return;
MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE,
} memcached_behavior;
+typedef enum {
+ MEMCACHED_CONNECTION_UNKNOWN,
+ MEMCACHED_CONNECTION_TCP,
+ MEMCACHED_CONNECTION_UDP,
+ MEMCACHED_CONNECTION_UNIX_SOCKET,
+} memcached_connection;
+
typedef enum {
MEMCACHED_NOT_ALLOCATED= 0,
MEMCACHED_ALLOCATED= 1,
int fd;
unsigned int stack_responses;
unsigned int cursor_active;
+ memcached_connection type;
};
struct memcached_stat_st {
#define memcached_server_list(A) A->hosts
#define memcached_server_response_count(A,B) A->hosts[B].stack_responses
+memcached_return memcached_server_add_unix_socket(memcached_st *ptr,
+ char *filename);
memcached_return memcached_server_add(memcached_st *ptr, char *hostname,
unsigned int port);
void memcached_server_list_free(memcached_server_st *ptr);
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netinet/tcp.h>
#include <netdb.h>
-memcached_return memcached_real_connect(memcached_st *ptr, unsigned int server_key)
+static memcached_return unix_socket_connect(memcached_st *ptr, unsigned int server_key)
{
- struct sockaddr_in localAddr, servAddr;
+ struct sockaddr_un servAddr;
+ socklen_t addrlen;
+
+ if (ptr->hosts[server_key].fd == -1)
+ {
+ if ((ptr->hosts[server_key].fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ ptr->my_errno= errno;
+ return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+ }
+
+ memset(&servAddr, 0, sizeof (struct sockaddr_un));
+ servAddr.sun_family= AF_UNIX;
+ strcpy(servAddr.sun_path, ptr->hosts[server_key].hostname);
+
+ addrlen= strlen(servAddr.sun_path) + sizeof(servAddr.sun_family);
+
+test_connect:
+ if (connect(ptr->hosts[server_key].fd, (struct sockaddr_un *)&servAddr, sizeof(servAddr)) < 0)
+ {
+ switch (errno) {
+ /* We are spinning waiting on connect */
+ case EALREADY:
+ case EINPROGRESS:
+ case EINTR:
+ goto test_connect;
+ case EISCONN: /* We were spinning waiting on connect */
+ break;
+ default:
+ ptr->my_errno= errno;
+ return MEMCACHED_ERRNO;
+ }
+ ptr->connected++;
+ }
+ }
+ return MEMCACHED_SUCCESS;
+}
+
+static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
+{
+ struct sockaddr_in servAddr;
struct hostent *h;
if (ptr->hosts[server_key].fd == -1)
return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
}
- /* bind any port number */
- localAddr.sin_family = AF_INET;
- localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- localAddr.sin_port = htons(0);
-
/* For the moment, not getting a nonblocking mode will note be fatal */
if (ptr->flags & MEM_NO_BLOCK)
{
/* connect to server */
test_connect:
- if (connect(ptr->hosts[server_key].fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
+ if (connect(ptr->hosts[server_key].fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
{
switch (errno) {
/* We are spinning waiting on connect */
/* We need to clean up the multi startup piece */
if (server_key)
- rc= memcached_real_connect(ptr, server_key);
+ rc= tcp_connect(ptr, server_key);
else
{
unsigned int x;
{
memcached_return possible_rc;
- possible_rc= memcached_real_connect(ptr, x);
+ possible_rc= MEMCACHED_NOT_SUPPORTED; /* Remove warning */
+
+ switch (ptr->hosts[x].type)
+ {
+ case MEMCACHED_CONNECTION_UNKNOWN:
+ case MEMCACHED_CONNECTION_UDP:
+ WATCHPOINT_ASSERT(0);
+ possible_rc= MEMCACHED_NOT_SUPPORTED;
+ break;
+ case MEMCACHED_CONNECTION_TCP:
+ possible_rc= tcp_connect(ptr, x);
+ break;
+ case MEMCACHED_CONNECTION_UNIX_SOCKET:
+ possible_rc= unix_socket_connect(ptr, x);
+ break;
+ }
rc= MEMCACHED_SUCCESS;
if (possible_rc != MEMCACHED_SUCCESS)
#include <memcached.h>
#include "common.h"
-static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port)
+/* Protoypes (static) */
+static memcached_return server_add(memcached_st *ptr, char *hostname,
+ unsigned int port,
+ memcached_connection type);
+
+static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port,
+ memcached_connection type)
{
host->stack_responses= 0;
host->cursor_active= 0;
host->hostname= new_hostname;
host->port= port;
host->fd= -1;
+ host->type= type;
}
memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list)
ptr->hosts[ptr->number_of_hosts].fd= list[x].fd;
ptr->hosts[ptr->number_of_hosts].stack_responses= list[x].stack_responses;
ptr->hosts[ptr->number_of_hosts].cursor_active= list[x].cursor_active;
+ ptr->hosts[ptr->number_of_hosts].type= list[x].type;
ptr->number_of_hosts++;
}
- host_reset(&ptr->hosts[ptr->number_of_hosts], NULL, 0);
+ host_reset(&ptr->hosts[ptr->number_of_hosts], NULL, 0,
+ MEMCACHED_CONNECTION_UNKNOWN);
return MEMCACHED_SUCCESS;
}
-memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port)
+memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filename)
{
- memcached_server_st *new_host_list;
- char *new_hostname;
- LIBMEMCACHED_MEMCACHED_SERVER_ADD_START();
+ if (!filename)
+ return MEMCACHED_FAILURE;
+
+ return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET);
+}
+memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port)
+{
if (!port)
port= MEMCACHED_DEFAULT_PORT;
if (!hostname)
hostname= "localhost";
+ return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_TCP);
+}
+
+static memcached_return server_add(memcached_st *ptr, char *hostname,
+ unsigned int port,
+ memcached_connection type)
+{
+ memcached_server_st *new_host_list;
+ char *new_hostname;
+ LIBMEMCACHED_MEMCACHED_SERVER_ADD_START();
+
if (ptr->number_of_hosts)
{
sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
if (!new_host_list)
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- host_reset(&new_host_list[ptr->number_of_hosts], NULL, 0);
+ host_reset(&new_host_list[ptr->number_of_hosts], NULL, 0,
+ MEMCACHED_CONNECTION_UNKNOWN);
}
else
{
(memcached_server_st *)malloc(sizeof(memcached_server_st) * 2);
if (!new_host_list)
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- host_reset(&new_host_list[0], NULL, 0);
- host_reset(&new_host_list[1], NULL, 0);
+ host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
+ host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
}
ptr->hosts= new_host_list;
memset(new_hostname, 0, strlen(hostname)+1);
memcpy(new_hostname, hostname, strlen(hostname));
- host_reset(&ptr->hosts[ptr->number_of_hosts], new_hostname, port);
+ host_reset(&ptr->hosts[ptr->number_of_hosts], new_hostname, port, type);
ptr->number_of_hosts++;
LIBMEMCACHED_MEMCACHED_SERVER_ADD_END();
new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count);
if (!new_host_list)
goto error;
- host_reset(&new_host_list[count-1], NULL, 0);
+ host_reset(&new_host_list[count-1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
}
else
{
new_host_list= (memcached_server_st *)malloc(sizeof(memcached_server_st) * count);
if (!new_host_list)
goto error;
- host_reset(&new_host_list[0], NULL, 0);
- host_reset(&new_host_list[1], NULL, 0);
+ host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
+ host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
}
new_hostname= strdup(hostname);
if (!new_hostname)
goto error;
- host_reset(&new_host_list[count-2], new_hostname, port);
+ host_reset(&new_host_list[count-2], new_hostname, port, MEMCACHED_CONNECTION_TCP);
*error= MEMCACHED_SUCCESS;
return new_host_list;
return "STAT VALUE";
case MEMCACHED_ERRNO:
return "SYSTEM ERROR";
+ case MEMCACHED_FAIL_UNIX_SOCKET:
+ return "COULD NOT OPEN UNIX SOCKET";
+ case MEMCACHED_NOT_SUPPORTED:
+ return "ACTION NOT SUPPORTED";
case MEMCACHED_MAXIMUM_RETURN:
return "Gibberish returned!";
default:
Error 23 -> SERVER VALUE
Error 24 -> STAT VALUE
Error 25 -> SYSTEM ERROR
+Error 26 -> COULD NOT UNIX SOCKET
+Error 27 -> ACTION NOT SUPPORTED
Found key pid
Found key uptime
Found key time
Error 23 -> SERVER VALUE
Error 24 -> STAT VALUE
Error 25 -> SYSTEM ERROR
+Error 26 -> COULD NOT UNIX SOCKET
+Error 27 -> ACTION NOT SUPPORTED
Found key pid
Found key uptime
Found key time
Error 23 -> SERVER VALUE
Error 24 -> STAT VALUE
Error 25 -> SYSTEM ERROR
+Error 26 -> COULD NOT UNIX SOCKET
+Error 27 -> ACTION NOT SUPPORTED
Found key pid
Found key uptime
Found key time
Error 23 -> SERVER VALUE
Error 24 -> STAT VALUE
Error 25 -> SYSTEM ERROR
+Error 26 -> COULD NOT UNIX SOCKET
+Error 27 -> ACTION NOT SUPPORTED
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Error 0 -> SUCCESS
+Error 1 -> FAILURE
+Error 2 -> HOSTNAME LOOKUP FAILURE
+Error 3 -> CONNECTION FAILURE
+Error 4 -> CONNECTION BIND FAILURE
+Error 5 -> WRITE FAILURE
+Error 6 -> READ FAILURE
+Error 7 -> UNKNOWN READ FAILURE
+Error 8 -> PROTOCOL ERROR
+Error 9 -> CLIENT ERROR
+Error 10 -> SERVER ERROR
+Error 11 -> CONNECTION SOCKET CREATE FAILURE
+Error 12 -> CONNECTION DATA EXISTS
+Error 13 -> CONNECTION DATA DOES NOT EXIST
+Error 14 -> NOT STORED
+Error 15 -> STORED
+Error 16 -> NOT FOUND
+Error 17 -> MEMORY ALLOCATION FAILURE
+Error 18 -> PARTIAL READ
+Error 19 -> SOME ERRORS WERE REPORTED
+Error 20 -> NO SERVERS DEFINED
+Error 21 -> SERVER END
+Error 22 -> SERVER DELETE
+Error 23 -> SERVER VALUE
+Error 24 -> STAT VALUE
+Error 25 -> SYSTEM ERROR
+Error 26 -> COULD NOT UNIX SOCKET
+Error 27 -> ACTION NOT SUPPORTED
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Error 0 -> SUCCESS
+Error 1 -> FAILURE
+Error 2 -> HOSTNAME LOOKUP FAILURE
+Error 3 -> CONNECTION FAILURE
+Error 4 -> CONNECTION BIND FAILURE
+Error 5 -> WRITE FAILURE
+Error 6 -> READ FAILURE
+Error 7 -> UNKNOWN READ FAILURE
+Error 8 -> PROTOCOL ERROR
+Error 9 -> CLIENT ERROR
+Error 10 -> SERVER ERROR
+Error 11 -> CONNECTION SOCKET CREATE FAILURE
+Error 12 -> CONNECTION DATA EXISTS
+Error 13 -> CONNECTION DATA DOES NOT EXIST
+Error 14 -> NOT STORED
+Error 15 -> STORED
+Error 16 -> NOT FOUND
+Error 17 -> MEMORY ALLOCATION FAILURE
+Error 18 -> PARTIAL READ
+Error 19 -> SOME ERRORS WERE REPORTED
+Error 20 -> NO SERVERS DEFINED
+Error 21 -> SERVER END
+Error 22 -> SERVER DELETE
+Error 23 -> SERVER VALUE
+Error 24 -> STAT VALUE
+Error 25 -> SYSTEM ERROR
+Error 26 -> COULD NOT UNIX SOCKET
+Error 27 -> ACTION NOT SUPPORTED
Found key pid
Found key uptime
Found key time
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <time.h>
#include "../lib/common.h"
memcached_server_list_free(servers);
}
-void pre_nonblock(memcached_st *memc)
+memcached_return pre_nonblock(memcached_st *memc)
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL);
+
+ return MEMCACHED_SUCCESS;
}
-void pre_md5(memcached_st *memc)
+memcached_return pre_md5(memcached_st *memc)
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_MD5_HASHING, NULL);
+
+ return MEMCACHED_SUCCESS;
}
-void pre_crc(memcached_st *memc)
+memcached_return pre_crc(memcached_st *memc)
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CRC_HASHING, NULL);
+
+ return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_unix_socket(memcached_st *memc)
+{
+ memcached_return rc;
+ struct stat buf;
+
+ memcached_server_list_free(memc->hosts);
+ memc->hosts= NULL;
+ memc->number_of_hosts= 0;
+
+ if (stat("/tmp/memcached.socket", &buf))
+ return MEMCACHED_FAILURE;
+
+ rc= memcached_server_add_unix_socket(memc, "/tmp/memcached.socket");
+
+ return rc;
}
-void pre_nodelay(memcached_st *memc)
+memcached_return pre_nodelay(memcached_st *memc)
{
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL);
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, NULL);
+
+ return MEMCACHED_SUCCESS;
}
typedef struct collection_st collection_st;
struct collection_st {
char *name;
- void (*pre)(memcached_st *memc);
- void (*post)(memcached_st *memc);
+ memcached_return (*pre)(memcached_st *memc);
+ memcached_return (*post)(memcached_st *memc);
test_st *tests;
};
{"nodelay", pre_nodelay, 0, tests},
{"md5", pre_md5, 0, tests},
{"crc", pre_crc, 0, tests},
+ {"unix_socket", pre_unix_socket, 0, tests},
{"string", 0, 0, string_tests},
{"user", 0, 0, user_tests},
{0, 0, 0, 0}
}
if (next->pre)
- next->pre(memc);
+ {
+ memcached_return rc;
+ rc= next->pre(memc);
+
+ if (rc != MEMCACHED_SUCCESS)
+ {
+ fprintf(stderr, "\t\t\t\t\t [ skipping ]\n");
+ goto error;
+ }
+ }
gettimeofday(&start_time, NULL);
run->function(memc);
load_time % 1000);
if (next->post)
- next->post(memc);
+ (void)next->post(memc);
assert(memc);
+error:
memcached_free(memc);
}
}