def on_spawn_update_entity(self, widget, path=None): """ Spawns a thread that updates a single entity in the claimtable """ logging.debug("\t-> ClaimTableView.on_spawn_update_entity()") treemodel = self.treeview.get_model() if not path: path = treemodel.get_iter(self.click_path[0]) # Set update colour on row, set tab label to include 'Updating' self.claimtable.set(path, self.claimtable.get_n_columns() - 1, self.options.get("Settings", "update-colour")) o_tab_text = self.retrieve_tab_text() self.set_tab_text(o_tab_text + " (Updating)") queue = Queue.Queue() threading.Thread(target=self.update_entity_thread, \ args=(queue, path, self.options.get("Settings", "province"))).start() while True: gobject.main_context_default().iteration(False) try: if queue.get(block=False) == "ERROR": # Set error colour on row self.claimtable.set(path, self.claimtable.get_n_columns()-1, \ self.options.get("Settings", "error-colour")) break except Queue.Empty: pass else: # Clear colour on row self.claimtable.set(path, self.claimtable.get_n_columns() - 1, "#000000") break self.set_tab_text(o_tab_text)
def test(): def counter(max): for i in range(max): yield i def shower(queue): # Never stop reading the queue: while True: try: cnt = queue.get() print 'cnt =', cnt except QueueEmpty: pass yield None print 'Test 1: (should print range 0..22)' queue = Queue() c = GIdleThread(counter(23), queue) s = GIdleThread(shower(queue)) main = gobject.main_context_default() c.start() s.start() s.wait(2) print 'Test 2: (should only print 22)' queue = Queue(size=1) c = GIdleThread(counter(23), queue) s = GIdleThread(shower(queue)) main = gobject.main_context_default() c.start(priority=gobject.PRIORITY_DEFAULT) s.start() s.wait(3)
def run_server(): """Run the top-level loop. Returns when this process is no longer exporting any object references. """ while (plash_core.cap_server_exporting() or _reasons_count > 0 or event_loop.is_listening()): gobject.main_context_default().iteration()
def glib_poll_fds(fd_flags): # Emulates poll() (when called with a zero timeout) using a # one-off call to glib's main loop. watch_ids = [] ready_fds = [] revoked = False for fd, flags_requested in fd_flags.iteritems(): def handler(fd_unused, flags_got, fd=fd): assert not revoked ready_fds.append((fd, flags_got)) # Keep handler: it gets removed soon after return True # The ERROR_FLAGS are optional with glib even though they are # not optional with poll(). That means naive use of glib # could result in busy waits if you ignore error conditions on # FDs. watch_id = gobject.io_add_watch( fd, flags_requested | plash.comms.event_loop.ERROR_FLAGS, handler) watch_ids.append(watch_id) may_block = False gobject.main_context_default().iteration(may_block) revoked = True for watch_id in watch_ids: gobject.source_remove(watch_id) return ready_fds
def test_command_output(self): term = terminal.TerminalWidget(make_template()) term._current_reader("echo hello\n") while term._shell.job_controller._awaiting_job is not None: gobject.main_context_default().iteration(False) screen = "".join(get_vte_text(term.get_terminal_widget())).rstrip("\n") self.assertEquals(screen, "$ echo hello\nhello\n$ ")
def test_reading_pending_data(self): term = terminal.TerminalWidget(make_template()) term._terminal.set_size(100, 100) data = "".join(itertools.islice((char for i in itertools.count() for char in str(i)), 3000)) term._process_input("echo %s\n" % data) while term._shell.job_controller._awaiting_job is not None: gobject.main_context_default().iteration(False) screen = "".join(get_vte_text(term.get_terminal_widget())).rstrip("\n") self.assertEquals(screen, "$ " + data + "\n$ ")
def __cz_link_button_cb (self, widget): cmd = ["gnome-open", self.link_url] run = subprocess.Popen(cmd) returncode = None while(returncode is None): gobject.main_context_default ().iteration () returncode = run.poll() widget.set_property("has-focus", False)
def watch_screen(term, expected, timeout=10): # VTE updates the terminal in the event loop after a # non-configurable timeout, so we have to work around that. start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) gobject.main_context_default().iteration(False) vte_text = term.get_terminal_widget().get_text(lambda *args: True) screen = "".join(vte_text).rstrip("\n") if screen == expected: break return screen
def media_change(self, medium, drive): """Callback for media changes""" #FIXME: make use of DeviceKit/hal self.transaction.required_medium = medium, drive self.transaction.paused = True self.transaction.status = enums.STATUS_WAITING_MEDIUM while self.transaction.paused: gobject.main_context_default().iteration() self.transaction.status = enums.STATUS_DOWNLOADING if self.transaction.cancelled: return False return True
def test_freeing_last_reference(self): sock_pair = socket.socketpair() # Junk data should not be read because the connection is # closed down first. sock_pair[1].send("junk data") sock_pair[1].close() plash_core.cap_make_connection.make_conn2( plash_core.wrap_fd(sock_pair[0].fileno()), 1, []) # "may_block=False" argument to iteration() method not supported. # Adding an idle callback is a workaround. def idle_callback(): return False # remove callback gobject.idle_add(idle_callback) gobject.main_context_default().iteration()
def run(self): display = self.get_screen().get_display() cursor = gtk.gdk.Cursor(display, gtk.gdk.CROSSHAIR) main_context = gobject.main_context_default() if (gtk.gdk.pointer_grab(self.window, False, gtk.gdk.BUTTON_RELEASE_MASK, None, cursor) == gtk.gdk.GRAB_SUCCESS): self.query_clicked = False self.connect("button-release-event", self.button_release_event_cb) # Process events until clicked is set by button_release_event_cb. # We pass in may_block=True since we want to wait if there # are no events currently. # while self.query_clicked is False: main_context.iteration(True) toplevel = find_toplevel_at_pointer(display) if (toplevel == self): toplevel = None; self.destroy() gtk.gdk.flush() # Really release the grab return toplevel
def wait_for_blocker(blocker): """Run a recursive mainloop until blocker is triggered. @param blocker: event to wait on @type blocker: L{Blocker} @since: 0.53 """ assert wait_for_blocker.loop is None # Avoid recursion if not blocker.happened: def quitter(): yield blocker wait_for_blocker.loop.quit() Task(quitter(), "quitter") wait_for_blocker.loop = gobject.MainLoop( gobject.main_context_default()) try: debug(_("Entering mainloop, waiting for %s"), blocker) wait_for_blocker.loop.run() finally: wait_for_blocker.loop = None assert blocker.happened, "Someone quit the main loop!" check(blocker)
def loop(self): self.server.start() self.log.info('Adding io watch') display_tag = gobject.io_add_watch( self.conn.conn.get_file_descriptor(), gobject.IO_IN, self._xpoll ) try: context = gobject.main_context_default() while True: if context.iteration(True): try: # this seems to be crucial part self.conn.flush() # Catch some bad X exceptions. Since X is event based, race # conditions can occur almost anywhere in the code. For # example, if a window is created and then immediately # destroyed (before the event handler is evoked), when the # event handler tries to examine the window properties, it # will throw a BadWindow exception. We can essentially # ignore it, since the window is already dead and we've got # another event in the queue notifying us to clean it up. except (BadWindow, BadAccess, BadDrawable): pass if self._exit: self.log.info('Got shutdown, Breaking main loop cleanly') break finally: self.log.info('Removing source') gobject.source_remove(display_tag)
def run(self): display = self.get_screen().get_display() cursor = gtk.gdk.Cursor(display, gtk.gdk.CROSSHAIR) main_context = gobject.main_context_default() if (gtk.gdk.pointer_grab(self.window, False, gtk.gdk.BUTTON_RELEASE_MASK, None, cursor) == gtk.gdk.GRAB_SUCCESS): self.query_clicked = False self.connect("button-release-event", self.button_release_event_cb) # Process events until clicked is set by button_release_event_cb. # We pass in may_block=True since we want to wait if there # are no events currently. # while self.query_clicked is False: main_context.iteration(True) toplevel = find_toplevel_at_pointer(display) if (toplevel == self): toplevel = None self.destroy() gtk.gdk.flush() # Really release the grab return toplevel
def loop(self): self.server.start() self.log.info('Adding io watch') display_tag = gobject.io_add_watch( self.conn.conn.get_file_descriptor(), gobject.IO_IN, self._xpoll) try: context = gobject.main_context_default() while True: if context.iteration(True): try: # this seems to be crucial part self.conn.flush() # Catch some bad X exceptions. Since X is event based, race # conditions can occur almost anywhere in the code. For # example, if a window is created and then immediately # destroyed (before the event handler is evoked), when the # event handler tries to examine the window properties, it # will throw a BadWindow exception. We can essentially # ignore it, since the window is already dead and we've got # another event in the queue notifying us to clean it up. except (BadWindow, BadAccess, BadDrawable): pass if self._exit: self.log.info('Got shutdown, Breaking main loop cleanly') break finally: self.log.info('Removing source') gobject.source_remove(display_tag)
def run(self): global mouse_clicked global pointer_position self.display = self.get_display() cursor = gtk.gdk.Cursor(self.display, gtk.gdk.CROSSHAIR) main_context = gobject.main_context_default() self.mouse_clicked = False self.pointer_position = {} if (gdk.pointer_grab(self.window, True, gdk.BUTTON_RELEASE_MASK, None, self.cursors['search'], 0L) == gtk.gdk.GRAB_SUCCESS): self.connect("button_release_event", self.button_release_event_cb) self.grabbed = True # Process events until clicked is set by button_release_event_cb. # We pass in may_block=True since we want to wait if there # are no events currently. # while self.mouse_clicked is False: gtk.main_iteration(False) #main_context.iteration(True) self.destroy() gtk.gdk.flush() # Really release the grab toplevel = self.find_window_at_position(self.pointer_position) if (toplevel == self): toplevel = None; return toplevel
def get_vte_text(vte_terminal): # VTE updates the terminal in the event loop after a # non-configurable timeout, so we have to work around that. time.sleep(0.05) while gobject.main_context_default().iteration(False): pass return vte_terminal.get_text(lambda *args: True)
def run(self): #self.server.start() display_tag = gobject.io_add_watch(orion.conn.conn.get_file_descriptor(), gobject.IO_IN, orion.conn.xpoll) try: context = gobject.main_context_default() while True: if context.iteration(True): try: # this seems to be crucial part orion.conn.flush() # Catch some bad X exceptions. Since X is event based, race # conditions can occur almost anywhere in the code. For # example, if a window is created and then immediately # destroyed (before the event handler is evoked), when the # event handler tries to examine the window properties, it # will throw a BadWindow exception. We can essentially # ignore it, since the window is already dead and we've got # another event in the queue notifying us to clean it up. except (xcb.xproto.BadWindow, xcb.xproto.BadAccess): # TODO: add some logging for this? pass if self._exit: break finally: gobject.source_remove(display_tag)
def _conffile(self, current, new): """Callback for a config file conflict""" log.warning("Config file prompt: '%s' (%s)" % (current, new)) self.transaction.config_file_conflict = (current, new) self.transaction.paused = True self.transaction.status = enums.STATUS_WAITING_CONFIG_FILE_PROMPT while self.transaction.paused: gobject.main_context_default().iteration() log.debug("Sending config file answer: %s", self.transaction.config_file_conflict_resolution) if self.transaction.config_file_conflict_resolution == "replace": os.write(self.master_fd, "y\n") elif self.transaction.config_file_conflict_resolution == "keep": os.write(self.master_fd, "n\n") self.transaction.config_file_conflict_resolution = None self.transaction.config_file_conflict = None self.transaction.status = enums.STATUS_COMMITTING return True
def test_get_io_err_when_no_reader(self): """Check that we get IO_ERR when polling a pipe FD with no reader.""" pipe_read, pipe_write = os.pipe() os.close(pipe_read) try: calls = [] def callback(*args): calls.append(args) return False gobject.io_add_watch(pipe_write, gobject.IO_OUT | gobject.IO_ERR | gobject.IO_HUP, callback) gobject.main_context_default().iteration() self.assertEquals(calls, [(pipe_write, gobject.IO_OUT | gobject.IO_ERR)]) finally: os.close(pipe_write)
def test_not_reentering_glib_watches(self): # glib will not re-enter a glib watch while it is active. If # we run an iteration of the main loop from inside a handler, # the handler will not be called again. We do not rely on # this behaviour; in fact, we work around it. got = [] def handler(fd_unused, flags): got.append(flags) may_block = False gobject.main_context_default().iteration(may_block) return False pipe_read, pipe_write = plash.comms.stream.make_pipe() gobject.io_add_watch(pipe_read, select.POLLIN, handler) os.write(pipe_write.fileno(), "hello") may_block = False gobject.main_context_default().iteration(may_block) self.assertEquals(len(got), 1)
def __at_async_handler(self, fd, condition, at_command, get_info_from_raw, func): print "__at_async_handler in" tt_res = [at_command] while True : res = self.serial.readline() gobject.main_context_default ().iteration () if len(res.strip("\r\n")) > 0: tt_res.append(res.strip("\r\n")) if res.startswith("OK") or res.startswith("ERROR") or res.startswith("+CME ERROR"): break result = [tt_res[0],tt_res[1:-1],tt_res[-1]] func(get_info_from_raw(result)) print "__at_async_handler out" self.pause_polling_necesary = False return False
def on_report(self, element, message): log.info('%s: %s' % (type(element).__name__, message)) model = self.model iter = model.append() model.set_value(iter, PYELEMENT_COLUMN, element) model.set_value(iter, ELEMENT_COLUMN, type(element).__name__) model.set_value(iter, REASON_COLUMN, message) main = gobject.main_context_default() main.iteration(False)
def update_rss(self): tmpfile = "/tmp/rss-%i.xml" % int(time.time()) if os.path.exists("/usr/bin/wget"): cmd = ["wget", self.url, "-O", tmpfile, "-t", "1", "--timeout=10"] elif os.path.exists("/usr/bin/curl"): cmd = ["curl", "-o", tmpfile, self.url, "-m", "10"] else: return False returncode = None run = subprocess.Popen(cmd) self.downloader_pid = run.pid while returncode is None: gobject.main_context_default().iteration() returncode = run.poll() if returncode != 0: self.downloader_pid = None self.read_cache = self.__load_cache() return False self.downloader_pid = None actualizado = False if os.path.exists(self.rss_file): d1 = feedparser.parse(self.rss_file) d2 = feedparser.parse(tmpfile) if d2.feed.updated_parsed <= d1.feed.updated_parsed: self.feed = d1 actualizado = False else: subprocess.Popen(["mv", tmpfile, self.rss_file]) self.feed = d2 actualizado = True else: subprocess.Popen(["mv", tmpfile, self.rss_file]) self.feed = feedparser.parse(tmpfile) actualizado = True self.read_cache = self.__load_cache() return actualizado
def pulse(self, owner): """Callback to update progress information""" if self.transaction.cancelled: return False self.transaction.progress_details = (self.current_items, self.total_items, self.current_bytes, self.total_bytes, self.current_cps, self.elapsed_time) percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) progress = int(self.progress_begin + percent/100 * \ (self.progress_end - self.progress_begin)) # If the progress runs backwards emit an illegal progress value # e.g. during cache updates. if self.progress > progress: self.transaction.progress = 101 else: self.transaction.progress = progress self.progress = progress # Show all currently downloaded files items = set() for worker in owner.workers: if not worker.current_item: continue self._emit_acquire_item(worker.current_item, worker.total_size, worker.current_size) if worker.current_item.owner.id: items.add(worker.current_item.owner.id) else: items.add(worker.current_item.shortdesc) if items: #TRANSLATORS: %s is a list of package names msg = self.transaction.ngettext("Downloading %(files)s", "Downloading %(files)s", len(items)) % {"files": " ".join(items)} self.transaction.status_details = msg while gobject.main_context_default().pending(): gobject.main_context_default().iteration() return True
def interactive_main(): history = History() shell = Shell({"history": history}) fds = {FILENO_STDIN: sys.stdin, FILENO_STDOUT: sys.stdout, FILENO_STDERR: sys.stderr} signal.signal(signal.SIGINT, signal.SIG_IGN) try: import shell_pyrepl reader = shell_pyrepl.make_reader(shell.get_prompt, shell.completer, shell.cwd) reader.history = [command for command, time, cwd in history] print "using pyrepl" except ImportError: reader = ReadlineReader(shell.get_prompt, shell.completer) for command, time, cwd in history: reader.add_history(command) print "using readline (pyrepl not available)" should_run = [True] def read_input(): shell.job_controller.shell_to_foreground() shell.job_controller.print_messages() if os.environ.get("TERM") == "xterm": sys.stdout.write("\x1b]2;%s\x07" % shell.get_title()) sys.stdout.flush() reader.readline(process_input) def process_input(line): if line is None: sys.stdout.write("\n") should_run[0] = False else: try: shell.run_command(line, fds) except Exception: traceback.print_exc() shell.job_controller.check_for_done() shell.job_controller.add_done_handler(read_input) read_input() while should_run[0]: gobject.main_context_default().iteration()
def wait_for_lock(trans, alt_lock=None): """Acquire the system lock or the optionally given one. If the lock cannot be obtained pause the transaction in the meantime. :param trans: the transaction :param lock: optional alternative lock """ def watch_lock(): """Helper to unpause the transaction if the lock can be obtained. Keyword arguments: trans -- the corresponding transaction alt_lock -- alternative lock to the system lock """ try: if alt_lock: alt_lock.acquire() else: acquire() except LockFailedError: return True trans.paused = False return True try: if alt_lock: alt_lock.acquire() else: acquire() except LockFailedError, error: trans.paused = True trans.status = enums.STATUS_WAITING_LOCK if error.process: #TRANSLATORS: %s is the name of a package manager msg = trans.gettext("Waiting for %s to exit") trans.status_details = msg % error.process lock_watch = gobject.timeout_add_seconds(3, watch_lock) while trans.paused and not trans.cancelled: gobject.main_context_default().iteration() gobject.source_remove(lock_watch) if trans.cancelled: raise TransactionCancelled()
def wait(self, timeout=0): """Wait until the corouine is finished or return after timeout seconds. This is achieved by running the GTK+ main loop. """ clock = time.clock start_time = clock() main = gobject.main_context_default() while self.is_alive(): main.iteration(False) if timeout and (clock() - start_time >= timeout): return
def _init(): global _step, _mainloop if _options[ 'x11' ]: import gtk _step = gtk.main_iteration_do else: _mainloop = gobject.main_context_default() _step = _mainloop.iteration gobject.threads_init()
def _init(): global _step, _mainloop if _options['x11']: import gtk _step = gtk.main_iteration_do else: _mainloop = gobject.main_context_default() _step = _mainloop.iteration gobject.threads_init()
def pixbuf_cb (buf): data = [buf] status = [] def write_coro (w_plexer): while data: buf = data.pop () handle.write (buf, w_plexer.send ()) yield None _, (_, requested, result, written) = w_plexer.receive () if result: print "Error writing \"%s\": %s" % (uri, result) status.insert (0, False) return if written < requested: data.insert (0, buf[written:]) status.insert (0, True) rb.Coroutine (write_coro).begin () while not status: gobject.main_context_default ().iteration () return status[0]
def run(self): '''Start processing the transaction''' # avoid blocking the user interface context = gobject.main_context_default() while context.pending(): context.iteration() polkit_auth_wrapper(self._method, *self._args) if not self._exit_handler: self._main_loop.run() if self._error_code: raise PackageKitError(self._error_code, self._error_details) return self.result
def run(self, url, directory, fn, message=None): if self.url: return _("Download already in progress") self.url = url self.directory = directory self.fn = fn self.done = False self.err = None self.bytes_read = -1 self.content_length = 0 self.cancelled = False thread.start_new_thread(self.thread_func, ()) timeout_id = gobject.timeout_add(500, self.update_progress) self.update_progress() # Don't try to be smart and block here using mayblock=True, it won't work while not self.done: gobject.main_context_default().iteration(False) gobject.source_remove(timeout_id) # Update to 'finished' state self.update_progress() while gobject.main_context_default().pending(): gobject.main_context_default().iteration(False) # Reset state self.url = None self.directory = None self.fn = None self.done = False self.bytes_read = -1 self.content_length = 0 return self.err
def test_setsid_helper(self): got = [] def callback(pid, status): got.append((pid, status)) spec1 = {"args": ["sh", "-c", "exit 42"], "fds": {0: sys.stdin, 1: sys.stdout, 2: sys.stderr}} spec2 = {"args": ["sh", "-c", "exit 24"], "fds": {0: sys.stdin, 1: sys.stdout, 2: sys.stderr}} master_fd, slave_fd = terminal.openpty() helper_pid, pids = setsid_helper.run([spec1, spec2], slave_fd, callback) self.assertEquals(len(pids), 2) gobject.main_context_default().iteration(True) gobject.main_context_default().iteration(True) gobject.main_context_default().iteration(True) statuses = dict(got) self.assertEquals(set(statuses.keys()), set(pids)) assert os.WIFEXITED(statuses[pids[0]]) assert os.WIFEXITED(statuses[pids[1]]) self.assertEquals(os.WEXITSTATUS(statuses[pids[0]]), 42) self.assertEquals(os.WEXITSTATUS(statuses[pids[1]]), 24) # Helper process should exit OK. pid2, status = os.waitpid(helper_pid, 0) assert os.WIFEXITED(status) self.assertEquals(os.WEXITSTATUS(status), 0)
def wait(self, timeout=0): """ @summary: Wait until the coroutine is finished or return after timeout seconds. This is achieved by running the GTK+ main loop. @param timeout: Timeout to execute the function. """ clock = time.clock start_time = clock() while self.isAlive(): main = gobject.main_context_default() main.iteration(False) if timeout and (clock() - start_time >= timeout): return False return True
def __init__(self, useGtk=True): self.context = gobject.main_context_default() self.loop = gobject.MainLoop() posixbase.PosixReactorBase.__init__(self) if (hasattr(gobject, "pygtk_version") and gobject.pygtk_version >= (2, 3, 91) and not useGtk): self.__pending = self.context.pending self.__iteration = self.context.iteration self.__crash = self.loop.quit self.__run = self.loop.run else: import gtk self.__pending = gtk.events_pending self.__iteration = gtk.main_iteration self.__crash = _our_mainquit self.__run = gtk.main
def __init__(self, useGtk=True): self.context = gobject.main_context_default() self.loop = gobject.MainLoop() posixbase.PosixReactorBase.__init__(self) # pre 2.3.91 the glib iteration and mainloop functions didn't release # global interpreter lock, thus breaking thread and signal support. if (hasattr(gobject, "pygtk_version") and gobject.pygtk_version >= (2, 3, 91) and not useGtk): self.__pending = self.context.pending self.__iteration = self.context.iteration self.__crash = self.loop.quit self.__run = self.loop.run else: import gtk self.__pending = gtk.events_pending self.__iteration = gtk.main_iteration self.__crash = _our_mainquit self.__run = gtk.main
def wait_for_blocker(self, blocker): """Run a recursive mainloop until blocker is triggered. @param blocker: event to wait on @type blocker: L{tasks.Blocker}""" if not blocker.happened: import gobject def quitter(): yield blocker self._loop.quit() quit = tasks.Task(quitter(), "quitter") assert self._loop is None # Avoid recursion self._loop = gobject.MainLoop(gobject.main_context_default()) try: debug(_("Entering mainloop, waiting for %s"), blocker) self._loop.run() finally: self._loop = None assert blocker.happened, "Someone quit the main loop!" tasks.check(blocker)
def shower(queue): # Never stop reading the queue: while True: try: cnt = queue.get() print 'cnt =', cnt except QueueEmpty: pass yield None print 'Test 1: (should print range 0..22)' queue = Queue() c = GIdleThread(counter(23), queue) s = GIdleThread(shower(queue)) main = gobject.main_context_default() c.start() s.start() s.wait(2) print 'Test 2: (should only print 22)' queue = Queue(size=1) c = GIdleThread(counter(23), queue) s = GIdleThread(shower(queue)) main = gobject.main_context_default() c.start(priority=gobject.PRIORITY_DEFAULT) s.start() s.wait(3)