From 56337b00ea46d96037037816d7b5c7904825b8a9 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 9 Feb 2012 12:04:42 -0800 Subject: [PATCH] Add global_event_loop() and GlibEventLoop. This causes all PollScheduler instances within a given process to share a singleton EventLoop instance, and also makes it possible to swap in glib's main loop for all portage event loops in the main process. --- pym/_emerge/PollScheduler.py | 4 +-- pym/portage/util/_eventloop/EventLoop.py | 2 ++ pym/portage/util/_eventloop/GlibEventLoop.py | 20 +++++++++++ .../util/_eventloop/global_event_loop.py | 36 +++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 pym/portage/util/_eventloop/GlibEventLoop.py create mode 100644 pym/portage/util/_eventloop/global_event_loop.py diff --git a/pym/_emerge/PollScheduler.py b/pym/_emerge/PollScheduler.py index 165c618d1..3b86fa08e 100644 --- a/pym/_emerge/PollScheduler.py +++ b/pym/_emerge/PollScheduler.py @@ -12,7 +12,7 @@ except ImportError: from portage import _encodings from portage import _unicode_encode from portage.util import writemsg_level -from portage.util._eventloop.EventLoop import EventLoop +from portage.util._eventloop.global_event_loop import global_event_loop from _emerge.SlotObject import SlotObject from _emerge.getloadavg import getloadavg @@ -32,7 +32,7 @@ class PollScheduler(object): self._jobs = 0 self._scheduling = False self._background = False - self._event_loop = EventLoop() + self._event_loop = global_event_loop() self.sched_iface = self._sched_iface_class( idle_add=self._event_loop.idle_add, io_add_watch=self._event_loop.io_add_watch, diff --git a/pym/portage/util/_eventloop/EventLoop.py b/pym/portage/util/_eventloop/EventLoop.py index 3f4d35445..aa78ccd15 100644 --- a/pym/portage/util/_eventloop/EventLoop.py +++ b/pym/portage/util/_eventloop/EventLoop.py @@ -13,6 +13,8 @@ from _emerge.PollSelectAdapter import PollSelectAdapter class EventLoop(object): + supports_multiprocessing = True + class _idle_callback_class(SlotObject): __slots__ = ("args", "callback", "source_id") diff --git a/pym/portage/util/_eventloop/GlibEventLoop.py b/pym/portage/util/_eventloop/GlibEventLoop.py new file mode 100644 index 000000000..b35772e7f --- /dev/null +++ b/pym/portage/util/_eventloop/GlibEventLoop.py @@ -0,0 +1,20 @@ +# Copyright 2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import portage +portage.proxy.lazyimport.lazyimport(globals(), + 'glib', +) + +class GlibEventLoop(object): + + # TODO: Support multiprocessing by using a separate glib.MainContext + # instance for each process. + supports_multiprocessing = False + + def __init__(self): + self.iteration = glib.main_context_default().iteration + self.idle_add = glib.idle_add + self.io_add_watch = glib.io_add_watch + self.timeout_add = glib.timeout_add + self.source_remove = glib.source_remove diff --git a/pym/portage/util/_eventloop/global_event_loop.py b/pym/portage/util/_eventloop/global_event_loop.py new file mode 100644 index 000000000..0f0c53f2b --- /dev/null +++ b/pym/portage/util/_eventloop/global_event_loop.py @@ -0,0 +1,36 @@ +# Copyright 2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import os + +from portage.util._eventloop.EventLoop import EventLoop + +_default_constructor = EventLoop +#from portage.util._eventloop.GlibEventLoop \ +# import GlibEventLoop as _default_constructor + +# If _default_constructor doesn't support multiprocessing, +# then _multiprocessing_constructor is used in subprocesses. +_multiprocessing_constructor = EventLoop + +_MAIN_PID = os.getpid() +_instances = {} + +def global_event_loop(): + """ + Get a global EventLoop (or compatible object) instance which + belongs exclusively to the current process. + """ + + pid = os.getpid() + instance = _instances.get(pid) + if instance is not None: + return instance + + constructor = _default_constructor + if not constructor.supports_multiprocessing and pid != _MAIN_PID: + constructor = _multiprocessing_constructor + + instance = constructor() + _instances[pid] = instance + return instance -- 2.26.2