@@ -8,13 +8,24 @@ use std::cell::Cell;
88use std:: num:: NonZeroU32 ;
99use std:: panic:: resume_unwind;
1010use std:: rc:: Rc ;
11- use std:: sync:: mpsc;
11+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
12+ use std:: sync:: { mpsc, Mutex } ;
1213use std:: thread;
1314use std:: thread:: JoinHandle ;
14- use std:: time:: Duration ;
15+
16+ pub ( crate ) struct WindowThreadShared {
17+ stopped : AtomicBool ,
18+ final_error : Mutex < Option < String > > ,
19+ }
20+
21+ impl WindowThreadShared {
22+ pub fn new ( ) -> Self {
23+ Self { stopped : false . into ( ) , final_error : None . into ( ) }
24+ }
25+ }
1526
1627pub struct WindowThreadHandle {
17- window_id : NonZeroU32 ,
28+ shared : Arc < WindowThreadShared > ,
1829 loop_signal : LoopSignal ,
1930 event_loop_handle : Cell < Option < JoinHandle < ( ) > > > ,
2031}
@@ -24,33 +35,42 @@ impl WindowThreadHandle {
2435 options : WindowOpenOptions , handler : WindowHandlerBuilder ,
2536 ) -> Result < Self > {
2637 let ( tx, rx) = result_channel ( ) ;
38+ let shared = Arc :: new ( WindowThreadShared :: new ( ) ) ;
2739
28- let join_handle = thread:: spawn ( move || {
29- let thread = match WindowThread :: create ( options, handler) {
30- Err ( e) => return tx. send_error ( e) ,
31- Ok ( thread) => thread,
32- } ;
40+ let join_handle = {
41+ let shared = shared. clone ( ) ;
3342
34- if tx. send_success ( & thread) {
35- thread. run ( )
36- }
37- } ) ;
43+ thread:: spawn ( move || {
44+ let thread = match WindowThread :: create ( options, handler, shared) {
45+ Err ( e) => return tx. send_error ( e) ,
46+ Ok ( thread) => thread,
47+ } ;
3848
39- thread:: sleep ( Duration :: from_millis ( 2000 ) ) ;
49+ if tx. send_success ( & thread) {
50+ thread. run ( )
51+ }
52+ } )
53+ } ;
4054
41- rx. receive ( join_handle)
55+ rx. receive ( join_handle, shared )
4256 }
4357
44- pub fn run_until_closed ( & self ) {
45- let Some ( thread) = self . event_loop_handle . take ( ) else { return } ;
58+ pub fn run_until_closed ( & self ) -> Result < ( ) > {
59+ let Some ( thread) = self . event_loop_handle . take ( ) else { return Ok ( ( ) ) } ;
4660
4761 if let Err ( panic) = thread. join ( ) {
4862 resume_unwind ( panic) ;
4963 }
64+
65+ if let Some ( e) = self . shared . final_error . lock ( ) . unwrap ( ) . take ( ) {
66+ return Err ( Error :: RunError ( e) ) ;
67+ }
68+
69+ Ok ( ( ) )
5070 }
5171
5272 pub fn is_open ( & self ) -> bool {
53- todo ! ( )
73+ ! self . shared . stopped . load ( Ordering :: Relaxed )
5474 }
5575}
5676
@@ -64,27 +84,32 @@ impl Drop for WindowThreadHandle {
6484}
6585
6686enum WindowOpenResult {
67- Success { window_id : NonZeroU32 , loop_signal : LoopSignal } ,
87+ Success { loop_signal : LoopSignal } ,
6888 Error ( String ) ,
6989}
7090
7191struct WindowThread {
7292 event_loop : EventLoop ,
7393 ev_loop : calloop:: EventLoop < ' static , EventLoop > ,
94+ shared : Arc < WindowThreadShared > ,
7495}
7596
7697impl WindowThread {
77- pub fn create ( options : WindowOpenOptions , handler : WindowHandlerBuilder ) -> Result < Self > {
98+ pub fn create (
99+ options : WindowOpenOptions , handler : WindowHandlerBuilder , shared : Arc < WindowThreadShared > ,
100+ ) -> Result < Self > {
78101 let mut ev_loop = calloop:: EventLoop :: try_new ( ) ?;
79102 let inner = WindowInner :: create ( options, & ev_loop) ?;
80103 let handler = handler. build ( WindowContext :: new ( Rc :: clone ( & inner) ) ) ?;
81- let event_loop = EventLoop :: new ( inner, handler, & mut ev_loop) ?;
104+ let event_loop = EventLoop :: new ( inner, handler, shared . clone ( ) , & mut ev_loop) ?;
82105
83- Ok ( Self { event_loop, ev_loop } )
106+ Ok ( Self { event_loop, ev_loop, shared } )
84107 }
85108
86109 pub fn run ( self ) {
87- self . event_loop . run ( self . ev_loop ) . unwrap ( ) ;
110+ if let Err ( e) = self . event_loop . run ( self . ev_loop ) {
111+ self . shared . final_error . lock ( ) . unwrap ( ) . replace ( e. to_string ( ) ) ;
112+ }
88113 }
89114}
90115
@@ -103,10 +128,7 @@ impl WindowResultSender {
103128 }
104129
105130 pub fn send_success ( self , thread : & WindowThread ) -> bool {
106- let msg = WindowOpenResult :: Success {
107- loop_signal : thread. ev_loop . get_signal ( ) ,
108- window_id : thread. event_loop . window_id ( ) ,
109- } ;
131+ let msg = WindowOpenResult :: Success { loop_signal : thread. ev_loop . get_signal ( ) } ;
110132
111133 if let Err ( err) = self . 0 . send ( msg) {
112134 crate :: error!( "Failed to send created window to main thread: {}. Aborting." , err) ;
@@ -119,13 +141,15 @@ impl WindowResultSender {
119141
120142struct WindowResultReceiver ( mpsc:: Receiver < WindowOpenResult > ) ;
121143impl WindowResultReceiver {
122- pub fn receive ( self , join_handle : JoinHandle < ( ) > ) -> Result < WindowThreadHandle > {
144+ pub fn receive (
145+ self , join_handle : JoinHandle < ( ) > , shared : Arc < WindowThreadShared > ,
146+ ) -> Result < WindowThreadHandle > {
123147 let result = self . 0 . recv ( ) ?;
124148 match result {
125149 WindowOpenResult :: Error ( e) => Err ( Error :: CreationFailed ( e) ) ,
126- WindowOpenResult :: Success { window_id , loop_signal } => Ok ( WindowThreadHandle {
150+ WindowOpenResult :: Success { loop_signal } => Ok ( WindowThreadHandle {
127151 event_loop_handle : Some ( join_handle) . into ( ) ,
128- window_id ,
152+ shared ,
129153 loop_signal,
130154 } ) ,
131155 }
0 commit comments