55
66mod utils;
77
8+ use std:: fmt:: Debug ;
89use std:: {
910 borrow:: { Borrow , Cow } ,
1011 collections:: HashSet ,
1112 fmt:: Display ,
12- sync:: {
13- atomic:: { AtomicBool , Ordering } ,
14- Arc ,
15- } ,
13+ sync:: atomic:: { AtomicBool , Ordering } ,
1614} ;
17- use std:: { fmt:: Debug , sync:: Mutex } ;
1815
19- use driver_ipc:: {
20- ClientCommand , Dimen , DriverClient , EventCommand , Id , Mode , Monitor , RefreshRate ,
21- } ;
16+ use driver_ipc:: { Dimen , DriverClient , EventCommand , Id , Mode , Monitor , RefreshRate } ;
2217use pyo3:: prelude:: * ;
2318use pyo3:: {
2419 exceptions:: { PyIndexError , PyRuntimeError , PyTypeError } ,
2520 pyclass:: boolean_struct:: False ,
2621 types:: { DerefToPyAny , PyList , PyLong } ,
2722 DowncastIntoError , PyClass , PyTypeCheck ,
2823} ;
29- use windows:: Win32 :: {
30- Foundation :: { DuplicateHandle , DUPLICATE_SAME_ACCESS , HANDLE } ,
31- System :: {
32- Threading :: { GetCurrentProcess , GetCurrentThread } ,
33- IO :: CancelSynchronousIo ,
34- } ,
35- } ;
3624
3725use self :: utils:: IntoPyErr as _;
3826
@@ -336,7 +324,6 @@ impl IntoPyListIter for Py<PyTypedList> {
336324#[ pyo3( name = "DriverClient" ) ]
337325struct PyDriverClient {
338326 client : DriverClient ,
339- thread_registry : Arc < Mutex < Option < HANDLE > > > ,
340327 /// The list of monitors
341328 /// Sig: list[Monitor]
342329 #[ pyo3( get) ]
@@ -358,11 +345,7 @@ impl PyDriverClient {
358345
359346 let monitors = state_to_pytypedlist ( py, client. monitors ( ) ) ?;
360347
361- let slf = Self {
362- client,
363- monitors,
364- thread_registry : Arc :: new ( Mutex :: new ( None ) ) ,
365- } ;
348+ let slf = Self { client, monitors } ;
366349
367350 Ok ( slf)
368351 }
@@ -417,58 +400,28 @@ impl PyDriverClient {
417400 }
418401
419402 /// Get notified of other clients changing driver configuration
420- /// Sig: receive(Callable[list[Monitor], None])
421- fn receive ( & self , callback : PyObject ) {
422- // cancel the receiver internally if called again
423- {
424- let lock = self . thread_registry . lock ( ) . unwrap ( ) . take ( ) ;
425- if let Some ( thread) = lock {
426- unsafe {
427- _ = CancelSynchronousIo ( thread) ;
428- }
429- }
403+ /// Sig: receive(Optional[Callable[list[Monitor], None]])
404+ fn receive ( & self , callback : Option < PyObject > ) {
405+ if let Some ( callback) = callback {
406+ self . client . set_event_receiver ( move |cmd| {
407+ let EventCommand :: Changed ( data) = cmd else {
408+ unreachable ! ( )
409+ } ;
410+
411+ Python :: with_gil ( |py| {
412+ let state = state_to_pylist ( py, & data) ;
413+ let Ok ( state) = state else {
414+ return ;
415+ } ;
416+
417+ if let Err ( e) = callback. call1 ( py, ( state, ) ) {
418+ e. print ( py) ;
419+ }
420+ } ) ;
421+ } ) ;
422+ } else {
423+ self . client . terminate_receiver ( ) ;
430424 }
431-
432- let registry = self . thread_registry . clone ( ) ;
433- self . client . set_receiver (
434- // init - store thread handle for later
435- Some ( move || {
436- let mut lock = registry. lock ( ) . unwrap ( ) ;
437-
438- let pseudo_handle = unsafe { GetCurrentThread ( ) } ;
439- let current_process = unsafe { GetCurrentProcess ( ) } ;
440-
441- let mut thread_handle = HANDLE :: default ( ) ;
442- unsafe {
443- _ = DuplicateHandle (
444- current_process,
445- pseudo_handle,
446- current_process,
447- & mut thread_handle,
448- 0 ,
449- false ,
450- DUPLICATE_SAME_ACCESS ,
451- ) ;
452- }
453-
454- * lock = Some ( thread_handle) ;
455- } ) ,
456- // cb
457- move |command| {
458- if let ClientCommand :: Event ( EventCommand :: Changed ( data) ) = command {
459- Python :: with_gil ( |py| {
460- let state = state_to_pylist ( py, & data) ;
461- let Ok ( state) = state else {
462- return ;
463- } ;
464-
465- if let Err ( e) = callback. call1 ( py, ( state, ) ) {
466- e. print ( py) ;
467- }
468- } ) ;
469- }
470- } ,
471- ) ;
472425 }
473426
474427 /// Find a monitor by Id
0 commit comments