Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions asyncio_glib/glib_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def __init__(self, main_context=None):
main_context = GLib.MainContext.default()
selector = glib_selector.GLibSelector(main_context)
super().__init__(selector)
# GSource only has timeouts with 1ms accuracy
self._clock_resolution = 1e-3


class GLibEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
Expand Down
37 changes: 10 additions & 27 deletions asyncio_glib/glib_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,17 @@
'GLibSelector',
)


# The override for GLib.MainLoop.run installs a signal wakeup fd,
# which interferes with asyncio signal handlers. Try to get the
# direct version.
try:
g_main_loop_run = super(GLib.MainLoop, GLib.MainLoop).run
except AttributeError:
g_main_loop_run = GLib.MainLoop.run


class _SelectorSource(GLib.Source):
"""A GLib source that gathers selector """

def __init__(self, main_loop):
def __init__(self):
super().__init__()
self._fd_to_tag = {}
self._fd_to_events = {}
self._main_loop = main_loop
self._iteration_timeout = 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick, I would drop the leading '_' or set it through a function, honoring the python convention of 'private variables'.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is completely normal to add a leading _ for internal (module private) variables. Or is that for private to subclasses only?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not explicitly defined in PEP8 however as in lots of (if not all) languages where there exists a strict private/protected keyword, this applies to the context of definition. Thus in this case the _SelectorSource class, which on its turn can be and is marked as internal within the module scope (which will exclude it and all its members from a default import).
On line 83 and 85 the _iteration_timeout variable is accessed from outside of the class scope, hence implying it should actually be public.
But again, it's just a nitpick (and probably something contested, which you get with conventions)


def prepare(self):
return False, -1
return False, self._iteration_timeout

def check(self):
return False
Expand All @@ -41,7 +31,6 @@ def dispatch(self, callback, args):
if condition & GLib.IOCondition.OUT:
events |= selectors.EVENT_WRITE
self._fd_to_events[fd] = events
self._main_loop.quit()
return GLib.SOURCE_CONTINUE

def register(self, fd, events):
Expand Down Expand Up @@ -70,8 +59,7 @@ class GLibSelector(selectors._BaseSelectorImpl):
def __init__(self, context):
super().__init__()
self._context = context
self._main_loop = GLib.MainLoop.new(self._context, False)
self._source = _SelectorSource(self._main_loop)
self._source = _SelectorSource()
self._source.attach(self._context)

def close(self):
Expand All @@ -89,20 +77,15 @@ def unregister(self, fileobj):
return key

def select(self, timeout=None):
may_block = True
self._source.set_ready_time(-1)
# Calling .set_ready_time() always causes a mainloop iteration to finish.
if timeout is not None:
if timeout > 0:
self._source.set_ready_time(
GLib.get_monotonic_time() + int(timeout * 1000000))
else:
may_block = False
# Negative timeout implies an immediate dispatch
self._source._iteration_timeout = int(max(0, timeout) * 1000)
else:
self._source._iteration_timeout = -1

self._source.clear()
if may_block:
g_main_loop_run(self._main_loop)
else:
self._context.iteration(False)
self._context.iteration(True)

ready = []
for key in self.get_map().values():
Expand Down
3 changes: 3 additions & 0 deletions tests/test_glib_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ def SELECTOR(self):

def test_select_interrupt_exc(self):
raise unittest.SkipTest("TODO")

def test_select_interrupt_noraise(self):
raise unittest.SkipTest("TODO")