From 2afd4b7bd03ed2224bc6e1968338585316904a3e Mon Sep 17 00:00:00 2001
From: Zardosht Kasheff <zardosht@tokutek.com>
Date: Wed, 12 Sep 2012 17:44:39 +0000
Subject: [PATCH] closes #5439, fix stress test issue

git-svn-id: file:///svn/toku/tokudb@47702 c7de825b-a66e-492c-adef-691d508d4ae1
---
 ft/cachetable.cc                           | 12 ++++++++++++
 ft/tests/cachetable-clone-partial-fetch.cc |  3 ++-
 ft/tests/cachetable-partial-fetch.cc       |  4 +++-
 ft/tests/cachetable-simple-pin-cheap.cc    |  1 +
 ft/tests/cachetable-simple-read-pin.cc     |  6 ++++++
 5 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/ft/cachetable.cc b/ft/cachetable.cc
index f2fa8e358e..bf16614dba 100644
--- a/ft/cachetable.cc
+++ b/ft/cachetable.cc
@@ -1528,6 +1528,12 @@ static bool try_pin_pair(
             p->value_rwlock.write_lock(false);
             pair_unlock(p);
         }
+        // small hack here for #5439,
+        // for queries, pf_req_callback does some work for the caller,
+        // that information may be out of date after a write_unlock
+        // followed by a relock, so we do it again.
+        bool pf_required = pf_req_callback(p->value_data,read_extraargs);
+        assert(!pf_required);
         ct->list.read_list_lock();
     }
 
@@ -1744,6 +1750,12 @@ beginning:
             p->value_rwlock.write_unlock();
             p->value_rwlock.read_lock();
             pair_unlock(p);
+            // small hack here for #5439,
+            // for queries, pf_req_callback does some work for the caller,
+            // that information may be out of date after a write_unlock
+            // followed by a read_lock, so we do it again.
+            bool pf_required = pf_req_callback(p->value_data,read_extraargs);
+            assert(!pf_required);
         }
         // We need to be holding the read list lock when we exit.
         // We grab it here because we released it earlier to 
diff --git a/ft/tests/cachetable-clone-partial-fetch.cc b/ft/tests/cachetable-clone-partial-fetch.cc
index e49fd3da9e..46f555fe38 100644
--- a/ft/tests/cachetable-clone-partial-fetch.cc
+++ b/ft/tests/cachetable-clone-partial-fetch.cc
@@ -39,7 +39,8 @@ flush (
 }
 
 static bool true_pf_req_callback(void* UU(ftnode_pv), void* UU(read_extraargs)) {
-  return true;
+    if (pf_called) return false;
+    return true;
 }
 
 static int true_pf_callback(void* UU(ftnode_pv), void* UU(dd), void* UU(read_extraargs), int UU(fd), PAIR_ATTR* sizep) {
diff --git a/ft/tests/cachetable-partial-fetch.cc b/ft/tests/cachetable-partial-fetch.cc
index d68566ad7e..fa237c9e40 100644
--- a/ft/tests/cachetable-partial-fetch.cc
+++ b/ft/tests/cachetable-partial-fetch.cc
@@ -53,7 +53,8 @@ static bool pf_req_callback(void* UU(ftnode_pv), void* UU(read_extraargs)) {
 }
 
 static bool true_pf_req_callback(void* UU(ftnode_pv), void* UU(read_extraargs)) {
-  return true;
+    if (pf_req_called) return false;
+    return true;
 }
 
 static int err_pf_callback(void* UU(ftnode_pv), void* UU(dd), void* UU(read_extraargs), int UU(fd), PAIR_ATTR* UU(sizep)) {
@@ -156,6 +157,7 @@ cachetable_test (void) {
     //
     // now verify a prefetch that requires a partial fetch works, and that we can then pin the node
     //
+    pf_req_called = false;
     r = toku_cachefile_prefetch(
         f1,
         make_blocknum(1),
diff --git a/ft/tests/cachetable-simple-pin-cheap.cc b/ft/tests/cachetable-simple-pin-cheap.cc
index d5b13acfa7..1ec2c6fceb 100644
--- a/ft/tests/cachetable-simple-pin-cheap.cc
+++ b/ft/tests/cachetable-simple-pin-cheap.cc
@@ -7,6 +7,7 @@
 
 bool pf_called;
 static bool true_pf_req_callback(void* UU(ftnode_pv), void* UU(read_extraargs)) {
+  if (pf_called) return false;
   return true;
 }
 
diff --git a/ft/tests/cachetable-simple-read-pin.cc b/ft/tests/cachetable-simple-read-pin.cc
index 31874d436e..b110e77c65 100644
--- a/ft/tests/cachetable-simple-read-pin.cc
+++ b/ft/tests/cachetable-simple-read-pin.cc
@@ -30,6 +30,8 @@ sleep_fetch (CACHEFILE f        __attribute__((__unused__)),
 }
 
 static bool sleep_pf_req_callback(void* UU(ftnode_pv), void* UU(read_extraargs)) {
+    if (pf_called || fetch_called) return false;
+    return true;
   return true;
 }
 
@@ -44,6 +46,8 @@ static void *run_expensive_pf(void *arg) {
     void* v1;
     long s1;
     CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
+    pf_called = false;
+    fetch_called = false;
     int r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, sleep_pf_req_callback, sleep_pf_callback, false, NULL);
     assert_zero(r);
     assert(pf_called);
@@ -54,6 +58,8 @@ static void *run_expensive_fetch(void *arg) {
     void* v1;
     long s1;
     CACHETABLE_WRITE_CALLBACK wc = def_write_callback(NULL);
+    pf_called = false;
+    fetch_called = false;
     int r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, sleep_pf_req_callback, sleep_pf_callback, false, NULL);
     assert_zero(r);
     assert(fetch_called);
-- 
2.30.9