static void asc_process_delete(struct conn *c, struct token *token, int ntoken) { char *key; /* key to be deleted */ size_t nkey; /* # key bytes */ struct item *it; /* item for this key */ asc_set_noreply_maybe(c, token, ntoken); if (!asc_ntoken_valid(c, ntoken)) { log_hexdump(LOG_NOTICE, c->req, c->req_len, "client error on c %d for " "req of type %d with %d invalid tokens", c->sd, c->req_type, ntoken); asc_write_client_error(c); return; } key = token[TOKEN_KEY].val; nkey = token[TOKEN_KEY].len; if (nkey > KEY_MAX_LEN) { log_debug(LOG_NOTICE, "client error on c %d for req of type %d and %d " "length key", c->sd, c->req_type, nkey); asc_write_client_error(c); return; } /* * FIXME: This is not thread-safe, two threads could try to delete the same * item twice after succeeding in item_get, leading to erroneous stats */ it = item_get(key, nkey); if (it != NULL) { stats_slab_incr(it->id, delete_hit); item_delete(it); asc_write_deleted(c); } else { stats_thread_incr(delete_miss); asc_write_not_found(c); } }
static void asc_process_delete(struct conn *c, struct token *token, int ntoken) { char *key; /* key to be deleted */ size_t nkey; /* # key bytes */ struct item *it; /* item for this key */ asc_set_noreply_maybe(c, token, ntoken); if (!asc_ntoken_valid(c, ntoken)) { log_hexdump(LOG_INFO, c->req, c->req_len, "client error on c %d for " "req of type %d with %d invalid tokens", c->sd, c->req_type, ntoken); asc_write_client_error(c); return; } key = token[TOKEN_KEY].val; nkey = token[TOKEN_KEY].len; if (nkey > KEY_MAX_LEN) { log_debug(LOG_INFO, "client error on c %d for req of type %d and %d " "length key", c->sd, c->req_type, nkey); asc_write_client_error(c); return; } it = item_get(key, nkey); if (it != NULL) { stats_slab_incr(it->id, delete_hit); item_unlink(it); item_remove(it); asc_write_deleted(c); } else { stats_thread_incr(delete_miss); asc_write_not_found(c); } }