示例#1
0
    def abort(self):
        """Abort any queued up calls.

        Can still be reused afterwards.
        """

        if self.dirty:
            GLib.source_remove(self._id)
            self.dirty = False
            self.args = None
示例#2
0
    def call(self, func, *args, **kwargs):
        """Runs the function in the main loop and blocks until
        it is finshed or abort() was called. In case this is called
        from the main loop the function gets executed immediately.

        The priority kwargs defines the event source priority and will
        not be passed to func.

        In case a timeout kwarg is given the call will raise
        MainRunnerTimeoutError in case the function hasn't been scheduled
        (doesn't mean returned) until that time. timeout is a float in seconds.

        Can raise MainRunnerError in case the function raises an exception.
        Raises MainRunnerAbortedError in case the runner was aborted.
        Raises MainRunnerTimeoutError in case the timeout was reached.
        """

        with self._lock:
            if self._aborted:
                # Make sure we have a debug statment if we catch this error accidently
                logger.debug(
                    "Ran {}| self.aborted={}".format(
                        sys._getframe().f_code.co_name, self._aborted
                    )
                )
                raise self._error  # pylint: disable=raising-bad-type
            self._error = None
            # XXX: ideally this should be GLib.MainContext.default().is_owner()
            # but that's not available in older pygobject
            if is_main_thread():
                kwargs.pop("priority", None)
                self._run(func, *args, **kwargs)
            else:
                assert self._source_id is None
                assert self._call_id is None
                timeout = kwargs.pop("timeout", None)
                call_event = threading.Event()
                self._call_id = object()
                self._source_id = GLib.idle_add(
                    self._idle_run, self._call_id, call_event, func, *args, **kwargs
                )
                # only wait for the result if we are sure it got scheduled
                if call_event.wait(timeout):
                    self._cond.wait()
                self._call_id = None
                if self._source_id is not None:
                    GLib.source_remove(self._source_id)
                    self._source_id = None
                    raise MainRunnerTimeoutError("timeout: %r" % timeout)
            if self._error is not None:
                raise self._error  # pylint: disable=raising-bad-type
            return self._return
示例#3
0
 def PropertiesChanged(self, interface_name, changed_properties,
                       invalidated_properties):
     self.con.emit_signal(
         None,
         "/org/scarlett/Listener",
         "org.freedesktop.DBus.Properties",
         "PropertiesChanged",
         GLib.Variant.new_tuple(
             GLib.Variant("s", interface_name),
             GLib.Variant("a{sv}", changed_properties),
             GLib.Variant("as", invalidated_properties),
         ),
     )
def create_glib_main_loop():
    mainloop = GLib.MainLoop()
    timed_out = False

    def quit_cb(unused):
        # source: http://stackoverflow.com/questions/1261875/python-nonlocal-statement
        # source: https://www.smallsurething.com/a-quick-guide-to-nonlocal-in-python-3/
        #
        # Now, by adding nonlocal timed_out to the top of quit_cb,
        # Python knows that when it sees an assignment to timed_out,
        # it should assign to the variable from the outer scope
        # instead of declaring a new variable that shadows its name.
        nonlocal timed_out
        timed_out = True
        mainloop.quit()

    def run(timeout_seconds=5):
        source = GLib.timeout_source_new_seconds(timeout_seconds)
        source.set_callback(quit_cb)
        source.attach()
        GLib.MainLoop.run(mainloop)
        source.destroy()
        if timed_out:
            raise Exception("Timed out after %s seconds" % timeout_seconds)

    mainloop.run = run
    return mainloop
示例#5
0
    def on_method_call(
        self,
        connection,
        sender,
        object_path,
        interface_name,
        method_name,
        parameters,
        invocation,
    ):

        args = list(parameters.unpack())
        for i, sig in enumerate(self.method_inargs[method_name]):
            if sig is "h":
                msg = invocation.get_message()
                fd_list = msg.get_unix_fd_list()
                args[i] = fd_list.get(args[i])

        result = getattr(self, method_name)(*args)

        # out_args is atleast (signature1). We therefore always wrap the result
        # as a tuple. Refer to https://bugzilla.gnome.org/show_bug.cgi?id=765603
        result = (result, )

        out_args = self.method_outargs[method_name]
        if out_args != "()":
            variant = GLib.Variant(out_args, result)
            invocation.return_value(variant)
        else:
            invocation.return_value(None)
