[Reportbug-commits] [reportbug] 16/31: gtk2_ui: Create a GLib main-context for each thread
Sandro Tosi
morph at moszumanska.debian.org
Mon Jan 16 01:36:57 UTC 2017
This is an automated email from the git hooks/post-receive script.
morph pushed a commit to branch master
in repository reportbug.
commit beb28cba873899a030d00be4ca25ffca59862370
Author: Simon McVittie <smcv at debian.org>
Date: Sat Jan 14 18:32:11 2017 +0000
gtk2_ui: Create a GLib main-context for each thread
A main context represents a set of callbacks, sockets and other
event sources, and each main-context can be acquired (owned) by at
most one thread at a time. A main-context is normally owned by the
same thread for its entire lifetime, and that's how we use them here.
The "thread-default main context" is how GLib and GIO track the thread
in which the callback for an async operation should be called; we don't
actually use any GIO async operations at the moment, but it's a good
idea to set it correctly. This also gives us the ability to give better
diagnostics than just asserting is_owner(), because we can show both
the expected thread and the actual thread in the assertion message.
---
reportbug/ui/gtk2_ui.py | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/reportbug/ui/gtk2_ui.py b/reportbug/ui/gtk2_ui.py
index 0d3f14e..87a8d79 100644
--- a/reportbug/ui/gtk2_ui.py
+++ b/reportbug/ui/gtk2_ui.py
@@ -71,7 +71,7 @@ from reportbug.urlutils import launch_browser
ISATTY = True
DEBIAN_LOGO = "/usr/share/pixmaps/debian-logo.png"
-global application, assistant, report_message
+global application, assistant, report_message, reportbug_context, ui_context
# Utilities
@@ -347,6 +347,7 @@ class BugPage(Gtk.EventBox, threading.Thread):
threading.Thread.__init__(self)
Gtk.EventBox.__init__(self)
self.setDaemon(True)
+ self.context = GLib.MainContext()
self.dialog = dialog
self.assistant = assistant
@@ -371,6 +372,11 @@ class BugPage(Gtk.EventBox, threading.Thread):
self.add(vbox)
def run(self):
+ if not self.context.acquire():
+ # should be impossible
+ raise AssertionError('Could not acquire my own main-context')
+ self.context.push_thread_default()
+
# Start the progress bar
GLib.timeout_add(10, self.pulse)
@@ -474,6 +480,7 @@ class BugsDialog(Gtk.Dialog):
# Application
class ReportbugApplication(threading.Thread):
def __init__(self):
+ _assert_context(reportbug_context)
threading.Thread.__init__(self)
self.setDaemon(True)
@@ -481,6 +488,11 @@ class ReportbugApplication(threading.Thread):
self.next_value = None
def run(self):
+ if not ui_context.acquire():
+ # should be impossible
+ raise AssertionError('Could not acquire UI context')
+ ui_context.push_thread_default()
+
Gdk.threads_enter()
Gtk.main()
Gdk.threads_leave()
@@ -1576,7 +1588,7 @@ def forward_operations(parent, operations):
def initialize():
- global application, assistant, Vte
+ global application, assistant, reportbug_context, ui_context, Vte
try:
gi.require_version('Vte', '2.91')
@@ -1595,6 +1607,18 @@ Falling back to 'text' interface."""
os.execlp('x-terminal-emulator', 'x-terminal-emulator', '-e', 'reportbug -u text')
return False
+ # The first thread of the process runs reportbug's UI-agnostic logic
+ reportbug_context = GLib.MainContext()
+ if not reportbug_context.acquire():
+ # should be impossible
+ raise AssertionError('Could not acquire new main-context')
+ reportbug_context.push_thread_default()
+
+ # A secondary thread (the ReportbugApplication) runs the GTK UI.
+ # This is the "default main context", used by GLib.idle_add() and similar
+ # non-thread-aware APIs.
+ ui_context = GLib.MainContext.default()
+
# Exception hook
oldhook = sys.excepthook
sys.excepthook = ExceptionDialog.create_excepthook(oldhook)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reportbug/reportbug.git
More information about the Reportbug-commits
mailing list