Skip to content

Commit

Permalink
fix: do not allow merging of unrelated Semaphores
Browse files Browse the repository at this point in the history
Prevent merging permits from two different Semaphore instances.
Attempting to merge unrelated permits will panic.
  • Loading branch information
domodwyer committed Aug 28, 2022
1 parent d8afc6a commit 8356f05
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
8 changes: 8 additions & 0 deletions tokio/src/sync/semaphore.rs
Expand Up @@ -626,6 +626,10 @@ impl<'a> SemaphorePermit<'a> {
///
/// Permits held by both `self` and `other` are released when `self` drops.
pub fn merge(&mut self, mut other: Self) {
assert!(
std::ptr::eq(self.sem, other.sem),
"merging permits from different semaphore instances"
);
self.permits += other.permits;
other.permits = 0;
}
Expand All @@ -644,6 +648,10 @@ impl OwnedSemaphorePermit {
///
/// Permits held by both `self` and `other` are released when `self` drops.
pub fn merge(&mut self, mut other: Self) {
assert!(
Arc::ptr_eq(&self.sem, &other.sem),
"merging permits from different semaphore instances"
);
self.permits += other.permits;
other.permits = 0;
}
Expand Down
10 changes: 10 additions & 0 deletions tokio/tests/sync_semaphore.rs
Expand Up @@ -77,6 +77,16 @@ fn merge() {
assert_eq!(sem.available_permits(), 3);
}

#[test]
#[should_panic]
fn merge_unrelated_permits() {
let sem1 = Arc::new(Semaphore::new(3));
let sem2 = Arc::new(Semaphore::new(3));
let mut p1 = sem1.try_acquire().unwrap();
let p2 = sem2.try_acquire().unwrap();
p1.merge(p2);
}

#[tokio::test]
#[cfg(feature = "full")]
async fn stress_test() {
Expand Down
10 changes: 10 additions & 0 deletions tokio/tests/sync_semaphore_owned.rs
Expand Up @@ -103,6 +103,16 @@ fn merge() {
assert_eq!(sem.available_permits(), 3);
}

#[test]
#[should_panic]
fn merge_unrelated_permits() {
let sem1 = Arc::new(Semaphore::new(3));
let sem2 = Arc::new(Semaphore::new(3));
let mut p1 = sem1.try_acquire_owned().unwrap();
let p2 = sem2.try_acquire_owned().unwrap();
p1.merge(p2)
}

#[tokio::test]
#[cfg(feature = "full")]
async fn stress_test() {
Expand Down

0 comments on commit 8356f05

Please sign in to comment.