示例#6
0
    def __runner(self):
        self.__gloop = GLib.MainLoop()
        try:
            self.__gloop.run()
            # Definition: GLib.MainLoop.get_context

            # The GLib.MainContext with which the source is associated,
            # or None if the context has not yet been added to a source.
            # Return type: GLib.MainContext or None

            # Gets the GLib.MainContext with which the source is associated.
            # You can call this on a source that has been destroyed,
            # provided that the GLib.MainContext it was attached to still
            # exists (in which case it will return that GLib.MainContext).
            # In particular, you can always call this function on the
            # source returned from GLib.main_current_source().
            # But calling this function on a source whose
            # GLib.MainContext has been destroyed is an error.
            context = self.__gloop.get_context()
            while self.__active:
                context.iteration(False)
                if not context.pending():
                    time.sleep(.1)
        except KeyboardInterrupt:
            self.__active = False
示例#7
0
    def run(self):
        """Run the process."""

        # NOTE: DO_NOT_REAP_CHILD: the child will not be automatically reaped;
        # you must use g_child_watch_add yourself (or call waitpid or handle `SIGCHLD` yourself),
        # or the child will become a zombie.
        # source:
        # http://valadoc.org/#!api=glib-2.0/GLib.SpawnFlags.DO_NOT_REAP_CHILD

        # NOTE: SEARCH_PATH: argv[0] need not be an absolute path, it will be looked for in the user's PATH
        # source:
        # http://lazka.github.io/pgi-docs/#GLib-2.0/flags.html#GLib.SpawnFlags.SEARCH_PATH

        self.pid, self.stdin, self.stdout, self.stderr = self.spawn_command()

        logger.debug("command: {}".format(self.command))
        logger.debug("stdin: {}".format(self.stdin))
        logger.debug("stdout: {}".format(self.stdout))
        logger.debug("stderr: {}".format(self.stderr))
        logger.debug("pid: {}".format(self.pid))

        # close file descriptor
        self.pid.close()

        print(self.stderr)

        # NOTE: GLib.PRIORITY_HIGH = -100
        # Use this for high priority event sources.
        # It is not used within GLib or GTK+.
        watch = GLib.child_watch_add(GLib.PRIORITY_HIGH, self.pid, self.exited_cb)

        return self.pid
示例#8
0
 def run(timeout_seconds=5):
     source = GLib.timeout_source_new_seconds(timeout_seconds)
     source.set_callback(quit_cb)
     source.attach()
     GLib.MainLoop.run(mainloop)
     source.destroy()
     if timed_out:
         raise Exception("Timed out after %s seconds" % timeout_seconds)
示例#9
0
 def run(timeout_seconds=5):
     source = GLib.timeout_source_new_seconds(timeout_seconds)
     source.set_callback(quit_cb)
     source.attach()
     GLib.MainLoop.run(mainloop)
     source.destroy()
     if timed_out:
         raise Exception("Timed out after %s seconds" % timeout_seconds)
示例#10
0
    def abort(self):
        """After this call returns no function will be executed anymore
        and a currently blocking call will fail with MainRunnerAbortedError.

        Can be called multiple times and can not fail.
        call() will always fail after this was called.
        """

        with self._lock:
            if self._aborted:
                return
            if self._source_id is not None:
                GLib.source_remove(self._source_id)
                self._source_id = None
            self._aborted = True
            self._call_id = None
            self._error = MainRunnerAbortedError("aborted")
            self._cond.notify()
