diff options
Diffstat (limited to 'src/tools/clippy/src/docs/await_holding_lock.txt')
-rw-r--r-- | src/tools/clippy/src/docs/await_holding_lock.txt | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/tools/clippy/src/docs/await_holding_lock.txt b/src/tools/clippy/src/docs/await_holding_lock.txt new file mode 100644 index 000000000..0f450a111 --- /dev/null +++ b/src/tools/clippy/src/docs/await_holding_lock.txt @@ -0,0 +1,51 @@ +### What it does +Checks for calls to await while holding a non-async-aware MutexGuard. + +### Why is this bad? +The Mutex types found in std::sync and parking_lot +are not designed to operate in an async context across await points. + +There are two potential solutions. One is to use an async-aware Mutex +type. Many asynchronous foundation crates provide such a Mutex type. The +other solution is to ensure the mutex is unlocked before calling await, +either by introducing a scope or an explicit call to Drop::drop. + +### Known problems +Will report false positive for explicitly dropped guards +([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A workaround for this is +to wrap the `.lock()` call in a block instead of explicitly dropping the guard. + +### Example +``` +async fn foo(x: &Mutex<u32>) { + let mut guard = x.lock().unwrap(); + *guard += 1; + baz().await; +} + +async fn bar(x: &Mutex<u32>) { + let mut guard = x.lock().unwrap(); + *guard += 1; + drop(guard); // explicit drop + baz().await; +} +``` + +Use instead: +``` +async fn foo(x: &Mutex<u32>) { + { + let mut guard = x.lock().unwrap(); + *guard += 1; + } + baz().await; +} + +async fn bar(x: &Mutex<u32>) { + { + let mut guard = x.lock().unwrap(); + *guard += 1; + } // guard dropped here at end of scope + baz().await; +} +```
\ No newline at end of file |