crux icon indicating copy to clipboard operation
crux copied to clipboard

Fix a bug caused by drop order of the `Core` struct

Open charypar opened this issue 6 months ago • 1 comments

This is a very subtle problem with the order of the fields of the Core type interacting with the async runtime when using channels (and possibly other coordination primitives).

The problem is this:

  1. A capability creates a long running future with a loop
  2. In order to communicate with this future it creates a channel, gives the receving end to the future and holds the sending end
  3. The future gets to the point of receiving from the channel and suspends on .await.
  4. If the core is now dropped, then due to the original ordering of the fields, the executor is dropped first, causing the task_sender channel to close.
  5. The A::Capabilities instance is dropped, dropping the capability instance, including the sending end of the channel
  6. The channel's Drop implementation closes the channel, which wakes up the future, so that the recv() method can return Err
  7. The ArcWake implementation on the task spawned by Crux's Spawner attempts to .send self to the task_sender, which fails, because the receving end dropped in step 4, and we panic on the .expect

To fix, I've reordered the fields of Core to drop the user defined types first, so that any Crux infrastructure they rely on is still alive when any Drop implementations in them run.

charypar avatar Aug 09 '24 16:08 charypar