示例#11
0
 def GetAll(self, interface_name):
     if interface_name == ScarlettListener.LISTENER_IFACE:
         return {
             "CanQuit": GLib.Variant("b", True),
             "Fullscreen": GLib.Variant("b", False),
             "HasTrackList": GLib.Variant("b", True),
             "Identity": GLib.Variant("s", "Scarlett"),
             "DesktopEntry": GLib.Variant("s", "scarlett-listener"),
         }
     elif interface_name == "org.freedesktop.DBus.Properties":
         return {}
     elif interface_name == "org.freedesktop.DBus.Introspectable":
         return {}
     else:
         raise Exception(
             "org.scarlett.ScarlettListener1",
             "This object does not implement the %s interface" %
             interface_name,
         )
示例#12
0
    def __init__(self, func, timeout=None, owner=None, priority=None):
        """Timeout in milliseconds"""

        self.func = func
        self.dirty = False
        self.args = None

        if owner:

            def destroy_cb(owner):
                self.abort()

            owner.connect("destroy", destroy_cb)

        if priority is None:
            priority = GLib.PRIORITY_DEFAULT

        if timeout is None:
            self.do_idle_add = lambda f: GLib.idle_add(f, priority=priority)
        else:
            self.do_idle_add = lambda f: GLib.timeout_add(timeout, f, priority=priority)
示例#13
0
 def ListenerReadySignal(self, message, scarlett_sound):
     logger.debug(" sending message: {}".format(message))
     bus = self.dbus_stack[0]
     # (ss) - struct/tuple containing 2 strings.
     listener_rdy_status = GLib.Variant("(ss)", (message, scarlett_sound))
     bus.emit_signal(
         None,
         "/org/scarlett/Listener",
         "org.scarlett.Listener",
         "ListenerReadySignal",
         listener_rdy_status,
     )
示例#14
0
 def CommandRecognizedSignal(self, message, scarlett_sound, scarlett_cmd):
     logger.debug(" sending message: {}".format(message))
     bus = self.dbus_stack[0]
     # (sss) - struct/tuple containing 3 strings.
     cmd_rec_status = GLib.Variant("(sss)",
                                   (message, scarlett_sound, scarlett_cmd))
     bus.emit_signal(
         None,
         "/org/scarlett/Listener",
         "org.scarlett.Listener",
         "CommandRecognizedSignal",
         cmd_rec_status,
     )
示例#15
0
def run_emitter_signal(request, get_environment, sig_name="ready"):
    print("Setting up emitter")
    print("[Emit]: {}".format(sig_name))

    # Return return code for running shell out command
    def cb(pid, status):
        """
        Set return code for emitter shell script.
        """
        print("status code: {}".format(status))

    # Send [ready] signal to dbus service
    # FIXME: THIS IS THE CULPRIT
    argv = [sys.executable, "-m", "scarlett_os.emitter", "-s", sig_name]

    # convert environment dict -> list of strings
    env_dict_to_str = ["{}={}".format(k, v) for k, v in get_environment.items()]

    # Async background call. Send a signal to running process.
    pid, stdin, stdout, stderr = GLib.spawn_async(
        argv,
        envp=env_dict_to_str,
        working_directory=PROJECT_ROOT,
        flags=GLib.SpawnFlags.DO_NOT_REAP_CHILD,
    )

    print("run_emitter_signal: stdout")
    print(stdout)
    print("run_emitter_signal: stderr")
    print(stderr)
    print("run_emitter_signal: stdin")
    print(stdin)

    # Close file descriptor when finished running scarlett emitter
    pid.close()

    # NOTE: We give this PRIORITY_HIGH to ensure callback [cb] runs before dbus signal callback
    id = GLib.child_watch_add(GLib.PRIORITY_HIGH, pid, cb)
示例#16
0
 def KeywordRecognizedSignal(self, message, scarlett_sound):
     logger.debug(" sending message: {}".format(message))
     bus = self.dbus_stack[0]
     logger.debug("Inside KeywordRecognizedSignal. Dump bus object")
     pp.pprint(bus)
     # (ss) - struct/tuple containing 2 strings.
     kw_rec_status = GLib.Variant("(ss)", (message, scarlett_sound))
     bus.emit_signal(
         None,
         "/org/scarlett/Listener",
         "org.scarlett.Listener",
         "KeywordRecognizedSignal",
         kw_rec_status,
     )
