diff options
Diffstat (limited to 'erts/emulator/beam/io.c')
-rw-r--r-- | erts/emulator/beam/io.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 7e49e9c48f..ebff564421 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -4192,8 +4192,8 @@ static void sweep_one_monitor(ErtsMonitor *mon, void *vpsc) ErtsMonitor *rmon; Process *rp; - ASSERT(is_internal_pid(mon->pid)); - rp = erts_pid2proc(NULL, 0, mon->pid, ERTS_PROC_LOCK_LINK); + ASSERT(is_internal_pid(mon->u.pid)); + rp = erts_pid2proc(NULL, 0, mon->u.pid, ERTS_PROC_LOCK_LINK); if (!rp) { goto done; } @@ -4294,7 +4294,7 @@ port_fire_one_monitor(ErtsMonitor *mon, void *ctx0) Process *origin; ErtsProcLocks origin_locks; - if (mon->type != MON_TARGET || ! is_pid(mon->pid)) { + if (mon->type != MON_TARGET || ! is_pid(mon->u.pid)) { return; } /* @@ -4303,7 +4303,7 @@ port_fire_one_monitor(ErtsMonitor *mon, void *ctx0) */ origin_locks = ERTS_PROC_LOCKS_MSG_SEND | ERTS_PROC_LOCK_LINK; - origin = erts_pid2proc(NULL, 0, mon->pid, origin_locks); + origin = erts_pid2proc(NULL, 0, mon->u.pid, origin_locks); if (origin) { DeclareTmpHeapNoproc(lhp,3); SweepContext *ctx = (SweepContext *)ctx0; @@ -4882,10 +4882,16 @@ erts_port_control(Process* c_p, ASSERT(!tmp_alloced); if (*ebinp == HEADER_SUB_BIN) ebinp = binary_val(((ErlSubBin *) ebinp)->orig); + if (*ebinp != HEADER_PROC_BIN) copy = 1; else { - binp = ((ProcBin *) ebinp)->val; + ProcBin *pb = (ProcBin *) ebinp; + + if (pb->flags) + erts_emasculate_writable_binary(pb); + + binp = pb->val; ASSERT(bufp <= bufp + size); ASSERT(binp->orig_bytes <= bufp && bufp + size <= binp->orig_bytes + binp->orig_size); @@ -5485,7 +5491,7 @@ typedef struct { static void prt_one_monitor(ErtsMonitor *mon, void *vprtd) { prt_one_lnk_data *prtd = (prt_one_lnk_data *) vprtd; - erts_print(prtd->to, prtd->arg, "(%T,%T)", mon->pid,mon->ref); + erts_print(prtd->to, prtd->arg, "(%T,%T)", mon->u.pid, mon->ref); } static void prt_one_lnk(ErtsLink *lnk, void *vprtd) @@ -7607,12 +7613,23 @@ erl_drv_convert_time_unit(ErlDrvTime val, (int) to); } -static void ref_to_driver_monitor(Eterm ref, ErlDrvMonitor *mon) +void erts_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)); } +Eterm erts_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, @@ -7637,7 +7654,7 @@ static int do_driver_monitor_process(Port *prt, erts_add_monitor(&ERTS_P_MONITORS(rp), MON_TARGET, ref, prt->common.id, NIL); erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK); - ref_to_driver_monitor(ref,monitor); + erts_ref_to_driver_monitor(ref,monitor); return 0; } @@ -7669,20 +7686,19 @@ 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 = erts_driver_monitor_to_ref(heap, monitor); mon = erts_lookup_monitor(ERTS_P_MONITORS(prt), ref); if (mon == NULL) { return 1; } ASSERT(mon->type == MON_ORIGIN); - to = mon->pid; + to = mon->u.pid; ASSERT(is_internal_pid(to)); rp = erts_pid2proc_opt(NULL, 0, @@ -7731,16 +7747,15 @@ 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 = erts_driver_monitor_to_ref(heap, monitor); mon = erts_lookup_monitor(ERTS_P_MONITORS(prt), ref); if (mon == NULL) { return driver_term_nil; } ASSERT(mon->type == MON_ORIGIN); - to = mon->pid; + to = mon->u.pid; ASSERT(is_internal_pid(to)); return (ErlDrvTermData) to; } @@ -7767,12 +7782,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) @@ -7792,7 +7806,7 @@ void erts_fire_port_monitor(Port *prt, Eterm ref) } callback = prt->drv_ptr->process_exit; ASSERT(callback != NULL); - ref_to_driver_monitor(ref,&drv_monitor); + erts_ref_to_driver_monitor(ref,&drv_monitor); ERTS_MSACC_SET_STATE_CACHED_M(ERTS_MSACC_STATE_PORT); DRV_MONITOR_UNLOCK_PDL(prt); #ifdef USE_VM_PROBES |