aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_nif.c
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2019-03-19 20:39:17 +0100
committerSverker Eriksson <[email protected]>2019-03-19 20:39:17 +0100
commit9cce1357c3a0d3e13c57a0d9baaeccd249efe136 (patch)
tree51ec9fd8548be7005e369e0878aacda0931c5004 /erts/emulator/beam/erl_nif.c
parent6f97929787126b9c602c769a97a5598e0c35bef4 (diff)
parent6b414fbc67d2c7f703fe677f2acda1a6fa67d8ed (diff)
downloadotp-9cce1357c3a0d3e13c57a0d9baaeccd249efe136.tar.gz
otp-9cce1357c3a0d3e13c57a0d9baaeccd249efe136.tar.bz2
otp-9cce1357c3a0d3e13c57a0d9baaeccd249efe136.zip
Merge branch 'sverker/enif_whereis_pid-dirty-dtor'
into sverker/master/enif_whereis_pid-dirty-dtor
Diffstat (limited to 'erts/emulator/beam/erl_nif.c')
-rw-r--r--erts/emulator/beam/erl_nif.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index af1acbfc90..deaf35c2a1 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1024,7 +1024,7 @@ static Eterm call_whereis(ErlNifEnv *env, Eterm name)
int scheduler;
execution_state(env, &c_p, &scheduler);
- ASSERT((c_p && scheduler) || (!c_p && !scheduler));
+ ASSERT(scheduler || !c_p);
if (scheduler < 0) {
/* dirty scheduler */
@@ -2442,10 +2442,26 @@ int erts_dbg_is_resource_dying(ErtsResource* resource)
}
#endif
-# define NIF_RESOURCE_DTOR &nif_resource_dtor
+#define NIF_RESOURCE_DTOR &nif_resource_dtor_prologue
-static int nif_resource_dtor(Binary* bin)
+static void run_resource_dtor(void* vbin);
+
+static int nif_resource_dtor_prologue(Binary* bin)
{
+ /*
+ * Schedule user resource destructor as aux work to get a context
+ * where we know what locks we have for example.
+ */
+ Uint sched_id = erts_get_scheduler_id();
+ if (!sched_id)
+ sched_id = 1;
+ erts_schedule_misc_aux_work(sched_id, run_resource_dtor, bin);
+ return 0; /* don't free */
+}
+
+static void run_resource_dtor(void* vbin)
+{
+ Binary* bin = (Binary*) vbin;
ErtsResource* resource = (ErtsResource*) ERTS_MAGIC_BIN_UNALIGNED_DATA(bin);
ErlNifResourceType* type = resource->type;
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(bin) == NIF_RESOURCE_DTOR);
@@ -2477,11 +2493,11 @@ static int nif_resource_dtor(Binary* bin)
* If resource->monitors->refc != 0 there are
* outstanding references to the resource from
* monitors that has not been removed yet.
- * nif_resource_dtor() will be called again this
+ * nif_resource_dtor_prologue() will be called again when this
* reference count reach zero.
*/
if (refc != 0)
- return 0; /* we'll be back... */
+ return; /* we'll be back... */
erts_mtx_destroy(&rm->lock);
}
@@ -2498,7 +2514,7 @@ static int nif_resource_dtor(Binary* bin)
steal_resource_type(type);
erts_free(ERTS_ALC_T_NIF, type);
}
- return 1;
+ erts_magic_binary_free((Binary*)vbin);
}
void erts_resource_stop(ErtsResource* resource, ErlNifEvent e,