aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2017-02-01 18:32:22 +0100
committerErlang/OTP <[email protected]>2017-02-01 18:32:22 +0100
commit4925c1a6df409ea9a964cd4c319af3b1c2cf62dd (patch)
tree64322a2b9e79a9d2ed566cce9959962b7c64f01e /erts/emulator
parent7518684155aaabdde97c7b624803523c045bc185 (diff)
parent1c969304d4df4ad22c0089100a071bcb1dca4275 (diff)
downloadotp-4925c1a6df409ea9a964cd4c319af3b1c2cf62dd.tar.gz
otp-4925c1a6df409ea9a964cd4c319af3b1c2cf62dd.tar.bz2
otp-4925c1a6df409ea9a964cd4c319af3b1c2cf62dd.zip
Merge branch 'rickard/drv-send-term-thr-bug/OTP-13866' into maint-18
* rickard/drv-send-term-thr-bug/OTP-13866: Fix thread calls to erl_drv_send_term()/erl_drv_output_term()
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/io.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index fbcb0c31fc..538015b242 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -5767,16 +5767,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
@@ -5785,22 +5789,25 @@ 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
- ERTS_SMP_LC_ASSERT(dhndl == ERTS_THR_PRGR_DHANDLE_MANAGED
- ? erts_lc_is_port_locked(prt)
- : !erts_lc_is_port_locked(prt));
- return 1;
+ ERTS_SMP_LC_ASSERT(res != 1 || erts_lc_is_port_locked(prt));
+
+ 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... */
int res = deliver_term_check_port(port_id, &connected);
if (res <= 0)
return res;