示例#17
0
 def ConnectedToListener(self, scarlett_plugin):
     logger.debug(" Client Connected: {}".format(scarlett_plugin))
     bus = self.dbus_stack[0]
     # s - dbus.String a subclass of unicode
     logger.debug(" Client Type: {}".format(type(scarlett_plugin)))
     # GLib-GIO-CRITICAL fix s -> (s)
     # source: http://stackoverflow.com/questions/28949009/glib-gio-critical-error-while-invoking-a-method-on-dbus-interface
     conn_to_lis_status = GLib.Variant("(s)", (scarlett_plugin, ))
     bus.emit_signal(
         None,
         "/org/scarlett/Listener",
         "org.scarlett.Listener",
         "ConnectedToListener",
         conn_to_lis_status,
     )
示例#18
0
 def spawn_command(self):
     """Return: Tuple (pid(int), stdin, stdout, stderr)"""
     # TODO: Add this so we can toggle stdout/error returned to variable
     # return GLib.spawn_async(self.command,
     #                         flags=GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
     #                         standard_input=standard_input,
     #                         standard_output=standard_output,
     #                         standard_error=standard_error
     #                         )
     # DO_NOT_REAP_CHILD
     # Don't reap process automatically so it is possible to detect when it is closed.
     return GLib.spawn_async(
         self.command,
         flags=GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
     )
示例#19
0
def create_main_loop():
    """Create isolated GLibMainloop for testing."""
    mainloop = GLib.MainLoop()
    timed_out = False

    def quit_cb(unused):
        nonlocal timed_out  # noqa
        timed_out = True
        mainloop.quit()

    def run(timeout_seconds=5):
        source = GLib.timeout_source_new_seconds(timeout_seconds)
        source.set_callback(quit_cb)
        source.attach()
        GLib.MainLoop.run(mainloop)
        source.destroy()
        if timed_out:
            raise Exception("Timed out after %s seconds" % timeout_seconds)

    mainloop.run = run
    return mainloop
示例#20
0
def spawn(argv, stdout=False):
    """Asynchronously run a program. argv[0] is the executable name, which
    must be fully qualified or in the path. If stdout is True, return
    a file object corresponding to the child's standard output; otherwise,
    return the child's process ID.

    argv must be strictly str objects to avoid encoding confusion.
    """

    types = map(type, argv)
    if not (min(types) == max(types) == str):
        raise TypeError("executables and arguments must be str objects")
    logger.debug("Running %r" % " ".join(argv))
    args = GLib.spawn_async(
        argv=argv, flags=GLib.SpawnFlags.SEARCH_PATH, standard_output=stdout
    )

    if stdout:
        return os.fdopen(args[2])
    else:
        return args[0]
