aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2018-11-27 07:05:56 +0100
committerGitHub <[email protected]>2018-11-27 07:05:56 +0100
commit39d52f32656ab9ae1f508a0442175b6f0cd58f4c (patch)
treebb5389788779a22c250754f430b2621472dd2614 /erts/emulator
parent7fa32e36811029ff6f88229cdc5e2a0f97e72946 (diff)
parent63077f5bb3011ec9a14aa9b9e39ed31e4525078b (diff)
downloadotp-39d52f32656ab9ae1f508a0442175b6f0cd58f4c.tar.gz
otp-39d52f32656ab9ae1f508a0442175b6f0cd58f4c.tar.bz2
otp-39d52f32656ab9ae1f508a0442175b6f0cd58f4c.zip
Merge pull request #2024 from max-au/fix_aux_work_on_dcpu_sched
erts: fix attempt to start timer when executing on dirty scheduler OTP-15446
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/erl_node_tables.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index f4dc60941a..18ed782ae3 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -421,8 +421,25 @@ static void schedule_delete_dist_entry(DistEntry* dep)
*
* Note that timeouts do not guarantee thread progress.
*/
- erts_schedule_thr_prgr_later_op(start_timer_delete_dist_entry,
- dep, &dep->later_op);
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ if (esdp && !ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ erts_schedule_thr_prgr_later_op(start_timer_delete_dist_entry,
+ dep, &dep->later_op);
+ } else {
+ /*
+ * Since OTP 20, it's possible that destructor is executed on
+ * a dirty scheduler. Aux work cannot be done on a dirty
+ * scheduler, and scheduling any aux work on a dirty scheduler
+ * makes the scheduler to loop infinitely.
+ * To avoid this, make a spot jump: schedule this function again
+ * on a first normal scheduler. It is guaranteed to be always
+ * online. Since it's a rare event, this shall not pose a big
+ * utilisation hit.
+ */
+ erts_schedule_misc_aux_work(1,
+ (void (*)(void *))schedule_delete_dist_entry,
+ (void *) dep);
+ }
}
static void