* 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 <libmemcached/protocol_handler.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;
}
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)
{
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, "v1p:?")) != EOF)
{
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;