示例#21
0
        faulthandler.register(signal.SIGUSR2, all_threads=True)

        from scarlett_os.internal.debugger import init_debugger

        init_debugger()

        from scarlett_os.internal.debugger import enable_remote_debugging

        enable_remote_debugging()

    from scarlett_os.logger import setup_logger

    setup_logger()

    loop = GLib.MainLoop()

    to_complete = 2

    class TestThread(SuspendableThread):
        def do_run(self):
            for n in range(1000):
                time.sleep(0.01)
                self.emit("progress", n / 1000.0, "%s of 1000" % n)
                self.check_for_sleep()

    class TestError(SuspendableThread):
        def do_run(self):
            for n in range(1000):
                time.sleep(0.01)
                if n == 100:
    def test_ThreadManager_TThread(self, tmanager):
        blacklist_threads = [
            "MainThread",
            "HistorySavingThread",
            "IPythonHistorySavingThread",
            "Dummy",
            "Thread",
        ]
        whitelist_threads = [
            "SuspendableMainLoopThread",
            "NTsafeThread",
            "TInterminable",
            "TError",
            "TThread",
        ]
        # MainThread
        # IPythonHistorySavingThread
        # SuspendableMainLoopThread
        # IPythonHistorySavingThread
        # Dummy-6
        # Thread-1

        tm = tmanager

        assert (str(type(tm)) ==
                "<class 'scarlett_os.utility.threadmanager.ThreadManager'>")

        assert tm.active_count == 0
        assert tm.completed_threads == 0
        assert tm.count == 0
        assert tm.max_concurrent_threads == 2
        assert tm.thread_queue == []
        assert tm.threads == []

        # import pdb
        # pdb.set_trace()

        loop = GLib.MainLoop()

        to_complete = 2

        for desc, thread in [("Linear 1", TThread()), ("Linear 2", TThread())]:
            tm.add_thread(thread)

        # import pdb;pdb.set_trace()

        def get_tm_active_count(*args):
            print("time.sleep(3)")
            time.sleep(3)
            if int(tm.completed_threads) < to_complete:
                print("tm.completed_threads < to_complete: {} < {} friends.".
                      format(tm.completed_threads, to_complete))
                # NOTE: keep running callback
                return True
            else:
                print("tm.completed_threads <= to_complete: {} < {} friends.".
                      format(tm.completed_threads, to_complete))

                # tm.completed_threads < to_complete: 0 < 2 friends.
                # tm.completed_threads <= to_complete: 2 < 2 friends.
                # Current Thread via t_in_progress_intgr.getName(): [MainThread]
                # Current Thread via t_in_progress_intgr.getName(): [IPythonHistorySavingThread]
                # Current Thread via t_in_progress_intgr.getName(): [IPythonHistorySavingThread]
                # Current Thread via t_in_progress_intgr.getName(): [Dummy-5]
                # Current Thread via t_in_progress_intgr.getName(): [Dummy-2]
                # Current Thread via t_in_progress_intgr.getName(): [SuspendableMainLoopThread]
                # Current Thread via t_in_progress_intgr.getName(): [Thread-1]
                # Another process is in progress
                #########################################################################################
                # Return a list of all Thread objects currently alive. The list includes daemonic threads,
                # dummy thread objects created by current_thread(), and the main thread.
                # It excludes terminated threads and threads that have not yet been started.
                #########################################################################################
                threads = threading.enumerate()
                # source: http://www.diveintopython.net/power_of_introspection/filtering_lists.html
                filtered_threads = [
                    elem for elem in threads
                    if elem.getName() in whitelist_threads
                ]
                print("threads = threading.enumerate(): {}".format(
                    filtered_threads))
                for t_print in filtered_threads:
                    print("****************************")
                    print(t_print)
                    print(t_print.getName())
                    print("****************************")

                if len(filtered_threads) > 1:
                    msg = "Another process is in progress"
                    for t_in_progress_intgr in filtered_threads:
                        print(
                            "Current Thread via t_in_progress_intgr.getName(): [{}]"
                            .format(t_in_progress_intgr.getName()))
                        if "SuspendableMainLoopThread" in t_in_progress_intgr.getName(
                        ):
                            msg = _(
                                "An SuspendableMainLoopThread is in progress.")
                        if "export" in t_in_progress_intgr.getName():
                            msg = _("An export is in progress.")
                        if "delete" in t_in_progress_intgr.getName():
                            msg = _("A delete is in progress.")
                        if "TThread" in t_in_progress_intgr.getName():
                            msg = _("A TThread delete is in progress.")
                    # source: https://github.com/thinkle/gourmet/blob/a97af28b79af7cf1181b8bbd14c61eb396eb7ac6/gourmet/GourmetRecipeManager.py
                    print(msg)

                # Normally this is a diaologe where someone selects "yes i'm sure"
                quit_anyway = True

                if quit_anyway:
                    for (t_quit_anyway_intgr) in filtered_threads:  # pylint: disable=C0103
                        if t_quit_anyway_intgr.getName() in whitelist_threads:
                            try:
                                print(
                                    "QUIT ANYWAY t_in_progress_intgr.getName(): [{}]"
                                    .format(t_quit_anyway_intgr.getName()))
                                t_quit_anyway_intgr.terminate()
                            except BaseException as t_quit_anyway_intgr_exec:  # pylint: disable=C0103
                                print("Unable to terminate thread %s" %
                                      t_quit_anyway_intgr)
                                print(
                                    "[t_quit_anyway_intgr.terminate()] Recieved: {}"
                                    .format(str(t_quit_anyway_intgr_exec)))
                                # try not to lose data if this is going to
                                # end up in a force quit
                                return True
                        else:
                            print(
                                "t_quit_anyway_intgr.getName() in whitelist_threads == FALSE, continue callback"
                            )
                            # thread is not part of the whitelist threads list, continue callback
                            return True
                        # end - if t_quit_anyway_intgr.getName() in whitelist_threads:
                else:
                    print("quit_anyway set to false. continue callback")
                    # continue callback
                    return True

                print(__name__ + ".loop.quit()")
                loop.quit()
                # remove callback
                print(__name__ + ": remove callback")
                return False

        GLib.timeout_add_seconds(10, get_tm_active_count)
        loop.run()
