diff options
author | Rickard Green <[email protected]> | 2016-09-06 12:16:20 +0200 |
---|---|---|
committer | Rickard Green <[email protected]> | 2016-09-06 12:16:20 +0200 |
commit | 02c9a648db3753008e67f22140a2bf8dd8912ccd (patch) | |
tree | 9bdd44eca190e1d186e77033f38c56c25cd8ce55 /erts/emulator/beam/io.c | |
parent | dd2919dc29d3eb0d287522c7485bf42343173937 (diff) | |
parent | 1c969304d4df4ad22c0089100a071bcb1dca4275 (diff) | |
download | otp-02c9a648db3753008e67f22140a2bf8dd8912ccd.tar.gz otp-02c9a648db3753008e67f22140a2bf8dd8912ccd.tar.bz2 otp-02c9a648db3753008e67f22140a2bf8dd8912ccd.zip |
Merge branch 'rickard/drv-send-term-thr-bug/OTP-13866' into maint
* rickard/drv-send-term-thr-bug/OTP-13866:
Fix thread calls to erl_drv_send_term()/erl_drv_output_term()
Conflicts:
erts/emulator/beam/io.c
Diffstat (limited to 'erts/emulator/beam/io.c')
-rw-r--r-- | erts/emulator/beam/io.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index cb8792dffa..77dbe92241 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -6591,16 +6591,20 @@ deliver_term_check_port(ErlDrvTermData port_id, Eterm *connected_p, ErtsThrPrgrDelayHandle dhndl = erts_thr_progress_unmanaged_delay(); #endif erts_aint32_t state; + int res = 1; Port *prt = erts_port_lookup_raw((Eterm) port_id); - if (!prt) - return -1; + if (!prt) { + res = -1; + goto done; + } state = erts_atomic32_read_nob(&prt->state); if (state & (ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP | ERTS_PORT_SFLG_CLOSING)) { if (state & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) - return -1; + res = -1; else - return 0; + res = 0; + goto done; } if (connected_p) { #ifdef ERTS_SMP @@ -6609,25 +6613,27 @@ deliver_term_check_port(ErlDrvTermData port_id, Eterm *connected_p, #endif *connected_p = ERTS_PORT_GET_CONNECTED(prt); } + +done: + #ifdef ERTS_SMP if (dhndl != ERTS_THR_PRGR_DHANDLE_MANAGED) { + ERTS_SMP_LC_ASSERT(!prt || !erts_lc_is_port_locked(prt)); erts_thr_progress_unmanaged_continue(dhndl); ETHR_MEMBAR(ETHR_LoadLoad|ETHR_LoadStore); } else #endif - { + if (res == 1) { + ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt)); *trace_prt = prt; } - ERTS_SMP_LC_ASSERT(dhndl == ERTS_THR_PRGR_DHANDLE_MANAGED - ? erts_lc_is_port_locked(prt) - : !erts_lc_is_port_locked(prt)); - return 1; + return res; } int erl_drv_output_term(ErlDrvTermData port_id, ErlDrvTermData* data, int len) { /* May be called from arbitrary thread */ - Eterm connected; + Eterm connected = NIL; /* Shut up faulty warning... */ Port *prt = NULL; int res = deliver_term_check_port(port_id, &connected, &prt); if (res <= 0) |