aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_db_catree.c
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2018-10-22 16:06:51 +0200
committerSverker Eriksson <[email protected]>2018-10-23 12:36:29 +0200
commitde75be217596ec07ea42b03b701430cf2ae5260a (patch)
tree996a622034ebdc3b71aa0361b8ce3e9cf526be4c /erts/emulator/beam/erl_db_catree.c
parent822b60430eeae0ae32aca52019762566fec1acce (diff)
downloadotp-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.c19
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
}
}