示例#23
0
    def test_SuspendableMainLoopThread(
        self, listener_mocker_stopall, listener_monkeyfunc
    ):
        def my_signal_handler_cb(*args):
            assert len(args) == 5
            assert isinstance(args[0], C)
            assert args[0] == inst

            assert isinstance(args[1], int)
            assert args[1] == 42

            assert args[2:] == (1, 2, 3)

        def quit(*args):
            print(
                "timeout reached, lets close out SuspendableMainLoopThread in [test_SuspendableMainLoopThread]"
            )
            with _loop_thread_lock:
                time.sleep(0.5)
                print(
                    "SuspendableMainLoopThread attempting to terminate in [test_SuspendableMainLoopThread]"
                )
                print("running: _shared_loop_thread.terminate()")
                _shared_loop_thread.terminate()
                # print('running: stop_event.set()')
                # stop_event.set()
                # FIXME: DISABLED 5/9/2017 # SINCE YOU CAN'T JOIN CURRENT THREAD # print('SuspendableMainLoopThread attempting to join in [test_SuspendableMainLoopThread]')
                # FIXME: DISABLED 5/9/2017 # SINCE YOU CAN'T JOIN CURRENT THREAD # _shared_loop_thread.join(2)

        _shared_loop_thread = None
        _loop_thread_lock = threading.RLock()
        # stop_event = threading.Event()

        with _loop_thread_lock:
            print(
                "SuspendableMainLoopThread _loop_thread_lock acquired in [test_SuspendableMainLoopThread]"
            )
            if not _shared_loop_thread:
                print(
                    "SuspendableMainLoopThread if not _shared_loop_thread in [test_SuspendableMainLoopThread]"
                )
                # Start a new thread.
                print("[start] new listener.SuspendableMainLoopThread()")
                # _shared_loop_thread = listener.SuspendableMainLoopThread(stop_event)
                _shared_loop_thread = listener.SuspendableMainLoopThread()
                # get MainLoop
                print("[start] _shared_loop_thread.get_loop()")
                _ = _shared_loop_thread.get_loop()
                # disable daemon thread for testing
                # that way thread dies after .terminate() is called
                # instead of during garbage collection during exit() of python interperter
                print(
                    "[start] listener_monkeyfunc.setattr(__name__ + '.listener.SuspendableMainLoopThread.daemon', False)"
                )
                listener_monkeyfunc.setattr(
                    __name__ + ".listener.SuspendableMainLoopThread.daemon", False
                )
                # validate monkeypatch worked
                assert _shared_loop_thread.daemon is False
                # start thread
                print("[start] _shared_loop_thread.start()")
                _shared_loop_thread.start()
                # this should simply return
                print("[start] _shared_loop_thread.do_run()")
                _shared_loop_thread.do_run()
                # FIXME: This is still returning a Mock
                # assert str(type(_shared_loop_thread.get_loop())) == "<class 'gi.overrides.GLib.MainLoop'>"

        inst = C()
        inst.connect("my_signal", my_signal_handler_cb, 1, 2, 3)

        inst.emit("my_signal", 42)
        assert inst.arg == 42

        # Create a timeout that checks how many
        # tasks have been completed. When 2 have finished,
        # kill threads and finish.
        # GLib.timeout_add_seconds(10, quit, _shared_loop_thread, _loop_thread_lock, stop_event)
        GLib.timeout_add_seconds(10, quit, _shared_loop_thread, _loop_thread_lock)
