Skip to content

Commit

Permalink
Less Mutex poisoning
Browse files Browse the repository at this point in the history
If a test case panics while holding a static method's internal Mutex
locked, for example by violating a times() constraint, then clear the
Mutex's poison during Drop.  We're going to delete all of its
Expectations anyway, so there's no data to be poisoned.

Requires nightly.

Fixes #515
  • Loading branch information
asomers committed Jan 14, 2024
1 parent 17942ef commit c99b3a5
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- No longer poison a Context object's internal `Mutex` when panicing. This
requires the "nightly" feature.
([#527](https://github.com/asomers/mockall/pull/527))

- Raised predicates, which is reexported, to 3.0.0. This may affect backwards
compatibility for users who make use of predicates's "color" feature.
([#467](https://github.com/asomers/mockall/pull/467))
Expand Down
2 changes: 1 addition & 1 deletion mockall/tests/clear_expectations_on_panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn too_few_calls() {

// We shouldn't panic during drop in this case. Regression test for
// https://github.com/asomers/mockall/issues/491
#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: PoisonError { .. }")]
#[cfg_attr(not(feature = "nightly"), ignore)]
#[test]
fn too_many_calls() {
panic::catch_unwind(|| {
Expand Down
8 changes: 8 additions & 0 deletions mockall_derive/src/mock_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,11 @@ impl<'a> ToTokens for Context<'a> {
#[cfg(feature = "nightly_derive")]
let must_use = quote!();

#[cfg(not(feature = "nightly_derive"))]
let clear_poison = quote!();
#[cfg(feature = "nightly_derive")]
let clear_poison = quote!(EXPECTATIONS.clear_poison(););

quote!(
/// Manages the context for expectations of static methods.
///
Expand Down Expand Up @@ -1594,6 +1599,9 @@ impl<'a> ToTokens for Context<'a> {
impl #ty_ig Drop for Context #ty_tg #ty_wc {
fn drop(&mut self) {
if ::std::thread::panicking() {
// Clear poison since we're about to clear the Mutex's
// contents anyway.
#clear_poison
// Drain all expectations so other tests can run with a
// blank slate. But ignore errors so we don't
// double-panic.
Expand Down

0 comments on commit c99b3a5

Please sign in to comment.