aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2016-09-06 12:17:01 +0200
committerRickard Green <[email protected]>2016-09-06 12:17:01 +0200
commit5cc2afeaa6e617e393f573d3386fcc3bc483c8ff (patch)
treecc0614967802a64db6728d1c6e10be0bb96075ff
parent751658c435c49eb552da115fe9348bee6b98ccfe (diff)
parent02c9a648db3753008e67f22140a2bf8dd8912ccd (diff)
downloadotp-5cc2afeaa6e617e393f573d3386fcc3bc483c8ff.tar.gz
otp-5cc2afeaa6e617e393f573d3386fcc3bc483c8ff.tar.bz2
otp-5cc2afeaa6e617e393f573d3386fcc3bc483c8ff.zip
Merge branch 'maint'
* maint: Fix thread calls to erl_drv_send_term()/erl_drv_output_term()
-rw-r--r--erts/emulator/beam/io.c26
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)