@@ -73,6 +73,7 @@ mod blk;
7373mod data;
7474#[ cfg( target_os = "macos" ) ]
7575mod io;
76+ mod qos;
7677#[ cfg( target_os = "macos" ) ]
7778mod sem;
7879mod time;
@@ -86,17 +87,42 @@ pub use data::{
8687} ;
8788#[ cfg( target_os = "macos" ) ]
8889pub use ffi:: { DISPATCH_IO_STOP , DISPATCH_IO_STRICT_INTERVAL } ;
90+ pub use qos:: QosClass ;
8991#[ cfg( target_os = "macos" ) ]
9092pub use sem:: Semaphore ;
9193pub use time:: { after, at, now, Timeout , WaitTimeout } ;
9294
9395/// The type of a dispatch queue.
94- #[ derive( Clone , Debug , Hash , PartialEq ) ]
96+ #[ derive( Debug , Hash , PartialEq ) ]
9597pub enum QueueAttribute {
9698 /// The queue executes blocks serially in FIFO order.
9799 Serial ,
98100 /// The queue executes blocks concurrently.
99101 Concurrent ,
102+ /// Attribute for dispatch queues.
103+ Value ( dispatch_queue_attr_t ) ,
104+ }
105+
106+ impl Clone for QueueAttribute {
107+ fn clone ( & self ) -> Self {
108+ match * self {
109+ QueueAttribute :: Serial => QueueAttribute :: Serial ,
110+ QueueAttribute :: Concurrent => QueueAttribute :: Concurrent ,
111+ QueueAttribute :: Value ( attr) => {
112+ unsafe { dispatch_retain ( attr as * mut _ ) } ;
113+
114+ QueueAttribute :: Value ( attr)
115+ }
116+ }
117+ }
118+ }
119+
120+ impl Drop for QueueAttribute {
121+ fn drop ( & mut self ) {
122+ if let & mut QueueAttribute :: Value ( attr) = self {
123+ unsafe { dispatch_release ( attr as * mut _ ) }
124+ }
125+ }
100126}
101127
102128impl QueueAttribute {
@@ -105,6 +131,7 @@ impl QueueAttribute {
105131 match * self {
106132 QueueAttribute :: Serial => DISPATCH_QUEUE_SERIAL ,
107133 QueueAttribute :: Concurrent => DISPATCH_QUEUE_CONCURRENT ,
134+ QueueAttribute :: Value ( attr) => attr,
108135 }
109136 }
110137
@@ -115,6 +142,30 @@ impl QueueAttribute {
115142 // Back then, the attr for dispatch_queue_create must be NULL.
116143 ptr:: null ( )
117144 }
145+
146+ /// Returns an attribute value which may be provided to `Queue::create` or `Queue::with_target_queue`,
147+ /// in order to make the created queue initially inactive.
148+ #[ cfg( target_os = "macos" ) ]
149+ pub fn inactive ( self ) -> Self {
150+ let attr = unsafe { dispatch_queue_attr_make_initially_inactive ( self . as_raw ( ) ) } ;
151+
152+ QueueAttribute :: Value ( attr)
153+ }
154+
155+ /// Returns an attribute value which may be provided to `Queue::create` or `Queue::with_target_queue`,
156+ /// in order to assign a QOS class and relative priority to the queue.
157+ #[ cfg( target_os = "macos" ) ]
158+ pub fn with_qos_class ( self , qos_class : QosClass , relative_priority : i32 ) -> Self {
159+ let attr = unsafe {
160+ dispatch_queue_attr_make_with_qos_class (
161+ self . as_raw ( ) ,
162+ qos_class as dispatch_qos_class_t ,
163+ relative_priority,
164+ )
165+ } ;
166+
167+ QueueAttribute :: Value ( attr)
168+ }
118169}
119170
120171/// The priority of a global concurrent queue.
@@ -263,6 +314,16 @@ impl Queue {
263314 str:: from_utf8 ( label. to_bytes ( ) ) . unwrap ( )
264315 }
265316
317+ /// Returns the QOS class and relative priority of the given queue.
318+ pub fn qos_class ( & self ) -> ( QosClass , i32 ) {
319+ let mut relative_priority = 0 ;
320+
321+ let qos_class =
322+ unsafe { dispatch_queue_get_qos_class ( self . ptr , & mut relative_priority) } . into ( ) ;
323+
324+ ( qos_class, relative_priority)
325+ }
326+
266327 /// Submits a closure for execution on self and waits until it completes.
267328 pub fn sync < T , F > ( & self , work : F ) -> T
268329 where
@@ -694,9 +755,25 @@ mod tests {
694755 let q = Queue :: create ( "" , QueueAttribute :: Serial ) ;
695756 let mut num = 0 ;
696757
758+ q. sync ( || num = 1 ) ;
759+ assert_eq ! ( num, 1 ) ;
760+ assert_eq ! ( q. qos_class( ) , ( QosClass :: Unspecified , 0 ) ) ;
761+
762+ assert_eq ! ( q. sync( || num) , 1 ) ;
763+ }
764+
765+ #[ test]
766+ fn test_serial_queue_with_qos_class ( ) {
767+ let q = Queue :: create (
768+ "" ,
769+ QueueAttribute :: Serial . with_qos_class ( QosClass :: UserInteractive , 0 ) ,
770+ ) ;
771+ let mut num = 0 ;
772+
697773 q. sync ( || num = 1 ) ;
698774 assert_eq ! ( num, 1 ) ;
699775
776+ assert_eq ! ( q. qos_class( ) , ( QosClass :: UserInteractive , 0 ) ) ;
700777 assert_eq ! ( q. sync( || num) , 1 ) ;
701778 }
702779
0 commit comments