diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2016-11-14 09:39:08 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-14 09:39:08 +1100 |
commit | 370154159bc7e3b06488cbdf7deb0585baf841b6 (patch) | |
tree | 0778da3f34238bd5d23e9c827fdf6d89e6d38b96 | |
parent | 05e9389be80f28a63327d62d3d2e2eb1ecc3e14b (diff) | |
download | mongo-370154159bc7e3b06488cbdf7deb0585baf841b6.tar.gz |
WT-3017 Don't set NULL hazard pointers. (#3141)
-rw-r--r-- | src/support/hazard.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/support/hazard.c b/src/support/hazard.c index b1978dbe97a..27508bbdece 100644 --- a/src/support/hazard.c +++ b/src/support/hazard.c @@ -26,6 +26,7 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, bool *busyp WT_BTREE *btree; WT_CONNECTION_IMPL *conn; WT_HAZARD *hp; + WT_PAGE *page; int restarts = 0; btree = S2BT(session); @@ -37,6 +38,16 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, bool *busyp return (0); /* + * If there isn't a valid page pointer, we're done. This read can race + * with eviction and splits, we re-check it after a barrier to make + * sure we have a valid pointer. + */ + if (ref->state != WT_REF_MEM || (page = ref->page) == NULL) { + *busyp = true; + return (0); + } + + /* * Do the dance: * * The memory location which makes a page "real" is the WT_REF's state @@ -82,7 +93,7 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, bool *busyp if (hp->page != NULL) continue; - hp->page = ref->page; + hp->page = page; #ifdef HAVE_DIAGNOSTIC hp->file = file; hp->line = line; @@ -101,9 +112,12 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, bool *busyp * found this page using the tree's key space, whatever page we * find here is the page for us to use.) */ - if (ref->page == hp->page && ref->state == WT_REF_MEM) { - ++session->nhazard; - return (0); + if (ref->state == WT_REF_MEM) { + WT_READ_BARRIER(); + if (ref->page == page) { + ++session->nhazard; + return (0); + } } /* |