示例#24
0
 def notify_observers(self, info):
     for obs in self._observers:
         event = threading.Event()
         GLib.idle_add(obs.update, event, info)
    def test_ThreadManager_TThread(self, tmanager):
        blacklist_threads = [
            "MainThread",
            "HistorySavingThread",
            "IPythonHistorySavingThread",
            "Dummy",
            "Thread",
        ]
        whitelist_threads = [
            "SuspendableMainLoopThread",
            "NTsafeThread",
            "TInterminable",
            "TError",
            "TThread",
        ]
        # MainThread
        # IPythonHistorySavingThread
        # SuspendableMainLoopThread
        # IPythonHistorySavingThread
        # Dummy-6
        # Thread-1

        tm = tmanager

        assert (
            str(type(tm)) == "<class 'scarlett_os.utility.threadmanager.ThreadManager'>"
        )

        assert tm.active_count == 0
        assert tm.completed_threads == 0
        assert tm.count == 0
        assert tm.max_concurrent_threads == 2
        assert tm.thread_queue == []
        assert tm.threads == []

        # import pdb
        # pdb.set_trace()

        loop = GLib.MainLoop()

        to_complete = 2

        for desc, thread in [("Linear 1", TThread()), ("Linear 2", TThread())]:
            tm.add_thread(thread)

        # import pdb;pdb.set_trace()

        def get_tm_active_count(*args):
            print("time.sleep(3)")
            time.sleep(3)
            if int(tm.completed_threads) < to_complete:
                print(
                    "tm.completed_threads < to_complete: {} < {} friends.".format(
                        tm.completed_threads, to_complete
                    )
                )
                # NOTE: keep running callback
                return True
            else:
                print(
                    "tm.completed_threads <= to_complete: {} < {} friends.".format(
                        tm.completed_threads, to_complete
                    )
                )

                # tm.completed_threads < to_complete: 0 < 2 friends.
                # tm.completed_threads <= to_complete: 2 < 2 friends.
                # Current Thread via t_in_progress_intgr.getName(): [MainThread]
                # Current Thread via t_in_progress_intgr.getName(): [IPythonHistorySavingThread]
                # Current Thread via t_in_progress_intgr.getName(): [IPythonHistorySavingThread]
                # Current Thread via t_in_progress_intgr.getName(): [Dummy-5]
                # Current Thread via t_in_progress_intgr.getName(): [Dummy-2]
                # Current Thread via t_in_progress_intgr.getName(): [SuspendableMainLoopThread]
                # Current Thread via t_in_progress_intgr.getName(): [Thread-1]
                # Another process is in progress
                #########################################################################################
                # Return a list of all Thread objects currently alive. The list includes daemonic threads,
                # dummy thread objects created by current_thread(), and the main thread.
                # It excludes terminated threads and threads that have not yet been started.
                #########################################################################################
                threads = threading.enumerate()
                # source: http://www.diveintopython.net/power_of_introspection/filtering_lists.html
                filtered_threads = [
                    elem for elem in threads if elem.getName() in whitelist_threads
                ]
                print("threads = threading.enumerate(): {}".format(filtered_threads))
                for t_print in filtered_threads:
                    print("****************************")
                    print(t_print)
                    print(t_print.getName())
                    print("****************************")

                if len(filtered_threads) > 1:
                    msg = "Another process is in progress"
                    for t_in_progress_intgr in filtered_threads:
                        print(
                            "Current Thread via t_in_progress_intgr.getName(): [{}]".format(
                                t_in_progress_intgr.getName()
                            )
                        )
                        if "SuspendableMainLoopThread" in t_in_progress_intgr.getName():
                            msg = _("An SuspendableMainLoopThread is in progress.")
                        if "export" in t_in_progress_intgr.getName():
                            msg = _("An export is in progress.")
                        if "delete" in t_in_progress_intgr.getName():
                            msg = _("A delete is in progress.")
                        if "TThread" in t_in_progress_intgr.getName():
                            msg = _("A TThread delete is in progress.")
                    # source: https://github.com/thinkle/gourmet/blob/a97af28b79af7cf1181b8bbd14c61eb396eb7ac6/gourmet/GourmetRecipeManager.py
                    print(msg)

                # Normally this is a diaologe where someone selects "yes i'm sure"
                quit_anyway = True

                if quit_anyway:
                    for (
                        t_quit_anyway_intgr
                    ) in filtered_threads:  # pylint: disable=C0103
                        if t_quit_anyway_intgr.getName() in whitelist_threads:
                            try:
                                print(
                                    "QUIT ANYWAY t_in_progress_intgr.getName(): [{}]".format(
                                        t_quit_anyway_intgr.getName()
                                    )
                                )
                                t_quit_anyway_intgr.terminate()
                            except BaseException as t_quit_anyway_intgr_exec:  # pylint: disable=C0103
                                print(
                                    "Unable to terminate thread %s"
                                    % t_quit_anyway_intgr
                                )
                                print(
                                    "[t_quit_anyway_intgr.terminate()] Recieved: {}".format(
                                        str(t_quit_anyway_intgr_exec)
                                    )
                                )
                                # try not to lose data if this is going to
                                # end up in a force quit
                                return True
                        else:
                            print(
                                "t_quit_anyway_intgr.getName() in whitelist_threads == FALSE, continue callback"
                            )
                            # thread is not part of the whitelist threads list, continue callback
                            return True
                        # end - if t_quit_anyway_intgr.getName() in whitelist_threads:
                else:
                    print("quit_anyway set to false. continue callback")
                    # continue callback
                    return True

                print(__name__ + ".loop.quit()")
                loop.quit()
                # remove callback
                print(__name__ + ": remove callback")
                return False

        GLib.timeout_add_seconds(10, get_tm_active_count)
        loop.run()
