Skip to content

Commit

Permalink
add_delta should return a proper status indicator.
Browse files Browse the repository at this point in the history
Before, it was returning text protocol, requiring special handling in
the binary protocol.
  • Loading branch information
dustin authored and Trond Norbye committed Jun 29, 2009
1 parent cce46e8 commit d044acb
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
41 changes: 32 additions & 9 deletions memcached.c
Expand Up @@ -1031,10 +1031,22 @@ static void complete_incr_bin(conn *c) {
c->binary_header.request.cas == ITEM_get_cas(it))) { c->binary_header.request.cas == ITEM_get_cas(it))) {
/* Weird magic in add_delta forces me to pad here */ /* Weird magic in add_delta forces me to pad here */
char tmpbuf[INCR_MAX_STORAGE_LEN]; char tmpbuf[INCR_MAX_STORAGE_LEN];
char *adrv = add_delta(c, it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT, protocol_binary_response_status st = PROTOCOL_BINARY_RESPONSE_SUCCESS;
req->message.body.delta, tmpbuf);
if (strncmp(adrv, "CLIENT_ERROR", 12) == 0) { switch(add_delta(c, it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT,
write_bin_error(c, PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL, 0); 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 { } else {
rsp->message.body.value = swap64(strtoull(tmpbuf, NULL, 10)); rsp->message.body.value = swap64(strtoull(tmpbuf, NULL, 10));
c->cas = ITEM_get_cas(it); c->cas = ITEM_get_cas(it);
Expand Down Expand Up @@ -2516,7 +2528,17 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
return; 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 */ item_remove(it); /* release our reference */
} }


Expand All @@ -2531,15 +2553,16 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
* *
* returns a response string to send back to the client. * 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; char *ptr;
uint64_t value; uint64_t value;
int res; int res;


ptr = ITEM_data(it); ptr = ITEM_data(it);


if (!safe_strtoull(ptr, &value)) { if (!safe_strtoull(ptr, &value)) {
return "CLIENT_ERROR cannot increment or decrement non-numeric value"; return NON_NUMERIC;
} }


if (incr) { if (incr) {
Expand Down Expand Up @@ -2568,7 +2591,7 @@ char *do_add_delta(conn *c, item *it, const bool incr, const int64_t delta, char
item *new_it; item *new_it;
new_it = do_item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 ); new_it = do_item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 );
if (new_it == 0) { 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), buf, res);
memcpy(ITEM_data(new_it) + res, "\r\n", 2); memcpy(ITEM_data(new_it) + res, "\r\n", 2);
Expand All @@ -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); 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) { static void process_delete_command(conn *c, token_t *tokens, const size_t ntokens) {
Expand Down
11 changes: 7 additions & 4 deletions memcached.h
Expand Up @@ -178,6 +178,9 @@ enum store_item_type {
NOT_STORED=0, STORED, EXISTS, NOT_FOUND 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. */ /** Time relative to server start. Smaller than time_t on 64-bit systems. */
typedef unsigned int rel_time_t; typedef unsigned int rel_time_t;
Expand Down Expand Up @@ -402,8 +405,8 @@ extern volatile rel_time_t current_time;
* Functions * Functions
*/ */
void do_accept_new_conns(const bool do_accept); void do_accept_new_conns(const bool do_accept);
char *do_add_delta(conn *c, item *item, const bool incr, const int64_t delta, enum delta_result_type do_add_delta(conn *c, item *item, const bool incr,
char *buf); const int64_t delta, char *buf);
enum store_item_type do_store_item(item *item, int comm, conn* c); 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); 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); extern int daemonize(int nochdir, int noclose);
Expand All @@ -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); 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. */ /* 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, enum delta_result_type add_delta(conn *c, item *item, const int incr,
char *buf); const int64_t delta, char *buf);
void accept_new_conns(const bool do_accept); void accept_new_conns(const bool do_accept);
conn *conn_from_freelist(void); conn *conn_from_freelist(void);
bool conn_add_to_freelist(conn *c); bool conn_add_to_freelist(conn *c);
Expand Down
6 changes: 3 additions & 3 deletions thread.c
Expand Up @@ -400,9 +400,9 @@ void item_update(item *item) {
/* /*
* Does arithmetic on a numeric item value. * Does arithmetic on a numeric item value.
*/ */
char *add_delta(conn *c, item *item, int incr, const int64_t delta, enum delta_result_type add_delta(conn *c, item *item, int incr,
char *buf) { const int64_t delta, char *buf) {
char *ret; enum delta_result_type ret;


pthread_mutex_lock(&cache_lock); pthread_mutex_lock(&cache_lock);
ret = do_add_delta(c, item, incr, delta, buf); ret = do_add_delta(c, item, incr, delta, buf);
Expand Down

0 comments on commit d044acb

Please sign in to comment.