Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r61330:36e9ac53a32b Date: 2013-02-16 21:46 +0100 http://bitbucket.org/pypy/pypy/changeset/36e9ac53a32b/
Log: merge diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() 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 @@ -32,8 +32,7 @@ p = pypysig_getaddr_occurred() p.c_value = value - @staticmethod - def rearm_ticker(): + def rearm_ticker(self): p = pypysig_getaddr_occurred() p.c_value = -1 @@ -71,7 +70,7 @@ if self.fire_in_another_thread: if self.space.threadlocals.signals_enabled(): self.fire_in_another_thread = False - SignalActionFlag.rearm_ticker() + self.space.actionflag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to # -1, which should ensure perform() is called quickly. diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,5 +1,9 @@ from rpython.rlib import rthread -from pypy.interpreter.error import OperationError +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -10,12 +14,10 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} - self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._signalsenabled.clear() self._mainthreadident = 0 self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -36,7 +38,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._signalsenabled[ident] = 1 # the main thread is enabled + value._signals_enabled = 1 # the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value else: @@ -44,33 +46,25 @@ del self._valuedict[ident] except KeyError: pass - try: - del self._signalsenabled[ident] - except KeyError: - pass # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value def signals_enabled(self): - return rthread.get_ident() in self._signalsenabled + ec = self.getvalue() + return ec._signals_enabled def enable_signals(self, space): - ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - self._signalsenabled[ident] = old + 1 + ec = self.getvalue() + ec._signals_enabled += 1 def disable_signals(self, space): - ident = rthread.get_ident() - try: - new = self._signalsenabled[ident] - 1 - except KeyError: - raise OperationError(space.w_KeyError, space.wrap( - "cannot disable signals in thread not enabled for signals")) - if new > 0: - self._signalsenabled[ident] = new - else: - del self._signalsenabled[ident] + ec = self.getvalue() + new = ec._signals_enabled - 1 + if new < 0: + raise wrap_thread_error(space, + "cannot disable signals in thread not enabled for signals") + ec._signals_enabled = new def getallvalues(self): return self._valuedict @@ -85,16 +79,10 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - # clear the _signalsenabled dictionary for all other threads - # (which are now dead); and for the current thread, force an - # enable_signals() if necessary. That's a hack but I cannot - # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() - val = self.getvalue() - sig = self._signalsenabled.get(ident, 0) + ec = self.getvalue() if ident != self._mainthreadident: - sig += 1 + ec._signals_enabled += 1 self._cleanup_() - self.setvalue(val) - self._signalsenabled[ident] = sig + self.setvalue(ec) self._mainthreadident = ident _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit