Skip to content

Commit cfb827a

Browse files
authored
Fix unsoundness in MappedMutexGuard (#2240)
See #2239
1 parent 7340d3d commit cfb827a

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

futures-util/src/lock/mutex.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ use futures_core::task::{Context, Poll, Waker};
33
use slab::Slab;
44
use std::{fmt, mem};
55
use std::cell::UnsafeCell;
6+
use std::marker::PhantomData;
67
use std::ops::{Deref, DerefMut};
78
use std::pin::Pin;
89
use std::sync::Mutex as StdMutex;
910
use std::sync::atomic::{AtomicUsize, Ordering};
1011

1112
/// A futures-aware mutex.
12-
///
13+
///
1314
/// # Fairness
14-
///
15+
///
1516
/// This mutex provides no fairness guarantees. Tasks may not acquire the mutex
1617
/// in the order that they requested the lock, and it's possible for a single task
1718
/// which repeatedly takes the lock to starve other tasks, which may be left waiting
@@ -288,7 +289,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
288289
// Don't run the `drop` method for MutexGuard. The ownership of the underlying
289290
// locked state is being moved to the returned MappedMutexGuard.
290291
mem::forget(this);
291-
MappedMutexGuard { mutex, value }
292+
MappedMutexGuard { mutex, value, _marker: PhantomData }
292293
}
293294
}
294295

@@ -325,6 +326,7 @@ impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
325326
pub struct MappedMutexGuard<'a, T: ?Sized, U: ?Sized> {
326327
mutex: &'a Mutex<T>,
327328
value: *mut U,
329+
_marker: PhantomData<&'a mut U>,
328330
}
329331

330332
impl<'a, T: ?Sized, U: ?Sized> MappedMutexGuard<'a, T, U> {
@@ -354,7 +356,7 @@ impl<'a, T: ?Sized, U: ?Sized> MappedMutexGuard<'a, T, U> {
354356
// Don't run the `drop` method for MappedMutexGuard. The ownership of the underlying
355357
// locked state is being moved to the returned MappedMutexGuard.
356358
mem::forget(this);
357-
MappedMutexGuard { mutex, value }
359+
MappedMutexGuard { mutex, value, _marker: PhantomData }
358360
}
359361
}
360362

@@ -401,8 +403,8 @@ unsafe impl<T: ?Sized> Sync for MutexLockFuture<'_, T> {}
401403
// lock is essentially spinlock-equivalent (attempt to flip an atomic bool)
402404
unsafe impl<T: ?Sized + Send> Send for MutexGuard<'_, T> {}
403405
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
404-
unsafe impl<T: ?Sized + Send, U: ?Sized> Send for MappedMutexGuard<'_, T, U> {}
405-
unsafe impl<T: ?Sized + Sync, U: ?Sized> Sync for MappedMutexGuard<'_, T, U> {}
406+
unsafe impl<T: ?Sized + Send, U: ?Sized + Send> Send for MappedMutexGuard<'_, T, U> {}
407+
unsafe impl<T: ?Sized + Sync, U: ?Sized + Sync> Sync for MappedMutexGuard<'_, T, U> {}
406408

407409
#[test]
408410
fn test_mutex_guard_debug_not_recurse() {

0 commit comments

Comments
 (0)