Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
0516-erts-Fix-ets-rename-during-ets-delete_all_...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0516-erts-Fix-ets-rename-during-ets-delete_all_objects.patch of Package erlang
From 423690db5488fb1c08ea29c2017109edcab76266 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson <sverker@erlang.org> Date: Tue, 11 Oct 2022 20:27:58 +0200 Subject: [PATCH 2/2] erts: Fix ets:rename during ets:delete_all_objects Concurrent ets:rename could cause ets:delete_all_objects to fail halfway through with badarg "the table identifier does not refer to an existing ETS table" --- erts/emulator/beam/erl_db.c | 10 ++++++- erts/emulator/beam/erl_db_util.h | 2 +- lib/stdlib/test/ets_SUITE.erl | 48 +++++++++++++++++++++----------- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 05b21c53e2..db4eb95034 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -2832,15 +2832,23 @@ BIF_RETTYPE ets_internal_delete_all_2(BIF_ALIST_2) * the table and instead pitch in deleting objects * (in delete_all_objects_continue) and then trap to self. */ + Eterm tid; ASSERT((tb->common.status & (DB_PRIVATE|DB_PROTECTED|DB_PUBLIC)) == (tb->common.type & (DB_PRIVATE|DB_PROTECTED|DB_PUBLIC))); tb->common.status &= ~(DB_PRIVATE|DB_PROTECTED|DB_PUBLIC); tb->common.status |= DB_BUSY; db_unlock(tb, LCK_WRITE); + + if (is_atom(BIF_ARG_1)) { + ASSERT(is_table_named(tb)); + tid = make_tid(BIF_P, tb); + } else { + tid = BIF_ARG_1; + } BUMP_ALL_REDS(BIF_P); BIF_TRAP2(BIF_TRAP_EXPORT(BIF_ets_internal_delete_all_2), BIF_P, - BIF_ARG_1, nitems_holder); + tid, nitems_holder); } else { /* Done, no trapping needed */ diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 6ed1e15104..a57febffdb 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -302,7 +302,7 @@ typedef struct db_table_common { UWord heir_data; /* To send in ETS-TRANSFER (is_immed or (DbTerm*) */ Uint64 heir_started_interval; /* To further identify the heir */ Eterm the_name; /* an atom */ - Binary *btid; + Binary *btid; /* table magic ref, read only after creation */ DbTableMethod* meth; /* table methods */ /* The ErtsFlxCtr below contains: * - Total number of items in table diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index a1542247c3..615511471a 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -42,7 +42,7 @@ -export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1]). -export([t_delete_object/1, t_init_table/1, t_whitebox/1, select_bound_chunk/1, t_delete_all_objects/1, t_test_ms/1, - t_delete_all_objects_trap_unfix/1, + t_delete_all_objects_trap/1, t_select_delete/1,t_select_replace/1,t_select_replace_next_bug/1, t_select_pam_stack_overflow_bug/1, t_select_flatmap_term_copy_bug/1, @@ -150,7 +150,7 @@ all() -> match_heavy, {group, fold}, member, t_delete_object, select_bound_chunk, t_init_table, t_whitebox, t_delete_all_objects, - t_delete_all_objects_trap_unfix, + t_delete_all_objects_trap, t_test_ms, t_select_delete, t_select_replace, t_select_replace_next_bug, t_select_pam_stack_overflow_bug, @@ -1041,30 +1041,43 @@ inserter(T, Next, Papa) -> end. -%% Test unfix during delete_all_objects -t_delete_all_objects_trap_unfix(Config) when is_list(Config) -> +%% Poke table during delete_all_objects +t_delete_all_objects_trap(Config) when is_list(Config) -> EtsMem = etsmem(), repeat_for_opts_all_set_table_types( fun(Opts) -> - delete_all_objects_trap_unfix(Opts, unfix), - delete_all_objects_trap_unfix(Opts, exit) + delete_all_objects_trap(Opts, unfix), + delete_all_objects_trap(Opts, exit), + delete_all_objects_trap(Opts, rename) end), verify_etsmem(EtsMem), ok. -delete_all_objects_trap_unfix(Opts, Mode) -> +delete_all_objects_trap(Opts, Mode) -> io:format("Opts = ~p\nMode = ~p\n", [Opts, Mode]), Tester = self(), KeyRange = 50_000, - T=ets_new(x, Opts, KeyRange), + TableName = delete_all_objects_trap, + {Tref,T} = + case Mode of + rename -> + TableName = ets_new(TableName, [named_table,public|Opts], KeyRange), + {ets:whereis(TableName), TableName}; + _ -> + Tid = ets_new(x, Opts, KeyRange), + {Tid,Tid} + end, filltabint(T, KeyRange), KeyRange = ets:info(T,size), FixerFun = fun() -> erlang:trace(Tester, true, [running]), - ets:safe_fixtable(T, true), + case Mode of + rename -> ok; + _ -> ets:safe_fixtable(T, true) + end, io:format("Wait for ets:delete_all_objects/1 to yield...\n", []), - Tester ! {safe_fixtable, self()}, + Tester ! {ready, self()}, repeat_while( fun() -> case receive_any() of @@ -1083,18 +1096,21 @@ delete_all_objects_trap_unfix(Opts, Mode) -> ets:safe_fixtable(T, false); exit -> %%io:format("Exit and do auto-unfix...\n",[]), - exit + exit; + rename -> + %%io:format("Rename table...\n",[]), + renamed = ets:rename(T, renamed) end end, {Fixer, Mon} = spawn_opt(FixerFun, [link, monitor]), - {safe_fixtable, Fixer} = receive_any(), + {ready, Fixer} = receive_any(), true = ets:delete_all_objects(T), Fixer ! "delete_all_objects done", - 0 = ets:info(T,size), + 0 = ets:info(Tref,size), {'DOWN', Mon, process, Fixer, normal} = receive_any(), - 0 = get_kept_objects(T), - false = ets:info(T,safe_fixed), - ets:delete(T), + 0 = get_kept_objects(Tref), + false = ets:info(Tref,safe_fixed), + ets:delete(Tref), ok. -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor