@@ -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,6 +87,7 @@ 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 } ;
@@ -97,6 +99,16 @@ pub enum QueueAttribute {
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 Drop for QueueAttribute {
107+ fn drop ( & mut self ) {
108+ if let & mut QueueAttribute :: Value ( attr) = self {
109+ unsafe { dispatch_release ( attr as * mut _ ) }
110+ }
111+ }
100112}
101113
102114impl QueueAttribute {
@@ -105,6 +117,7 @@ impl QueueAttribute {
105117 match * self {
106118 QueueAttribute :: Serial => DISPATCH_QUEUE_SERIAL ,
107119 QueueAttribute :: Concurrent => DISPATCH_QUEUE_CONCURRENT ,
120+ QueueAttribute :: Value ( attr) => attr,
108121 }
109122 }
110123
@@ -115,6 +128,30 @@ impl QueueAttribute {
115128 // Back then, the attr for dispatch_queue_create must be NULL.
116129 ptr:: null ( )
117130 }
131+
132+ /// Returns an attribute value which may be provided to `Queue::create` or `Queue::with_target_queue`,
133+ /// in order to make the created queue initially inactive.
134+ #[ cfg( target_os = "macos" ) ]
135+ pub fn inactive ( self ) -> Self {
136+ let attr = unsafe { dispatch_queue_attr_make_initially_inactive ( self . as_raw ( ) ) } ;
137+
138+ QueueAttribute :: Value ( attr)
139+ }
140+
141+ /// Returns an attribute value which may be provided to `Queue::create` or `Queue::with_target_queue`,
142+ /// in order to assign a QOS class and relative priority to the queue.
143+ #[ cfg( target_os = "macos" ) ]
144+ pub fn with_qos_class ( self , qos_class : QosClass , relative_priority : i32 ) -> Self {
145+ let attr = unsafe {
146+ dispatch_queue_attr_make_with_qos_class (
147+ self . as_raw ( ) ,
148+ qos_class as dispatch_qos_class_t ,
149+ relative_priority,
150+ )
151+ } ;
152+
153+ QueueAttribute :: Value ( attr)
154+ }
118155}
119156
120157/// The priority of a global concurrent queue.
@@ -263,6 +300,16 @@ impl Queue {
263300 str:: from_utf8 ( label. to_bytes ( ) ) . unwrap ( )
264301 }
265302
303+ /// Returns the QOS class and relative priority of the given queue.
304+ pub fn qos_class ( & self ) -> ( QosClass , i32 ) {
305+ let mut relative_priority = 0 ;
306+
307+ let qos_class =
308+ unsafe { dispatch_queue_get_qos_class ( self . ptr , & mut relative_priority) } . into ( ) ;
309+
310+ ( qos_class, relative_priority)
311+ }
312+
266313 /// Submits a closure for execution on self and waits until it completes.
267314 pub fn sync < T , F > ( & self , work : F ) -> T
268315 where
@@ -694,9 +741,25 @@ mod tests {
694741 let q = Queue :: create ( "" , QueueAttribute :: Serial ) ;
695742 let mut num = 0 ;
696743
744+ q. sync ( || num = 1 ) ;
745+ assert_eq ! ( num, 1 ) ;
746+ assert_eq ! ( q. qos_class( ) , ( QosClass :: Unspecified , 0 ) ) ;
747+
748+ assert_eq ! ( q. sync( || num) , 1 ) ;
749+ }
750+
751+ #[ test]
752+ fn test_serial_queue_with_qos_class ( ) {
753+ let q = Queue :: create (
754+ "" ,
755+ QueueAttribute :: Serial . with_qos_class ( QosClass :: UserInteractive , 0 ) ,
756+ ) ;
757+ let mut num = 0 ;
758+
697759 q. sync ( || num = 1 ) ;
698760 assert_eq ! ( num, 1 ) ;
699761
762+ assert_eq ! ( q. qos_class( ) , ( QosClass :: UserInteractive , 0 ) ) ;
700763 assert_eq ! ( q. sync( || num) , 1 ) ;
701764 }
702765
0 commit comments