@@ -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,17 +87,42 @@ 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 } ;
92
94
93
95
/// The type of a dispatch queue.
94
- #[ derive( Clone , Debug , Hash , PartialEq ) ]
96
+ #[ derive( Debug , Hash , PartialEq ) ]
95
97
pub enum QueueAttribute {
96
98
/// The queue executes blocks serially in FIFO order.
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 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
+ }
100
126
}
101
127
102
128
impl QueueAttribute {
@@ -105,6 +131,7 @@ impl QueueAttribute {
105
131
match * self {
106
132
QueueAttribute :: Serial => DISPATCH_QUEUE_SERIAL ,
107
133
QueueAttribute :: Concurrent => DISPATCH_QUEUE_CONCURRENT ,
134
+ QueueAttribute :: Value ( attr) => attr,
108
135
}
109
136
}
110
137
@@ -115,6 +142,30 @@ impl QueueAttribute {
115
142
// Back then, the attr for dispatch_queue_create must be NULL.
116
143
ptr:: null ( )
117
144
}
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
+ }
118
169
}
119
170
120
171
/// The priority of a global concurrent queue.
@@ -263,6 +314,16 @@ impl Queue {
263
314
str:: from_utf8 ( label. to_bytes ( ) ) . unwrap ( )
264
315
}
265
316
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
+
266
327
/// Submits a closure for execution on self and waits until it completes.
267
328
pub fn sync < T , F > ( & self , work : F ) -> T
268
329
where
@@ -694,9 +755,25 @@ mod tests {
694
755
let q = Queue :: create ( "" , QueueAttribute :: Serial ) ;
695
756
let mut num = 0 ;
696
757
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
+
697
773
q. sync ( || num = 1 ) ;
698
774
assert_eq ! ( num, 1 ) ;
699
775
776
+ assert_eq ! ( q. qos_class( ) , ( QosClass :: UserInteractive , 0 ) ) ;
700
777
assert_eq ! ( q. sync( || num) , 1 ) ;
701
778
}
702
779
0 commit comments