Skip to content

Commit 2416117

Browse files
committed
Added a SuspendGuard struct for suspending queues.
1 parent 52edf69 commit 2416117

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

src/lib.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ impl Queue {
307307
dispatch_barrier_async_f(self.ptr, context, work);
308308
}
309309
}
310+
311+
pub fn suspend(&self) -> SuspendGuard {
312+
SuspendGuard::new(self)
313+
}
310314
}
311315

312316
unsafe impl Sync for Queue { }
@@ -329,6 +333,35 @@ impl Drop for Queue {
329333
}
330334
}
331335

336+
pub struct SuspendGuard {
337+
queue: Queue,
338+
}
339+
340+
impl SuspendGuard {
341+
fn new(queue: &Queue) -> SuspendGuard {
342+
unsafe {
343+
dispatch_suspend(queue.ptr);
344+
}
345+
SuspendGuard { queue: queue.clone() }
346+
}
347+
348+
pub fn resume(self) { }
349+
}
350+
351+
impl Clone for SuspendGuard {
352+
fn clone(&self) -> Self {
353+
SuspendGuard::new(&self.queue)
354+
}
355+
}
356+
357+
impl Drop for SuspendGuard {
358+
fn drop(&mut self) {
359+
unsafe {
360+
dispatch_resume(self.queue.ptr);
361+
}
362+
}
363+
}
364+
332365
pub struct Group {
333366
ptr: dispatch_group_t,
334367
}
@@ -399,6 +432,14 @@ impl GroupGuard {
399432
}
400433
GroupGuard { group: group.clone() }
401434
}
435+
436+
pub fn leave(self) { }
437+
}
438+
439+
impl Clone for GroupGuard {
440+
fn clone(&self) -> Self {
441+
GroupGuard::new(&self.group)
442+
}
402443
}
403444

404445
impl Drop for GroupGuard {
@@ -542,6 +583,25 @@ mod tests {
542583
assert!(*num.lock().unwrap() == 12);
543584
}
544585

586+
#[test]
587+
fn test_suspend() {
588+
let q = Queue::create("", QueueAttribute::Serial);
589+
let num = Arc::new(Mutex::new(0));
590+
591+
// Suspend the queue and then dispatch some work to it
592+
let guard = q.suspend();
593+
async_increment(&q, &num);
594+
595+
// Sleep and ensure the work doesn't occur
596+
::std::thread::sleep_ms(5);
597+
assert!(*num.lock().unwrap() == 0);
598+
599+
// But ensure the work does complete after we resume
600+
guard.resume();
601+
q.sync(|| ());
602+
assert!(*num.lock().unwrap() == 1);
603+
}
604+
545605
#[test]
546606
fn test_group() {
547607
let group = Group::create();
@@ -559,7 +619,7 @@ mod tests {
559619
q.async(move || {
560620
let mut num = num3.lock().unwrap();
561621
*num += 1;
562-
drop(guard);
622+
guard.leave();
563623
});
564624

565625
let num4 = num.clone();

0 commit comments

Comments
 (0)