From e2ca71b6e7172b320b5b171359d53a161383fb19 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 6 Feb 2019 19:08:25 +0100 Subject: erts: Fix bug in erts_map_from_ks_and_vs This sleeping bug was introduced in OTP 19.1 but not possible not provoke until OTP 21.0 when enif_make_map_from_arrays was introduced. --- erts/emulator/beam/erl_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index 979a0040b0..b48017d338 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -499,7 +499,7 @@ Eterm erts_hashmap_from_array(ErtsHeapFactory* factory, Eterm *leafs, Uint n, Eterm erts_map_from_ks_and_vs(ErtsHeapFactory *factory, Eterm *ks0, Eterm *vs0, Uint n) { - if (n < MAP_SMALL_MAP_LIMIT) { + if (n <= MAP_SMALL_MAP_LIMIT) { Eterm *ks, *vs, *hp; flatmap_t *mp; Eterm keys; -- cgit v1.2.3 From 2e36105479b300a6c51e21b31e03ded39df8c02b Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 6 Feb 2019 20:00:20 +0100 Subject: erts: Add test for bug in enif_make_maps_from_arrays --- erts/emulator/test/nif_SUITE.erl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'erts') diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index a2f3489943..ca5f90621f 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -1175,6 +1175,15 @@ maps(Config) when is_list(Config) -> M2 = maps_from_list_nif(maps:to_list(M2)), M3 = maps_from_list_nif(maps:to_list(M3)), + %% Test different map sizes (OTP-15567) + repeat_while(fun({35,_}) -> false; + ({K,Map}) -> + Map = maps_from_list_nif(maps:to_list(Map)), + Map = maps:filter(fun(K,V) -> V =:= K*100 end, Map), + {K+1, maps:put(K,K*100,Map)} + end, + {1,#{}}), + has_duplicate_keys = maps_from_list_nif([{1,1},{1,1}]), verify_tmpmem(TmpMem), @@ -2471,6 +2480,13 @@ repeat(0, _, Arg) -> repeat(N, Fun, Arg0) -> repeat(N-1, Fun, Fun(Arg0)). +repeat_while(Fun, Acc0) -> + case Fun(Acc0) of + false -> ok; + Acc1 -> + repeat_while(Fun, Acc1) + end. + check(Exp,Got,Line) -> case Got of Exp -> Exp; -- cgit v1.2.3 From 3f5c2b86b7dcd1d8b5a2eacad92b659ac9709a53 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 6 Feb 2019 20:17:39 +0100 Subject: erts: Fix faulty debug assert in enif_select --- erts/emulator/beam/erl_nif.c | 7 +++++++ erts/emulator/beam/global.h | 3 +++ erts/emulator/sys/common/erl_check_io.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index ee6e6085b6..17041cc91c 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -2354,6 +2354,13 @@ static void dtor_demonitor(ErtsMonitor* mon, void* context) erts_proc_sig_send_demonitor(mon); } +#ifdef DEBUG +int erts_dbg_is_resource_dying(ErtsResource* resource) +{ + return resource->monitors && rmon_is_dying(resource->monitors); +} +#endif + # define NIF_RESOURCE_DTOR &nif_resource_dtor static int nif_resource_dtor(Binary* bin) diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 0631404599..e04ac256df 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -113,6 +113,9 @@ extern Eterm erts_bld_resource_ref(Eterm** hp, ErlOffHeap*, ErtsResource*); extern void erts_pre_nif(struct enif_environment_t*, Process*, struct erl_module_nif*, Process* tracee); extern void erts_post_nif(struct enif_environment_t* env); +#ifdef DEBUG +int erts_dbg_is_resource_dying(ErtsResource*); +#endif extern void erts_resource_stop(ErtsResource*, ErlNifEvent, int is_direct_call); void erts_fire_nif_monitor(ErtsMonitor *tmon); void erts_nif_demonitored(ErtsResource* resource); diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index c681fa481f..1f5c87c523 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -962,7 +962,7 @@ enif_select(ErlNifEnv* env, ErtsDrvSelectDataState *free_select = NULL; ErtsNifSelectDataState *free_nif = NULL; - ASSERT(!resource->monitors); + ASSERT(!erts_dbg_is_resource_dying(resource)); #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS if (!grow_drv_ev_state(fd)) { -- cgit v1.2.3