@@ -250,17 +250,22 @@ static void send_unblock(pony_actor_t* actor)
250
250
251
251
static void send_block (pony_ctx_t * ctx , pony_actor_t * actor )
252
252
{
253
- // We're blocked, send block message.
254
253
pony_assert (ctx -> current == actor );
254
+
255
+ // Try and run GC because we're blocked and sending a block message
256
+ // to the CD. This will try and free any memory the actor has in its
257
+ // heap that wouldn't get freed otherwise until the actor is
258
+ // destroyed or happens to receive more work via application messages
259
+ // that eventually trigger a GC which may not happen for a long time
260
+ // (or ever). Do this BEFORE sending the message or else we might be
261
+ // GCing while the CD destroys us.
262
+ pony_triggergc (ctx );
263
+ try_gc (ctx , actor );
264
+
265
+ // We're blocked, send block message.
255
266
set_internal_flag (actor , FLAG_BLOCKED_SENT );
256
267
set_internal_flag (actor , FLAG_CD_CONTACTED );
257
268
ponyint_cycle_block (actor , & actor -> gc );
258
-
259
- // Trigger garbage collection. GC will get run next time `try_gc` is called
260
- // which should happen once all messages get processed in the messageq
261
- // at the time `pony_actor_run` was called if not earlier
262
- // when an app message is processed
263
- pony_triggergc (ctx );
264
269
}
265
270
266
271
static bool handle_message (pony_ctx_t * ctx , pony_actor_t * actor ,
@@ -644,20 +649,12 @@ bool ponyint_actor_run(pony_ctx_t* ctx, pony_actor_t* actor, bool polling)
644
649
)
645
650
{
646
651
// The cycle detector (CD) doesn't know we exist so it won't try
647
- // and reach out to us even though we're blocked, so send block message //// and set flag that the CD knows we exist now so that when we block
652
+ // and reach out to us even though we're blocked, so send block message
653
+ // and set flag that the CD knows we exist now so that when we block
648
654
// in the future we will wait for the CD to reach out and ask
649
655
// if we're blocked or not.
650
656
// But, only if gc.rc > 0 because if gc.rc == 0 we are a zombie.
651
657
send_block (ctx , actor );
652
-
653
- // Try and run GC because we're blocked and sending a block message
654
- // to the CD and we're past the normal point at which `try_gc` is
655
- // called as part of this function. This will try and free any
656
- // memory the actor has in its heap that wouldn't get freed otherwise
657
- // until the actor is destroyed or happens to receive more work via
658
- // application messages that eventually trigger a GC which may not
659
- // happen for a long time (or ever).
660
- try_gc (ctx , actor );
661
658
}
662
659
663
660
}
0 commit comments