1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use objc2::rc::{Id, Shared};
use objc2::{msg_send, msg_send_bool};
use crate::{NSObject, NSString};
object! {
unsafe pub struct NSThread: NSObject;
}
unsafe impl Send for NSThread {}
unsafe impl Sync for NSThread {}
impl NSThread {
pub fn current() -> Id<NSThread, Shared> {
let obj: *mut Self = unsafe { msg_send![Self::class(), currentThread] };
unsafe { Id::retain_autoreleased(obj).unwrap() }
}
pub fn main() -> Id<NSThread, Shared> {
let obj: *mut Self = unsafe { msg_send![Self::class(), mainThread] };
unsafe { Id::retain_autoreleased(obj).expect("Could not retrieve main thread.") }
}
pub fn is_main(&self) -> bool {
unsafe { msg_send_bool![self, isMainThread] }
}
pub fn name(&self) -> Option<Id<NSString, Shared>> {
let obj: *mut NSString = unsafe { msg_send![self, name] };
unsafe { Id::retain_autoreleased(obj) }
}
}
pub fn is_multi_threaded() -> bool {
unsafe { msg_send_bool![NSThread::class(), isMultiThreaded] }
}
pub fn is_main_thread() -> bool {
unsafe { msg_send_bool![NSThread::class(), isMainThread] }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg_attr(
feature = "gnustep-1-7",
should_panic = "Could not retrieve main thread"
)]
fn test_main_thread() {
let current = NSThread::current();
let main = NSThread::main();
assert!(main.is_main());
if main == current {
assert!(current.is_main());
assert!(is_main_thread());
} else {
assert!(!current.is_main());
assert!(!is_main_thread());
}
}
#[test]
fn test_not_main_thread() {
let res = std::thread::spawn(|| (is_main_thread(), NSThread::current().is_main()))
.join()
.unwrap();
assert_eq!(res, (false, false));
}
}