Skip to content

Commit dbfbd9a

Browse files
committed
Make sure unmuted actors can't run on two schedulers concurrently
Prior to this commit, an actor with no pending messages being unmuted could end up running concurrently on two scheduler threads due to a race condition. The specific issue is that we `unmute the actor` and then we `schedule the actor`. It is entirely possible that the unmuted actor could get scheduled on a different scheduler thread if another actor sent it a message at the same time as we schedule it to run on the current scheduler thread. This commit changes the logic to check whether the actor has any pending messages or not prior to unmuting it and will only reschedule the actor if the actor actually had pending messages to process already waiting in its queue.
1 parent b27e0bd commit dbfbd9a

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

src/libponyrt/sched/scheduler.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,10 +1488,23 @@ bool ponyint_sched_unmute_senders(pony_ctx_t* ctx, pony_actor_t* actor)
14881488
{
14891489
needs_unmuting = ponyint_actorstack_pop(needs_unmuting, &to_unmute);
14901490

1491+
// check if the actor has any messages waiting to be processed
1492+
// note: this must be done before the actor is unmuted to
1493+
// avoid a race condition
1494+
bool should_reschedule = !ponyint_messageq_isempty(&to_unmute->q);
1495+
1496+
// unmute actor
14911497
ponyint_unmute_actor(to_unmute);
1492-
ponyint_sched_add(ctx, to_unmute);
1493-
DTRACE2(ACTOR_SCHEDULED, (uintptr_t)sched, (uintptr_t)to_unmute);
1494-
actors_rescheduled++;
1498+
1499+
// only reschedule if the actor had messages waiting to be processed
1500+
// before we unnmuted it to ensure it cannot be concurrently
1501+
// scheduled on multiple scheduler threads
1502+
if(should_reschedule)
1503+
{
1504+
ponyint_sched_add(ctx, to_unmute);
1505+
DTRACE2(ACTOR_SCHEDULED, (uintptr_t)sched, (uintptr_t)to_unmute);
1506+
actors_rescheduled++;
1507+
}
14951508

14961509
ponyint_sched_start_global_unmute(ctx->scheduler->index, to_unmute);
14971510
}

0 commit comments

Comments
 (0)