@@ -73,6 +73,7 @@ mod blk;
73
73
mod data;
74
74
#[ cfg( target_os = "macos" ) ]
75
75
mod io;
76
+ mod qos;
76
77
#[ cfg( target_os = "macos" ) ]
77
78
mod sem;
78
79
mod time;
@@ -86,6 +87,7 @@ pub use data::{
86
87
} ;
87
88
#[ cfg( target_os = "macos" ) ]
88
89
pub use ffi:: { DISPATCH_IO_STOP , DISPATCH_IO_STRICT_INTERVAL } ;
90
+ pub use qos:: QosClass ;
89
91
#[ cfg( target_os = "macos" ) ]
90
92
pub use sem:: Semaphore ;
91
93
pub use time:: { after, at, now, Timeout , WaitTimeout } ;
@@ -97,6 +99,16 @@ pub enum QueueAttribute {
97
99
Serial ,
98
100
/// The queue executes blocks concurrently.
99
101
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
+ }
100
112
}
101
113
102
114
impl QueueAttribute {
@@ -105,6 +117,7 @@ impl QueueAttribute {
105
117
match * self {
106
118
QueueAttribute :: Serial => DISPATCH_QUEUE_SERIAL ,
107
119
QueueAttribute :: Concurrent => DISPATCH_QUEUE_CONCURRENT ,
120
+ QueueAttribute :: Value ( attr) => attr,
108
121
}
109
122
}
110
123
@@ -115,6 +128,30 @@ impl QueueAttribute {
115
128
// Back then, the attr for dispatch_queue_create must be NULL.
116
129
ptr:: null ( )
117
130
}
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
+ }
118
155
}
119
156
120
157
/// The priority of a global concurrent queue.
@@ -263,6 +300,16 @@ impl Queue {
263
300
str:: from_utf8 ( label. to_bytes ( ) ) . unwrap ( )
264
301
}
265
302
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
+
266
313
/// Submits a closure for execution on self and waits until it completes.
267
314
pub fn sync < T , F > ( & self , work : F ) -> T
268
315
where
@@ -694,9 +741,25 @@ mod tests {
694
741
let q = Queue :: create ( "" , QueueAttribute :: Serial ) ;
695
742
let mut num = 0 ;
696
743
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
+
697
759
q. sync ( || num = 1 ) ;
698
760
assert_eq ! ( num, 1 ) ;
699
761
762
+ assert_eq ! ( q. qos_class( ) , ( QosClass :: UserInteractive , 0 ) ) ;
700
763
assert_eq ! ( q. sync( || num) , 1 ) ;
701
764
}
702
765
0 commit comments