[pypy-commit] pypy default: merge heads
bdkearns
noreply at buildbot.pypy.org
Mon Jan 28 09:54:15 CET 2013
Author: Brian Kearns <bdkearns at gmail.com>
Branch:
Changeset: r60588:d1767635d7c4
Date: 2013-01-28 03:54 -0500
http://bitbucket.org/pypy/pypy/changeset/d1767635d7c4/
Log: merge heads
diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -19,7 +19,8 @@
class SignalActionFlag(AbstractActionFlag):
# This class uses the C-level pypysig_counter variable as the tick
# counter. The C-level signal handler will reset it to -1 whenever
- # a signal is received.
+ # a signal is received. This causes CheckSignalAction.perform() to
+ # be called.
def get_ticker(self):
p = pypysig_getaddr_occurred()
@@ -47,45 +48,40 @@
def __init__(self, space):
AsyncAction.__init__(self, space)
self.handlers_w = {}
- if space.config.objspace.usemodules.thread:
- # need a helper action in case signals arrive in a non-main thread
- self.pending_signals = {}
- self.reissue_signal_action = ReissueSignalAction(space)
- else:
- self.reissue_signal_action = None
+ self.emulated_sigint = False
@jit.dont_look_inside
def perform(self, executioncontext, frame):
- while True:
- n = pypysig_poll()
- if n < 0:
- break
- self.perform_signal(executioncontext, n)
-
- @jit.dont_look_inside
- def perform_signal(self, executioncontext, n):
- if self.reissue_signal_action is None:
- # no threads: we can report the signal immediately
- self.report_signal(n)
+ if self.space.config.objspace.usemodules.thread:
+ main_ec = self.space.threadlocals.getmainthreadvalue()
+ in_main = executioncontext is main_ec
else:
- main_ec = self.space.threadlocals.getmainthreadvalue()
- if executioncontext is main_ec:
- # running in the main thread: we can report the
- # signal immediately
- self.report_signal(n)
- else:
- # running in another thread: we need to hack a bit
- self.pending_signals[n] = None
- self.reissue_signal_action.fire_after_thread_switch()
+ in_main = True
+ # If we are in the main thread, poll and report the signals now.
+ if in_main:
+ if self.emulated_sigint:
+ self.emulated_sigint = False
+ self._report_signal(cpy_signal.SIGINT)
+ while True:
+ n = pypysig_poll()
+ if n < 0:
+ break
+ self._report_signal(n)
+ else:
+ # Otherwise, don't call pypysig_poll() at all. Instead,
+ # arrange for perform() to be called again after a thread
+ # switch. It might be called again and again, until we
+ # land in the main thread.
+ self.fire_after_thread_switch()
@jit.dont_look_inside
def set_interrupt(self):
"Simulates the effect of a SIGINT signal arriving"
ec = self.space.getexecutioncontext()
- self.perform_signal(ec, cpy_signal.SIGINT)
+ self.emulated_sigint = True
+ self.perform(ec, None)
- @jit.dont_look_inside
- def report_signal(self, n):
+ def _report_signal(self, n):
try:
w_handler = self.handlers_w[n]
except KeyError:
@@ -100,39 +96,6 @@
w_frame = space.wrap(ec.gettopframe_nohidden())
space.call_function(w_handler, space.wrap(n), w_frame)
- @jit.dont_look_inside
- def report_pending_signals(self):
- # XXX this logic isn't so complicated but I have no clue how
- # to test it :-(
- pending_signals = self.pending_signals.keys()
- self.pending_signals.clear()
- try:
- while pending_signals:
- self.report_signal(pending_signals.pop())
- finally:
- # in case of exception, put the undelivered signals back
- # into the dict instead of silently swallowing them
- if pending_signals:
- for n in pending_signals:
- self.pending_signals[n] = None
- self.reissue_signal_action.fire()
-
-
-class ReissueSignalAction(AsyncAction):
- """A special action to help deliver signals to the main thread. If
- a non-main thread caught a signal, this action fires after every
- thread switch until we land in the main thread.
- """
-
- def perform(self, executioncontext, frame):
- main_ec = self.space.threadlocals.getmainthreadvalue()
- if executioncontext is main_ec:
- # now running in the main thread: we can really report the signals
- self.space.check_signal_action.report_pending_signals()
- else:
- # still running in some other thread: try again later
- self.fire_after_thread_switch()
-
@unwrap_spec(signum=int)
def getsignal(space, signum):
diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py
--- a/pypy/module/thread/os_local.py
+++ b/pypy/module/thread/os_local.py
@@ -98,5 +98,5 @@
local = wref()
if local is not None:
del local.dicts[ec]
- local.last_dict = None
- local.last_ec = None
+ local.last_dict = None
+ local.last_ec = None
More information about the pypy-commit
mailing list