Author: Maciej Fijalkowski <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit