* the more "logical" interface.
* memcached_light.c - This file sets up all of the sockets and run the main
* message loop.
+ *
+ *
+ * config.h is included so that I can use the ntohll/htonll on platforms that
+ * doesn't have that (this is a private function inside libmemcached, so you
+ * cannot use it directly from libmemcached without special modifications to
+ * the library)
*/
+#include "config.h"
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#include <libmemcached/protocol_handler.h>
-#include "common.h"
+#include <libmemcached/byteorder.h>
#include "storage.h"
+#include "memcached_light.h"
-extern struct memcached_binary_protocol_callback_st interface_v0_impl;
-extern struct memcached_binary_protocol_callback_st interface_v1_impl;
+extern memcached_binary_protocol_callback_st interface_v0_impl;
+extern memcached_binary_protocol_callback_st interface_v1_impl;
static int server_sockets[1024];
static int num_server_sockets= 0;
static void* socket_userdata_map[1024];
+static bool verbose= false;
/**
* Create a socket and bind it to a specific port number
}
if ((flags & O_NONBLOCK) != O_NONBLOCK)
+ {
if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
{
perror("Failed to set socket to nonblocking mode");
close(sock);
continue;
}
+ }
flags= 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)) != 0)
/**
* Print out the command we are about to execute
*/
-static void pre_execute(const void *cookie, protocol_binary_request_header *header)
+static void pre_execute(const void *cookie __attribute__((unused)),
+ protocol_binary_request_header *header __attribute__((unused)))
{
- const char *cmd= comcode2str(header->request.opcode);
- if (cmd != NULL)
- fprintf(stderr, "pre_execute from %p: %s\n", cookie, cmd);
- else
- fprintf(stderr, "pre_execute from %p: 0x%02x\n", cookie, header->request.opcode);
+ if (verbose)
+ {
+ const char *cmd= comcode2str(header->request.opcode);
+ if (cmd != NULL)
+ fprintf(stderr, "pre_execute from %p: %s\n", cookie, cmd);
+ else
+ fprintf(stderr, "pre_execute from %p: 0x%02x\n", cookie, header->request.opcode);
+ }
}
/**
* Print out the command we just executed
*/
-static void post_execute(const void *cookie, protocol_binary_request_header *header)
+static void post_execute(const void *cookie __attribute__((unused)),
+ protocol_binary_request_header *header __attribute__((unused)))
{
- const char *cmd= comcode2str(header->request.opcode);
- if (cmd != NULL)
- fprintf(stderr, "post_execute from %p: %s\n", cookie, cmd);
- else
- fprintf(stderr, "post_execute from %p: 0x%02x\n", cookie, header->request.opcode);
+ if (verbose)
+ {
+ const char *cmd= comcode2str(header->request.opcode);
+ if (cmd != NULL)
+ fprintf(stderr, "post_execute from %p: %s\n", cookie, cmd);
+ else
+ fprintf(stderr, "post_execute from %p: 0x%02x\n", cookie, header->request.opcode);
+ }
}
/**
{
bool port_specified= false;
int cmd;
- struct memcached_binary_protocol_callback_st *interface= &interface_v0_impl;
+ memcached_binary_protocol_callback_st *interface= &interface_v0_impl;
+
+ /*
+ * We need to initialize the handlers manually due to a bug in the
+ * warnings generated by struct initialization in gcc (all the way up to 4.4)
+ */
+ initialize_interface_v0_handler();
- while ((cmd= getopt(argc, argv, "1p:?")) != EOF)
+ while ((cmd= getopt(argc, argv, "v1p:?")) != EOF)
{
switch (cmd) {
case '1':
port_specified= true;
(void)server_socket(optarg);
break;
+ case 'v':
+ verbose= true;
+ break;
case '?': /* FALLTHROUGH */
default:
- (void)fprintf(stderr, "Usage: %s [-p port]\n", argv[0]);
+ (void)fprintf(stderr, "Usage: %s [-p port] [-v] [-1]\n", argv[0]);
return 1;
}
}
+ if (!initialize_storage())
+ {
+ /* Error message already printed */
+ return 1;
+ }
+
if (!port_specified)
(void)server_socket("9999");
interface->post_execute= post_execute;
interface->unknown= unknown;
- struct memcached_binary_protocol_st *protocol_handle;
- if ((protocol_handle= memcached_binary_protocol_create_instance()) == NULL)
+ struct memcached_protocol_st *protocol_handle;
+ if ((protocol_handle= memcached_protocol_create_instance()) == NULL)
{
fprintf(stderr, "Failed to allocate protocol handle\n");
return 1;
return 0;
}
-static void work(void) {
+static void work(void)
+{
#define MAX_SERVERS_TO_POLL 100
struct pollfd fds[MAX_SERVERS_TO_POLL];
int max_poll;
continue;
}
- struct memcached_binary_protocol_st *protocol;
+ struct memcached_protocol_st *protocol;
protocol= socket_userdata_map[fds[x].fd];
- struct memcached_binary_protocol_client_st* c;
- c= memcached_binary_protocol_create_client(protocol, sock);
+ struct memcached_protocol_client_st* c;
+ c= memcached_protocol_create_client(protocol, sock);
if (c == NULL)
{
fprintf(stderr, "Failed to create client\n");
else
{
/* drive the client */
- struct memcached_binary_protocol_client_st* c;
+ struct memcached_protocol_client_st* c;
c= socket_userdata_map[fds[x].fd];
assert(c != NULL);
fds[max_poll].events= 0;
- switch (memcached_binary_protocol_client_work(c))
- {
- case WRITE_EVENT:
- case READ_WRITE_EVENT:
+ memcached_protocol_event_t events= memcached_protocol_client_work(c);
+ if (events & MEMCACHED_PROTOCOL_WRITE_EVENT)
fds[max_poll].events= POLLOUT;
- /* FALLTHROUGH */
- case READ_EVENT:
- fds[max_poll].events |= POLLIN;
- break;
- case ERROR_EVENT:
- default: /* ERROR or unknown state.. close */
- memcached_binary_protocol_client_destroy(c);
+
+ if (events & MEMCACHED_PROTOCOL_READ_EVENT)
+ fds[max_poll].events= POLLIN;
+
+ if (!(events & MEMCACHED_PROTOCOL_PAUSE_EVENT ||
+ fds[max_poll].events != 0))
+ {
+ memcached_protocol_client_destroy(c);
close(fds[x].fd);
fds[x].events= 0;