aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2013-09-02 16:30:16 +0200
committerLukas Larsson <[email protected]>2013-09-02 16:30:16 +0200
commit3515e75661a0e2c5a37eb226b9f2ea94b122e87b (patch)
treec484456b5c4c6c367635160a65c7aaf1459da3a8 /erts
parent1477aa1a8b78a806ae6b815e16776a64cf6fbc6e (diff)
parentb368fb879676fa6dd2d251ba6583d0a86d04aeb0 (diff)
downloadotp-3515e75661a0e2c5a37eb226b9f2ea94b122e87b.tar.gz
otp-3515e75661a0e2c5a37eb226b9f2ea94b122e87b.tar.bz2
otp-3515e75661a0e2c5a37eb226b9f2ea94b122e87b.zip
Merge branch 'lukas/erts/clean_port_msg_dispatcher/OTP-11290' into maint
* lukas/erts/clean_port_msg_dispatcher/OTP-11290: erts: Fix segfault when scheduling release_port later_op
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/erl_port_task.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 7d53ce7152..547a42beb2 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -1838,6 +1838,16 @@ release_port(void *vport)
{
erts_port_dec_refc((Port *) vport);
}
+
+static void
+schedule_release_port(void *vport) {
+ Port *pp = (Port*)vport;
+ /* This is only used when a port release was ordered from a non-scheduler */
+ erts_schedule_thr_prgr_later_op(release_port,
+ (void *) pp,
+ &pp->common.u.release);
+}
+
#endif
static void
@@ -2033,10 +2043,15 @@ begin_port_cleanup(Port *pp, ErtsPortTask **execqp, int *processing_busy_q_p)
* Schedule cleanup of port structure...
*/
#ifdef ERTS_SMP
- /* Has to be more or less immediate to release any driver */
- erts_schedule_thr_prgr_later_op(release_port,
- (void *) pp,
- &pp->common.u.release);
+ /* We might not be a scheduler, eg. traceing to port we are sys_msg_dispatcher */
+ if (!erts_get_scheduler_data()) {
+ erts_schedule_misc_aux_work(1, schedule_release_port, (void*)pp);
+ } else {
+ /* Has to be more or less immediate to release any driver */
+ erts_schedule_thr_prgr_later_op(release_port,
+ (void *) pp,
+ &pp->common.u.release);
+ }
#else
pp->cleanup = 1;
#endif