示例#26
0
def main_loop():
    loop = GLib.MainLoop()
    timeout = GLib.Timeout(RUN_TIMEOUT)
    timeout.set_callback(lambda loop: loop.quit(), loop)
    timeout.attach()
    return loop
示例#27
0
    #######################################################################
    # Init logging as early as possible so we can log startup code
    # enable_color = not os.environ.get(
    #     'PITIVI_DEBUG_NO_COLOR', '0') in ('', '1')
    # # Let's show a human-readable Pitivi debug output by default, and only
    # # show a crazy unreadable mess when surrounded by gst debug statements.
    # enable_crack_output = "GST_DEBUG" in os.environ
    # loggable.init('PITIVI_DEBUG', enable_color, enable_crack_output)
    #
    # self.info('starting up')
    #######################################################################
    # Pitivi logging setup - END
    #######################################################################

    #######################################################################
    loop = GLib.MainLoop()
    _INSTANCE = st = ScarlettTasker()
    # NOTE: OLD WAY OF DOING THINGS
    # st.prepare(player_cb, command_cb, connected_to_listener_cb)
    st.prepare(on_signal_recieved, on_signal_recieved, on_signal_recieved)
    st.configure()
    #######################################################################

    if os.environ.get("TRAVIS_CI"):
        # Close application silently
        try:
            loop.run()
        except KeyboardInterrupt:
            logger.warning("***********************************************")
            logger.warning(
                'Note: Added an exception "pass" for KeyboardInterrupt')
示例#28
0
 def notify_observers(self, info):
     for obs in self._observers:
         event = threading.Event()
         GLib.idle_add(obs.update, event, info)
示例#29
0
 def setup_method(self, method):
     """Set up called automatically before every test_XXXX method."""
     super(IntegrationTestbaseMainloop, self).setup_method(method)
     self.mainloop = GLib.MainLoop()
     self.quit_count = 0
示例#30
0
 def run_mainloop(self, timeout=5):
     """Start the MainLoop, set Quit-Counter to Zero"""
     self.quit_count = 0
     GLib.timeout_add_seconds(timeout, self.quit_mainloop)
     self.mainloop.run()