Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add_delta should return a proper status indicator.

Before, it was returning text protocol, requiring special handling in
the binary protocol.
  • Loading branch information...
commit d044acb2ff52147a2e0296519e8b0df1c96f817b 1 parent cce46e8
@dustin dustin authored Trond Norbye committed
Showing with 42 additions and 16 deletions.
  1. +32 −9 memcached.c
  2. +7 −4 memcached.h
  3. +3 −3 thread.c
View
41 memcached.c
@@ -1031,10 +1031,22 @@ static void complete_incr_bin(conn *c) {
c->binary_header.request.cas == ITEM_get_cas(it))) {
/* Weird magic in add_delta forces me to pad here */
char tmpbuf[INCR_MAX_STORAGE_LEN];
- char *adrv = add_delta(c, it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT,
- req->message.body.delta, tmpbuf);
- if (strncmp(adrv, "CLIENT_ERROR", 12) == 0) {
- write_bin_error(c, PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL, 0);
+ protocol_binary_response_status st = PROTOCOL_BINARY_RESPONSE_SUCCESS;
+
+ switch(add_delta(c, it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT,
+ req->message.body.delta, tmpbuf)) {
+ case OK:
+ break;
+ case NON_NUMERIC:
+ st = PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL;
+ break;
+ case EOM:
+ st = PROTOCOL_BINARY_RESPONSE_ENOMEM;
+ break;
+ }
+
+ if (st != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
+ write_bin_error(c, st, 0);
} else {
rsp->message.body.value = swap64(strtoull(tmpbuf, NULL, 10));
c->cas = ITEM_get_cas(it);
@@ -2516,7 +2528,17 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
return;
}
- out_string(c, add_delta(c, it, incr, delta, temp));
+ switch(add_delta(c, it, incr, delta, temp)) {
+ case OK:
+ out_string(c, temp);
+ break;
+ case NON_NUMERIC:
+ out_string(c, "CLIENT_ERROR cannot increment or decrement non-numeric value");
+ break;
+ case EOM:
+ out_string(c, "SERVER_ERROR out of memory");
+ break;
+ }
item_remove(it); /* release our reference */
}
@@ -2531,7 +2553,8 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
*
* returns a response string to send back to the client.
*/
-char *do_add_delta(conn *c, item *it, const bool incr, const int64_t delta, char *buf) {
+enum delta_result_type do_add_delta(conn *c, item *it, const bool incr,
+ const int64_t delta, char *buf) {
char *ptr;
uint64_t value;
int res;
@@ -2539,7 +2562,7 @@ char *do_add_delta(conn *c, item *it, const bool incr, const int64_t delta, char
ptr = ITEM_data(it);
if (!safe_strtoull(ptr, &value)) {
- return "CLIENT_ERROR cannot increment or decrement non-numeric value";
+ return NON_NUMERIC;
}
if (incr) {
@@ -2568,7 +2591,7 @@ char *do_add_delta(conn *c, item *it, const bool incr, const int64_t delta, char
item *new_it;
new_it = do_item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 );
if (new_it == 0) {
- return "SERVER_ERROR out of memory in incr/decr";
+ return EOM;
}
memcpy(ITEM_data(new_it), buf, res);
memcpy(ITEM_data(new_it) + res, "\r\n", 2);
@@ -2583,7 +2606,7 @@ char *do_add_delta(conn *c, item *it, const bool incr, const int64_t delta, char
memset(ITEM_data(it) + res, ' ', it->nbytes - res - 2);
}
- return buf;
+ return OK;
}
static void process_delete_command(conn *c, token_t *tokens, const size_t ntokens) {
View
11 memcached.h
@@ -178,6 +178,9 @@ enum store_item_type {
NOT_STORED=0, STORED, EXISTS, NOT_FOUND
};
+enum delta_result_type {
+ OK, NON_NUMERIC, EOM
+};
/** Time relative to server start. Smaller than time_t on 64-bit systems. */
typedef unsigned int rel_time_t;
@@ -402,8 +405,8 @@ extern volatile rel_time_t current_time;
* Functions
*/
void do_accept_new_conns(const bool do_accept);
-char *do_add_delta(conn *c, item *item, const bool incr, const int64_t delta,
- char *buf);
+enum delta_result_type do_add_delta(conn *c, item *item, const bool incr,
+ const int64_t delta, char *buf);
enum store_item_type do_store_item(item *item, int comm, conn* c);
conn *conn_new(const int sfd, const enum conn_states init_state, const int event_flags, const int read_buffer_size, enum network_transport transport, struct event_base *base);
extern int daemonize(int nochdir, int noclose);
@@ -429,8 +432,8 @@ int dispatch_event_add(int thread, conn *c);
void dispatch_conn_new(int sfd, enum conn_states init_state, int event_flags, int read_buffer_size, enum network_transport transport);
/* Lock wrappers for cache functions that are called from main loop. */
-char *add_delta(conn *c, item *item, const int incr, const int64_t delta,
- char *buf);
+enum delta_result_type add_delta(conn *c, item *item, const int incr,
+ const int64_t delta, char *buf);
void accept_new_conns(const bool do_accept);
conn *conn_from_freelist(void);
bool conn_add_to_freelist(conn *c);
View
6 thread.c
@@ -400,9 +400,9 @@ void item_update(item *item) {
/*
* Does arithmetic on a numeric item value.
*/
-char *add_delta(conn *c, item *item, int incr, const int64_t delta,
- char *buf) {
- char *ret;
+enum delta_result_type add_delta(conn *c, item *item, int incr,
+ const int64_t delta, char *buf) {
+ enum delta_result_type ret;
pthread_mutex_lock(&cache_lock);
ret = do_add_delta(c, item, incr, delta, buf);
Please sign in to comment.
Something went wrong with that request. Please try again.