@@ -508,7 +508,12 @@ protocol_binary_response_status KVBucket::evictKey(const DocKey& key,
508508 VBucket::id_type vbucket,
509509 const char ** msg) {
510510 VBucketPtr vb = getVBucket (vbucket);
511- if (!vb || (vb->getState () != vbucket_state_active)) {
511+ if (!vb) {
512+ return PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET;
513+ }
514+
515+ ReaderLockHolder rlh (vb->getStateLock ());
516+ if (vb->getState () != vbucket_state_active) {
512517 return PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET;
513518 }
514519
@@ -1411,34 +1416,26 @@ GetValue KVBucket::getInternal(const DocKey& key,
14111416GetValue KVBucket::getRandomKey () {
14121417 VBucketMap::id_type max = vbMap.getSize ();
14131418
1414- const long start = getRandom () % max;
1419+ const long start = labs ( getRandom () % max) ;
14151420 long curr = start;
14161421 std::unique_ptr<Item> itm;
14171422
1418- while (itm == NULL ) {
1423+ while (true ) {
14191424 VBucketPtr vb = getVBucket (curr++);
1420- while (!vb || vb-> getState () != vbucket_state_active ) {
1421- if (curr == max) {
1422- curr = 0 ;
1423- }
1424- if (curr == start) {
1425- return GetValue ( NULL , ENGINE_KEY_ENOENT) ;
1425+ if (vb ) {
1426+ ReaderLockHolder rlh (vb-> getStateLock ());
1427+ if (vb-> getState () == vbucket_state_active &&
1428+ (itm = vb-> ht . getRandomKey ( getRandom ()))) {
1429+ GetValue rv ( std::move (itm), ENGINE_SUCCESS);
1430+ return rv ;
14261431 }
1427-
1428- vb = getVBucket (curr++);
1429- }
1430-
1431- if ((itm = vb->ht .getRandomKey (getRandom ()))) {
1432- GetValue rv (std::move (itm), ENGINE_SUCCESS);
1433- return rv;
14341432 }
14351433
14361434 if (curr == max) {
14371435 curr = 0 ;
14381436 }
1439-
14401437 if (curr == start) {
1441- return GetValue ( NULL , ENGINE_KEY_ENOENT) ;
1438+ break ;
14421439 }
14431440 // Search next vbucket
14441441 }
@@ -1585,7 +1582,13 @@ GetValue KVBucket::getLocked(const DocKey& key, uint16_t vbucket,
15851582 rel_time_t currentTime, uint32_t lockTimeout,
15861583 const void *cookie) {
15871584 VBucketPtr vb = getVBucket (vbucket);
1588- if (!vb || vb->getState () != vbucket_state_active) {
1585+ if (!vb) {
1586+ ++stats.numNotMyVBuckets ;
1587+ return GetValue (NULL , ENGINE_NOT_MY_VBUCKET);
1588+ }
1589+
1590+ ReaderLockHolder rlh (vb->getStateLock ());
1591+ if (vb->getState () != vbucket_state_active) {
15891592 ++stats.numNotMyVBuckets ;
15901593 return GetValue (NULL , ENGINE_NOT_MY_VBUCKET);
15911594 }
@@ -1612,7 +1615,13 @@ ENGINE_ERROR_CODE KVBucket::unlockKey(const DocKey& key,
16121615{
16131616
16141617 VBucketPtr vb = getVBucket (vbucket);
1615- if (!vb || vb->getState () != vbucket_state_active) {
1618+ if (!vb) {
1619+ ++stats.numNotMyVBuckets ;
1620+ return ENGINE_NOT_MY_VBUCKET;
1621+ }
1622+
1623+ ReaderLockHolder rlh (vb->getStateLock ());
1624+ if (vb->getState () != vbucket_state_active) {
16161625 ++stats.numNotMyVBuckets ;
16171626 return ENGINE_NOT_MY_VBUCKET;
16181627 }
@@ -1667,6 +1676,7 @@ ENGINE_ERROR_CODE KVBucket::getKeyStats(const DocKey& key,
16671676 return ENGINE_NOT_MY_VBUCKET;
16681677 }
16691678
1679+ ReaderLockHolder rlh (vb->getStateLock ());
16701680 { // collections read scope
16711681 auto collectionsRHandle = vb->lockCollections (key);
16721682 if (!collectionsRHandle.valid ()) {
@@ -1679,7 +1689,7 @@ ENGINE_ERROR_CODE KVBucket::getKeyStats(const DocKey& key,
16791689 kstats,
16801690 wantsDeleted,
16811691 collectionsRHandle);
1682- }
1692+ }
16831693}
16841694
16851695std::string KVBucket::validateKey (const DocKey& key, uint16_t vbucket,
@@ -1723,7 +1733,13 @@ ENGINE_ERROR_CODE KVBucket::deleteItem(const DocKey& key,
17231733 ItemMetaData* itemMeta,
17241734 mutation_descr_t & mutInfo) {
17251735 VBucketPtr vb = getVBucket (vbucket);
1726- if (!vb || vb->getState () == vbucket_state_dead) {
1736+ if (!vb) {
1737+ ++stats.numNotMyVBuckets ;
1738+ return ENGINE_NOT_MY_VBUCKET;
1739+ }
1740+
1741+ ReaderLockHolder rlh (vb->getStateLock ());
1742+ if (vb->getState () == vbucket_state_dead) {
17271743 ++stats.numNotMyVBuckets ;
17281744 return ENGINE_NOT_MY_VBUCKET;
17291745 } else if (vb->getState () == vbucket_state_replica) {
0 commit comments