summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2012-01-05 13:39:56 -0800
committerdormando <dormando@rydia.net>2012-01-05 13:39:56 -0800
commitb3630e1a2c7eae28d758a3e4786d1c486aa4e258 (patch)
tree2e03ed121c8ce1e39c70b8826fc6f1826c44261e
parent8c1c18eda8f56a23a88ddfe7e9cc3d58e461af22 (diff)
downloadmemcached-b3630e1a2c7eae28d758a3e4786d1c486aa4e258.tar.gz
reap items on read for slab mover
popular items could stuck the slab mover forever, so if a move is in progress, check to see if the item we're fetching should be unlinked instead.
-rw-r--r--items.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/items.c b/items.c
index 7ce6b15..dfcbd8c 100644
--- a/items.c
+++ b/items.c
@@ -484,8 +484,18 @@ void do_item_stats_sizes(ADD_STAT add_stats, void *c) {
item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) {
mutex_lock(&cache_lock);
item *it = assoc_find(key, nkey, hv);
- if (it != NULL)
+ if (it != NULL) {
it->refcount++;
+ /* Optimization for slab reassignment. prevents popular items from
+ * jamming in busy wait. Can only do this here to satisfy lock order
+ * of item_lock, cache_lock, slabs_lock. */
+ if (slab_rebalance_signal &&
+ ((void *)it >= slab_rebal.slab_start && (void *)it < slab_rebal.slab_end)) {
+ it->refcount--;
+ do_item_unlink_nolock(it, hv);
+ it = NULL;
+ }
+ }
pthread_mutex_unlock(&cache_lock);
int was_found = 0;