MEMCACHED_DATA_EXISTS,
MEMCACHED_DATA_DOES_NOT_EXIST,
MEMCACHED_NOTSTORED,
+ MEMCACHED_STORED,
MEMCACHED_NOTFOUND,
MEMCACHED_MEMORY_ALLOCATION_FAILURE,
MEMCACHED_PARTIAL_READ,
MEMCACHED_MAXIMUM_RETURN, /* Always add new error code before */
} memcached_return;
+typedef enum {
+ MEMCACHED_BEHAVIOR_NO_BLOCK,
+} memcached_behavior;
+
typedef enum {
MEMCACHED_NOT_ALLOCATED= 0,
MEMCACHED_ALLOCATED= 1,
unsigned int limit_maxbytes;
};
+#define MEM_NO_BLOCK (1 << 0)
+
struct memcached_string_st {
char *string;
char *end;
size_t write_buffer_offset;
size_t write_between_flush;
char connected;
+ int my_errno;
+ unsigned int stack_responses;
+ unsigned long long flags;
+ memcached_return warning; /* Future Use */
};
/* Public API */
memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity);
void memcached_quit(memcached_st *ptr);
char *memcached_strerror(memcached_st *ptr, memcached_return rc);
+memcached_return memcached_behavior_set(memcached_st *ptr, memcached_behavior flag);
/* All of the functions for adding data to the server */
memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length,
#define WATCHPOINT_ERROR(A) printf("WATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout);
#define WATCHPOINT_STRING(A) printf("WATCHPOINT %s:%d %s\n", __FILE__, __LINE__, A);fflush(stdout);
#define WATCHPOINT_NUMBER(A) printf("WATCHPOINT %s:%d %d\n", __FILE__, __LINE__, A);fflush(stdout);
+#define WATCHPOINT_ERRNO(A) printf("WATCHPOINT %s:%d %s\n", __FILE__, __LINE__, strerror(A));A= 0;fflush(stdout);
#ifdef __cplusplus
lib_LTLIBRARIES = libmemcached.la
libmemcached_la_SOURCES = memcached.c \
memcached_auto.c \
+ memcached_behavior.c \
memcached_connect.c \
memcached_delete.c \
memcached_flush.c \
return MEMCACHED_WRITE_FAILURE;
memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE);
- send_length= read(ptr->hosts[server_key].fd, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE);
+ rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
+
+ /*
+ So why recheck responce? Because the protocol is brain dead :)
+ The number returned might end up equaling one of the string
+ values. Less chance of a mistake with memcmp() so we will
+ use it. We still called memcached_response() though since it
+ worked its magic for non-blocking IO.
+ */
if (!memcmp(buffer, "ERROR\r\n", MEMCACHED_DEFAULT_COMMAND_SIZE))
{
*value= 0;
--- /dev/null
+#include <memcached.h>
+
+memcached_return memcached_behavior_set(memcached_st *ptr, memcached_behavior flag)
+{
+ switch (flag)
+ {
+ case MEMCACHED_BEHAVIOR_NO_BLOCK:
+ ptr->flags|= MEM_NO_BLOCK;
+ break;
+ }
+
+ return MEMCACHED_SUCCESS;
+}
/* Create the socket */
if ((ptr->hosts[0].fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ ptr->my_errno= errno;
return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+ }
/* bind any port number */
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(0);
-#ifdef NOT_YET
/* For the moment, not getting a nonblocking mode will note be fatal */
- flags= fcntl(ptr->hosts[0].fd, F_GETFL, 0);
- if (flags != -1)
- (void)fcntl(ptr->hosts[0].fd, F_SETFL, flags | O_NONBLOCK);
-#endif
+ if (ptr->flags & MEM_NO_BLOCK)
+ {
+ flags= fcntl(ptr->hosts[0].fd, F_GETFL, 0);
+ if (flags != -1)
+ (void)fcntl(ptr->hosts[0].fd, F_SETFL, flags | O_NONBLOCK);
+ }
/* connect to server */
+test_connect:
if (connect(ptr->hosts[0].fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
+ {
+ switch (errno) {
+ /* We are spinning waiting on connect */
+ case EINPROGRESS:
+ case EINTR:
+ goto test_connect;
+ case EISCONN: /* We were spinning waiting on connect */
+ break;
+ default:
+ ptr->my_errno= errno;
return MEMCACHED_HOST_LOCKUP_FAILURE;
+ }
ptr->connected++;
+ }
}
}
LIBMEMCACHED_MEMCACHED_CONNECT_END();
*/
#include "common.h"
+#include "memcached_io.h"
memcached_return memcached_response(memcached_st *ptr,
char *buffer, size_t buffer_length,
return MEMCACHED_SUCCESS;
case 'S': /* STORED STATS SERVER_ERROR */
{
- if (buffer[1] == 'T') /* STORED STATS */
+ if (buffer[2] == 'A') /* STORED STATS */
return MEMCACHED_SUCCESS;
else if (buffer[1] == 'E')
return MEMCACHED_SERVER_ERROR;
+ else if (buffer[1] == 'T')
+ return MEMCACHED_STORED;
else
return MEMCACHED_UNKNOWN_READ_FAILURE;
}
if (rc != MEMCACHED_SUCCESS)
return rc;
+ /* Leaveing this assert in since only a library fubar could blow this */
assert(ptr->write_buffer_offset == 0);
server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
rc= MEMCACHED_WRITE_FAILURE;
goto error;
}
- assert(write_length == sent_length);
/*
We have to flush after sending the command. Memcached is not smart enough
rc= MEMCACHED_WRITE_FAILURE;
goto error;
}
- assert(value_length == sent_length);
if ((sent_length= memcached_io_write(ptr, server_key, "\r\n", 2)) == -1)
{
goto error;
}
- assert(2 == sent_length);
-
if ((sent_length= memcached_io_flush(ptr, server_key)) == -1)
return MEMCACHED_WRITE_FAILURE;
- //assert(sent_length == write_length + value_length + 2);
-
- sent_length= recv(ptr->hosts[server_key].fd, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 0);
+ rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
- if (sent_length && buffer[0] == 'S') /* STORED */
+ if (rc == MEMCACHED_STORED)
return MEMCACHED_SUCCESS;
- else if (write_length && buffer[0] == 'N') /* NOT_STORED */
- return MEMCACHED_NOTSTORED;
- else if (write_length && buffer[0] == 'E') /* ERROR */
- {
- printf("BUFFER :%s:\n", buffer);
- return MEMCACHED_PROTOCOL_ERROR;
- }
- else
- return MEMCACHED_READ_FAILURE;
+ else
+ return rc;
error:
memcached_io_reset(ptr, server_key);
return "CONNECTION DATA DOES NOT EXIST";
case MEMCACHED_NOTSTORED:
return "NOT STORED";
+ case MEMCACHED_STORED:
+ return "STORED";
case MEMCACHED_NOTFOUND:
return "NOT FOUND";
case MEMCACHED_MEMORY_ALLOCATION_FAILURE:
Error 12 -> CONNECTION DATA EXISTS
Error 13 -> CONNECTION DATA DOES NOT EXIST
Error 14 -> NOT STORED
-Error 15 -> NOT FOUND
-Error 16 -> MEMORY ALLOCATION FAILURE
-Error 17 -> PARTIAL READ
-Error 18 -> SOME ERRORS WERE REPORTED
-Error 19 -> NO SERVERS DEFINED
-Error 20 -> SERVER END
-Error 21 -> SERVER DELETE
-Error 22 -> SERVER VALUE
+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
Found key pid
Found key uptime
Found key time