[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Plash] [DRAFT] [PATCH] plash.comms.event_loop: Add timeout argument to
From: |
James Ascroft-Leigh |
Subject: |
[Plash] [DRAFT] [PATCH] plash.comms.event_loop: Add timeout argument to once(); Workaround for Gtk global lock issues |
Date: |
Fri, 29 Feb 2008 18:15:13 +0000 |
There are two changes here:
1. Add a timeout argument to the once() method in
plash.comms.event_loop.EventLoop().
2. Add a workaround for the Gtk global lock to GlibEventLoop to drop the
lock when entering the event loop and reclaim the lock while entering
event handlers, as event handlers can expect to use Gtk and may re-enter
the event loop themselves when performing a synchronous call. This is
not the ideal solution because it is Gtk specific, while GlibEventLoop
only depended on Glib before (though Glib is wrapped by python-gtk
anyway).
Attached is a tool for testing whether a program is using the Gtk global
lock correctly.
--- plash/comms/event_loop.py 2008/02/07 12:06:51 1.1
+++ plash/comms/event_loop.py 2008/02/07 15:06:02 1.2
@@ -21,6 +21,7 @@
import sys
import gobject
+import gtk
class ExcepthookProxy(object):
@@ -129,21 +130,25 @@
# Always re-register the event handler otherwise glib will
# refuse to re-enter the handler if the callback should happen
# to start a nested event loop.
- self.register()
- relevant_flags = flags & self._flags
- if relevant_flags != 0:
- try:
- self._callback(relevant_flags)
- except:
- self._excepthook(*sys.exc_info())
+ gtk.gdk.threads_enter()
+ try:
+ self.register()
+ relevant_flags = flags & self._flags
+ if relevant_flags != 0:
+ try:
+ self._callback(relevant_flags)
+ except:
+ self._excepthook(*sys.exc_info())
+ self.remove_watch()
+ if flags & ERROR_FLAGS != 0:
+ try:
+ self._error_callback(flags & ERROR_FLAGS)
+ except:
+ self._excepthook(*sys.exc_info())
self.remove_watch()
- if flags & ERROR_FLAGS != 0:
- try:
- self._error_callback(flags & ERROR_FLAGS)
- except:
- self._excepthook(*sys.exc_info())
- self.remove_watch()
- return False # remove handler
+ return False # remove handler
+ finally:
+ gtk.gdk.threads_leave()
def remove_watch(self):
if not self.destroyed:
@@ -181,6 +186,9 @@
assert gobject.IO_HUP == select.POLLHUP
assert gobject.IO_NVAL == select.POLLNVAL
+NEVER_BLOCK_TIMEOUT = 0
+MAY_BLOCK_FOREVER = None
+
class EventLoopBase(object):
@@ -255,32 +263,28 @@
did_something = True
return did_something
- def _iteration(self, may_block):
+ def _iteration(self, timeout):
did_something = self._run_call_queue()
- if may_block:
- timeout = None
- else:
- timeout = 0
ready = dict(self._poll_fds(self._get_fd_flags(), timeout))
if len(ready) > 0:
self._process_ready(ready)
did_something = True
return did_something
- def once(self):
- self._iteration(may_block=True)
+ def once(self, timeout=MAY_BLOCK_FOREVER):
+ self._iteration(timeout)
def once_safely(self):
- did_something = self._iteration(may_block=False)
+ did_something = self._iteration(NEVER_BLOCK_TIMEOUT)
assert did_something, self._get_fd_flags()
def run(self):
while True:
- self._iteration(may_block=True)
+ self._iteration(MAY_BLOCK_FOREVER)
def run_awhile(self):
while True:
- did_something = self._iteration(may_block=False)
+ did_something = self._iteration(NEVER_BLOCK_TIMEOUT)
if not did_something:
break
@@ -324,8 +328,12 @@
self._excepthook.set(func)
def _iteration(self, may_block):
- did_something =
gobject.main_context_default().iteration(may_block)
- return did_something
+ gtk.gdk.threads_leave()
+ try:
+ did_something =
gobject.main_context_default().iteration(may_block)
+ return did_something
+ finally:
+ gtk.gdk.threads_enter()
def once(self):
self._iteration(may_block=True)
--
J. W. Ascroft-Leigh
Software Engineer
Cmed Technology Ltd.
Registered in England and Wales No. 3869835
Registered Office and Address for Communication:
Holmwood, Broadlands Business Campus,
Langhurstwood Road, Horsham, RH12 4QP, United Kingdom
T +44 (0)1403 755634
F +44 (0)1403 755051
E address@hidden
W www.cmedresearch.com
__________________________________________________________
Driven by technology. Guided by experience.
__________________________________________________________
gtk-lock.tar
Description: Unix tar archive
smime.p7s
Description: S/MIME cryptographic signature
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Plash] [DRAFT] [PATCH] plash.comms.event_loop: Add timeout argument to once(); Workaround for Gtk global lock issues,
James Ascroft-Leigh <=