Commits

Maciej Fijalkowski committed 36e9ac5 Merge

merge

Comments (0)

Files changed (3)

pypy/interpreter/pycode.py

         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
 
     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
             # 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()
 

pypy/module/signal/interp_signal.py

         p = pypysig_getaddr_occurred()
         p.c_value = value
 
-    @staticmethod
-    def rearm_ticker():
+    def rearm_ticker(self):
         p = pypysig_getaddr_occurred()
         p.c_value = -1
 
         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.

pypy/module/thread/threadlocals.py

 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:
 
     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
         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:
                 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
 
     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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.