aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2017-02-20 17:36:25 +0100
committerSverker Eriksson <[email protected]>2017-02-20 17:36:25 +0100
commit32a74e6c83cd110b8e8ab714be4365c0da558fca (patch)
treeeed8a3984dc3a4a97955f3d3706b7467a4abd8e6 /erts/emulator
parent8beb8c6c11bec528d00125634bdebe38cc1b8d26 (diff)
parent7dc39b7f02bf1e12541e91298a44d09d052d8fde (diff)
downloadotp-32a74e6c83cd110b8e8ab714be4365c0da558fca.tar.gz
otp-32a74e6c83cd110b8e8ab714be4365c0da558fca.tar.bz2
otp-32a74e6c83cd110b8e8ab714be4365c0da558fca.zip
Merge branch 'rickard/magic-references-fixes'
* rickard/magic-references-fixes: Fix driver monitor implementation Handle magic refs in db_cleanup_offheap_comp()
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/erl_db_util.c5
-rw-r--r--erts/emulator/beam/io.c26
2 files changed, 22 insertions, 9 deletions
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 3ac2bdd3d6..6f30b1d3dd 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -3104,6 +3104,11 @@ void db_cleanup_offheap_comp(DbTerm* obj)
erts_erase_fun_entry(u.fun->fe);
}
break;
+ case REF_SUBTAG:
+ ASSERT(is_magic_ref_thing(u.hdr));
+ if (erts_refc_dectest(&u.mref->mb->refc, 0) == 0)
+ erts_bin_free((Binary *)u.mref->mb);
+ break;
default:
ASSERT(is_external_header(u.hdr->thing_word));
ASSERT(u.pb != &tmp);
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 7e49e9c48f..e0cc756887 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -7609,10 +7609,21 @@ erl_drv_convert_time_unit(ErlDrvTime val,
static void ref_to_driver_monitor(Eterm ref, ErlDrvMonitor *mon)
{
- ERTS_CT_ASSERT(sizeof(ErtsOIRefStorage) <= sizeof(ErlDrvMonitor));
- erts_oiref_storage_save((ErtsOIRefStorage *) mon, ref);
+ ERTS_CT_ASSERT(ERTS_REF_THING_SIZE*sizeof(Uint) <= sizeof(ErlDrvMonitor));
+ ASSERT(is_internal_ordinary_ref(ref));
+ sys_memcpy((void *) mon, (void *) internal_ref_val(ref),
+ ERTS_REF_THING_SIZE*sizeof(Uint));
}
+static Eterm driver_monitor_to_ref(Eterm *hp, const ErlDrvMonitor *mon)
+{
+ Eterm ref;
+ ERTS_CT_ASSERT(ERTS_REF_THING_SIZE*sizeof(Uint) <= sizeof(ErlDrvMonitor));
+ sys_memcpy((void *) hp, (void *) mon, ERTS_REF_THING_SIZE*sizeof(Uint));
+ ref = make_internal_ref(hp);
+ ASSERT(is_internal_ordinary_ref(ref));
+ return ref;
+}
static int do_driver_monitor_process(Port *prt,
ErlDrvTermData process,
@@ -7669,13 +7680,12 @@ int driver_monitor_process(ErlDrvPort drvport,
static int do_driver_demonitor_process(Port *prt, const ErlDrvMonitor *monitor)
{
Eterm heap[ERTS_REF_THING_SIZE];
- Eterm *hp = &heap[0];
Process *rp;
Eterm ref;
ErtsMonitor *mon;
Eterm to;
- ref = erts_oiref_storage_make_ref((ErtsOIRefStorage *) monitor, &hp),
+ ref = driver_monitor_to_ref(heap, monitor);
mon = erts_lookup_monitor(ERTS_P_MONITORS(prt), ref);
if (mon == NULL) {
@@ -7731,9 +7741,8 @@ static ErlDrvTermData do_driver_get_monitored_process(Port *prt,const ErlDrvMoni
ErtsMonitor *mon;
Eterm to;
Eterm heap[ERTS_REF_THING_SIZE];
- Eterm *hp = &heap[0];
- ref = erts_oiref_storage_make_ref((ErtsOIRefStorage *) monitor, &hp),
+ ref = driver_monitor_to_ref(heap, monitor);
mon = erts_lookup_monitor(ERTS_P_MONITORS(prt), ref);
if (mon == NULL) {
@@ -7767,12 +7776,11 @@ ErlDrvTermData driver_get_monitored_process(ErlDrvPort drvport,
return ret;
}
-
int driver_compare_monitors(const ErlDrvMonitor *monitor1,
const ErlDrvMonitor *monitor2)
{
- return erts_oiref_storage_cmp((ErtsOIRefStorage *) monitor1,
- (ErtsOIRefStorage *) monitor2);
+ return sys_memcmp((void *) monitor1, (void *) monitor2,
+ ERTS_REF_THING_SIZE*sizeof(Eterm));
}
void erts_fire_port_monitor(Port *prt, Eterm ref)