Skip to content

Commit db81e72

Browse files
authored
Merge pull request slgobinath#697 from deltragon/smartpause-extidle-noblocking
smartpause: ext_idle_notify: avoid blocking for long time when shutting down
2 parents 9e3e35d + 1b7fb1e commit db81e72

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

safeeyes/plugins/smartpause/ext_idle_notify.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import threading
2222
import datetime
23+
import os
24+
import select
2325

2426
from pywayland.client import Display
2527
from pywayland.protocol.wayland.wl_seat import WlSeat
@@ -33,19 +35,26 @@ class ExtIdleNotify:
3335
_notifier_set = False
3436
_running = True
3537
_thread = None
38+
_r_channel = None
39+
_w_channel = None
3640

3741
_idle_since = None
3842

3943
def __init__(self):
4044
self._display = Display()
4145
self._display.connect()
46+
self._r_channel, self._w_channel = os.pipe()
4247

4348
def stop(self):
4449
self._running = False
50+
# write anything, just to wake up the channel
51+
os.write(self._w_channel, b"!")
4552
self._notification.destroy()
4653
self._notification = None
4754
self._seat = None
4855
self._thread.join()
56+
os.close(self._r_channel)
57+
os.close(self._w_channel)
4958

5059
def run(self):
5160
self._thread = threading.Thread(
@@ -57,8 +66,26 @@ def _run(self):
5766
reg = self._display.get_registry()
5867
reg.dispatcher["global"] = self._global_handler
5968

69+
display_fd = self._display.get_fd()
70+
6071
while self._running:
61-
self._display.dispatch(block=True)
72+
self._display.flush()
73+
74+
# this blocks until either there are new events in self._display
75+
# (retrieved using dispatch())
76+
# or until there are events in self._r_channel - which means that stop()
77+
# was called
78+
# unfortunately, this seems like the best way to make sure that dispatch
79+
# doesn't block potentially forever (up to multiple seconds in my usage)
80+
read, _w, _x = select.select((display_fd, self._r_channel), (), ())
81+
82+
if self._r_channel in read:
83+
# the channel was written to, which means stop() was called
84+
# at this point, self._running should be false as well
85+
break
86+
87+
if display_fd in read:
88+
self._display.dispatch(block=True)
6289

6390
self._display.disconnect()
6491

0 commit comments

Comments
 (0)