diff options
author | Sverker Eriksson <[email protected]> | 2018-10-22 16:06:51 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2018-10-23 12:36:29 +0200 |
commit | de75be217596ec07ea42b03b701430cf2ae5260a (patch) | |
tree | 996a622034ebdc3b71aa0361b8ce3e9cf526be4c /erts/emulator/beam/erl_db_catree.c | |
parent | 822b60430eeae0ae32aca52019762566fec1acce (diff) | |
download | otp-de75be217596ec07ea42b03b701430cf2ae5260a.tar.gz otp-de75be217596ec07ea42b03b701430cf2ae5260a.tar.bz2 otp-de75be217596ec07ea42b03b701430cf2ae5260a.zip |
erts: Fix faulty assert in catree_find_nextprev_root
It's possible to first find an empty base node
and then retry and find the same base node as invalid.
It's a benign race with join which first makes the old invalid
'neighbor' accessible from 'gparent' before replacing it with
'new_neighbor'.
Diffstat (limited to 'erts/emulator/beam/erl_db_catree.c')
-rw-r--r-- | erts/emulator/beam/erl_db_catree.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c index c3bebefbdf..bc058dcf18 100644 --- a/erts/emulator/beam/erl_db_catree.c +++ b/erts/emulator/beam/erl_db_catree.c @@ -96,6 +96,12 @@ #include "erl_db_tree.h" #include "erl_db_tree_util.h" +#ifdef DEBUG +# define IF_DEBUG(X) X +#else +# define IF_DEBUG(X) +#endif + /* ** Forward declarations */ @@ -1647,7 +1653,8 @@ TreeDbTerm** catree_find_nextprev_root(CATreeRootIterator *iter, int next, Eterm *keyp) { #ifdef DEBUG - DbTableCATreeNode *rejected_base = NULL; + DbTableCATreeNode *rejected_invalid = NULL; + DbTableCATreeNode *rejected_empty = NULL; #endif DbTableCATreeNode *node; DbTableCATreeNode *parent; @@ -1689,9 +1696,10 @@ TreeDbTerm** catree_find_nextprev_root(CATreeRootIterator *iter, int next, } } } - ASSERT(node != rejected_base); + ASSERT(node != rejected_invalid); lock_iter_base_node(iter, node, parent, current_level); if (node->u.base.is_valid) { + ASSERT(node != rejected_empty); if (node->u.base.root) { iter->next_route_key = (next_route_node ? next_route_node->u.route.key.term : @@ -1704,12 +1712,13 @@ TreeDbTerm** catree_find_nextprev_root(CATreeRootIterator *iter, int next, return NULL; } key = next_route_node->u.route.key.term; + IF_DEBUG(rejected_empty = node); } + else + IF_DEBUG(rejected_invalid = node); + /* Retry */ unlock_iter_base_node(iter); -#ifdef DEBUG - rejected_base = node; -#endif } } |