Skip to content

Commit

Permalink
sync: add merge() to semaphore permits
Browse files Browse the repository at this point in the history
Adds a merge() method to:

    * SemaphorePermit
    * OwnedSemaphorePermit

Merging two permits instances together consumes one instance, adding the
permits it holds to the remaining instance.
  • Loading branch information
domodwyer committed Aug 26, 2022
1 parent 218f262 commit d8afc6a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
18 changes: 18 additions & 0 deletions tokio/src/sync/semaphore.rs
Expand Up @@ -620,6 +620,15 @@ impl<'a> SemaphorePermit<'a> {
pub fn forget(mut self) {
self.permits = 0;
}

/// Merge two [`SemaphorePermit`] instances together, consuming `other`
/// without releasing the permits it holds.
///
/// Permits held by both `self` and `other` are released when `self` drops.
pub fn merge(&mut self, mut other: Self) {
self.permits += other.permits;
other.permits = 0;
}
}

impl OwnedSemaphorePermit {
Expand All @@ -629,6 +638,15 @@ impl OwnedSemaphorePermit {
pub fn forget(mut self) {
self.permits = 0;
}

/// Merge two [`OwnedSemaphorePermit`] instances together, consuming `other`
/// without releasing the permits it holds.
///
/// Permits held by both `self` and `other` are released when `self` drops.
pub fn merge(&mut self, mut other: Self) {
self.permits += other.permits;
other.permits = 0;
}
}

impl Drop for SemaphorePermit<'_> {
Expand Down
14 changes: 14 additions & 0 deletions tokio/tests/sync_semaphore.rs
Expand Up @@ -63,6 +63,20 @@ fn forget() {
assert!(sem.try_acquire().is_err());
}

#[test]
fn merge() {
let sem = Arc::new(Semaphore::new(3));
{
let mut p1 = sem.try_acquire().unwrap();
assert_eq!(sem.available_permits(), 2);
let p2 = sem.try_acquire_many(2).unwrap();
assert_eq!(sem.available_permits(), 0);
p1.merge(p2);
assert_eq!(sem.available_permits(), 0);
}
assert_eq!(sem.available_permits(), 3);
}

#[tokio::test]
#[cfg(feature = "full")]
async fn stress_test() {
Expand Down
14 changes: 14 additions & 0 deletions tokio/tests/sync_semaphore_owned.rs
Expand Up @@ -89,6 +89,20 @@ fn forget() {
assert!(sem.try_acquire_owned().is_err());
}

#[test]
fn merge() {
let sem = Arc::new(Semaphore::new(3));
{
let mut p1 = sem.clone().try_acquire_owned().unwrap();
assert_eq!(sem.available_permits(), 2);
let p2 = sem.clone().try_acquire_many_owned(2).unwrap();
assert_eq!(sem.available_permits(), 0);
p1.merge(p2);
assert_eq!(sem.available_permits(), 0);
}
assert_eq!(sem.available_permits(), 3);
}

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

0 comments on commit d8afc6a

Please sign in to comment.