Going out of scope prematurely

I have a scenario where an Arc<tokio::sync::Mutex<()>> is used to serialize an operation(as it doesn't support concurrent processing). I am running into an issue where the MutexGuard sometimes gets dropped before the end of scope, causing undefined behavior as the assumption is violated. This is with tokio 0.2.22

I've tried to capture the issue here: play ground. Though this toy example would run as expected, the issue manifests in a very small number of cases under load in the deployed code.

Questions:

  1. My understanding is that rust guarantees objects to be freed at the end of scope. Or is this not true? Are there cases where this may not be true
  2. Could this caused by the old tokio version in play here?

1 answer

  • answered 2021-05-17 09:44 Masklinn

    My understanding is that rust guarantees objects to be freed at the end of scope. Or is this not true? Are there cases where this may not be true

    This is not true, and yes the compiler can decide to drop things long before the end of scope if it's considered unused. A common case is creating a drop-able object and never binding it to anything: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e10235743daca5b1286577b7d94a9af7

    This would be much more likely in async functions if you're binding but not using variables across suspension points (await), because the code is compiled to a state machine repeatedly calling a single function. If the transformation doesn't see your variable being used after the suspension point, it might not store the item in the Future object, therefore the item will be dropped at the suspension point, which is in essence an end-of-scope.

    Could this caused by the old tokio version in play here?

    Don't see why, tokio doesn't control async's codegen, so it would not influence drop locations.