Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3k
Changeset: r60629:fcaa58ce7548
Date: 2013-01-28 19:59 +0100
http://bitbucket.org/pypy/pypy/changeset/fcaa58ce7548/
Log: hg merge default
diff --git a/pypy/interpreter/executioncontext.py
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -343,9 +343,13 @@
signal, the tick counter is set to -1 by C code in signals.h.
"""
assert isinstance(action, PeriodicAsyncAction)
- self._periodic_actions.append(action)
+ # hack to put the release-the-GIL one at the end of the list,
+ # and the report-the-signals one at the start of the list.
if use_bytecode_counter:
+ self._periodic_actions.append(action)
self.has_bytecode_counter = True
+ else:
+ self._periodic_actions.insert(0, action)
self._rebuild_action_dispatcher()
def getcheckinterval(self):
@@ -419,15 +423,6 @@
The action must have been registered at space initalization time."""
self.space.actionflag.fire(self)
- def fire_after_thread_switch(self):
- """Bit of a hack: fire() the action but only the next time the GIL
- is released and re-acquired (i.e. after a potential thread switch).
- Don't call this if threads are not enabled. Currently limited to
- one action (i.e. reserved for CheckSignalAction from module/signal).
- """
- from pypy.module.thread.gil import spacestate
- spacestate.action_after_thread_switch = self
-
def perform(self, executioncontext, frame):
"""To be overridden."""
diff --git a/pypy/module/rctime/test/test_rctime.py
b/pypy/module/rctime/test/test_rctime.py
--- a/pypy/module/rctime/test/test_rctime.py
+++ b/pypy/module/rctime/test/test_rctime.py
@@ -114,7 +114,10 @@
assert rctime.mktime(rctime.localtime(-1)) == -1
res = rctime.mktime((2000, 1, 1, 0, 0, 0, -1, -1, -1))
- assert rctime.ctime(res) == 'Sat Jan 1 00:00:00 2000'
+ if os.name == 'nt':
+ assert rctime.ctime(res) == 'Sat Jan 01 00:00:00 2000'
+ else:
+ assert rctime.ctime(res) == 'Sat Jan 1 00:00:00 2000'
def test_asctime(self):
import time as rctime
diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py
--- a/pypy/module/signal/__init__.py
+++ b/pypy/module/signal/__init__.py
@@ -30,9 +30,10 @@
}
def buildloaders(cls):
- from pypy.module.signal import interp_signal
- for name in interp_signal.signal_names:
- signum = getattr(interp_signal, name)
+ from rpython.rlib import rsignal
+
+ for name in rsignal.signal_names:
+ signum = getattr(rsignal, name)
if signum is not None:
Module.interpleveldefs[name] = 'space.wrap(%d)' % (signum,)
super(Module, cls).buildloaders()
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
@@ -1,25 +1,28 @@
from __future__ import with_statement
+
+import signal as cpy_signal
+import sys
+
from pypy.interpreter.error import OperationError, exception_from_errno
-from pypy.interpreter.executioncontext import AsyncAction, AbstractActionFlag
-from pypy.interpreter.executioncontext import PeriodicAsyncAction
+from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag,
+ PeriodicAsyncAction)
from pypy.interpreter.gateway import unwrap_spec
-import signal as cpy_signal
-from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rtyper.tool import rffi_platform
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.conftest import cdir
-import py
-import sys
-from rpython.rlib import jit, rposix
+
+from rpython.rlib import jit, rposix, rgc
+from rpython.rlib.objectmodel import we_are_translated
from rpython.rlib.rarithmetic import intmask
from rpython.rlib.rsignal import *
+from rpython.rtyper.lltypesystem import lltype, rffi
+
WIN32 = sys.platform == 'win32'
+
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()
@@ -29,6 +32,11 @@
p = pypysig_getaddr_occurred()
p.c_value = value
+ @staticmethod
+ def rearm_ticker():
+ p = pypysig_getaddr_occurred()
+ p.c_value = -1
+
def decrement_ticker(self, by):
p = pypysig_getaddr_occurred()
value = p.c_value
@@ -44,48 +52,65 @@
class CheckSignalAction(PeriodicAsyncAction):
"""An action that is automatically invoked when a signal is received."""
+ # Note that this is a PeriodicAsyncAction: it means more precisely
+ # that it is called whenever the C-level ticker becomes < 0.
+ # Without threads, it is only ever set to -1 when we receive a
+ # signal. With threads, it also decrements steadily (but slowly).
+
def __init__(self, space):
+ "NOT_RPYTHON"
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.pending_signal = -1
+ self.fire_in_main_thread = False
+ if self.space.config.objspace.usemodules.thread:
+ from pypy.module.thread import gil
+ gil.after_thread_switch = self._after_thread_switch
+
+ @rgc.no_collect
+ def _after_thread_switch(self):
+ if self.fire_in_main_thread:
+ if self.space.threadlocals.ismainthread():
+ self.fire_in_main_thread = False
+ SignalActionFlag.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.
@jit.dont_look_inside
def perform(self, executioncontext, frame):
- while True:
- n = pypysig_poll()
- if n < 0:
+ # Poll for the next signal, if any
+ n = self.pending_signal
+ if n < 0: n = pypysig_poll()
+ while n >= 0:
+ if self.space.config.objspace.usemodules.thread:
+ in_main = self.space.threadlocals.ismainthread()
+ else:
+ in_main = True
+ if in_main:
+ # If we are in the main thread, report the signal now,
+ # and poll more
+ self.pending_signal = -1
+ self._report_signal(n)
+ n = self.pending_signal
+ if n < 0: n = pypysig_poll()
+ else:
+ # Otherwise, arrange for perform() to be called again
+ # after we switch to the main thread.
+ self.pending_signal = n
+ self.fire_in_main_thread = True
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)
- 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()
-
- @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)
+ if not we_are_translated():
+ self.pending_signal = cpy_signal.SIGINT
+ # ^^^ may override another signal, but it's just for testing
+ else:
+ pypysig_pushback(cpy_signal.SIGINT)
+ self.fire_in_main_thread = True
- @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 +125,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):
@@ -154,6 +146,7 @@
return action.handlers_w[signum]
return space.wrap(SIG_DFL)
+
def default_int_handler(space, w_signum, w_frame):
"""
default_int_handler(...)
@@ -164,22 +157,26 @@
raise OperationError(space.w_KeyboardInterrupt,
space.w_None)
+
@jit.dont_look_inside
@unwrap_spec(timeout=int)
def alarm(space, timeout):
return space.wrap(c_alarm(timeout))
+
@jit.dont_look_inside
def pause(space):
c_pause()
return space.w_None
+
def check_signum_exists(space, signum):
if signum in signal_values:
return
raise OperationError(space.w_ValueError,
space.wrap("invalid signal value"))
+
def check_signum_in_range(space, signum):
if 1 <= signum < NSIG:
return
@@ -201,7 +198,7 @@
A signal handler function is called with two arguments:
the first is the signal number, the second is the interrupted stack frame.
"""
- ec = space.getexecutioncontext()
+ ec = space.getexecutioncontext()
main_ec = space.threadlocals.getmainthreadvalue()
old_handler = getsignal(space, signum)
@@ -224,13 +221,14 @@
action.handlers_w[signum] = w_handler
return old_handler
+
@jit.dont_look_inside
@unwrap_spec(fd=int)
def set_wakeup_fd(space, fd):
"""Sets the fd to be written to (with '\0') when a signal
comes in. Returns the old fd. A library can use this to
wakeup select or poll. The previous fd is returned.
-
+
The fd must be non-blocking.
"""
if space.config.objspace.usemodules.thread:
@@ -243,6 +241,7 @@
old_fd = pypysig_set_wakeup_fd(fd)
return space.wrap(intmask(old_fd))
+
@jit.dont_look_inside
@unwrap_spec(signum=int, flag=int)
def siginterrupt(space, signum, flag):
@@ -258,33 +257,38 @@
rffi.setintfield(timeval, 'c_tv_sec', int(d))
rffi.setintfield(timeval, 'c_tv_usec', int((d - int(d)) * 1000000))
+
def double_from_timeval(tv):
return rffi.getintfield(tv, 'c_tv_sec') + (
rffi.getintfield(tv, 'c_tv_usec') / 1000000.0)
+
def itimer_retval(space, val):
w_value = space.wrap(double_from_timeval(val.c_it_value))
w_interval = space.wrap(double_from_timeval(val.c_it_interval))
return space.newtuple([w_value, w_interval])
+
class Cache:
def __init__(self, space):
self.w_itimererror = space.new_exception_class("signal.ItimerError",
space.w_IOError)
+
def get_itimer_error(space):
return space.fromcache(Cache).w_itimererror
+
@jit.dont_look_inside
@unwrap_spec(which=int, first=float, interval=float)
def setitimer(space, which, first, interval=0):
"""setitimer(which, seconds[, interval])
-
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL
+
or ITIMER_PROF) to fire after value seconds and after
that every interval seconds.
The itimer can be cleared by setting seconds to zero.
-
+
Returns old values as a tuple: (delay, interval).
"""
with lltype.scoped_alloc(itimervalP.TO, 1) as new:
@@ -298,14 +302,14 @@
if ret != 0:
raise exception_from_errno(space, get_itimer_error(space))
+ return itimer_retval(space, old[0])
- return itimer_retval(space, old[0])
@jit.dont_look_inside
@unwrap_spec(which=int)
def getitimer(space, which):
"""getitimer(which)
-
+
Returns current value of given itimer.
"""
with lltype.scoped_alloc(itimervalP.TO, 1) as old:
diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py
--- a/pypy/module/thread/gil.py
+++ b/pypy/module/thread/gil.py
@@ -62,22 +62,7 @@
do_yield_thread()
-class SpaceState:
-
- def _cleanup_(self):
- self.action_after_thread_switch = None
- # ^^^ set by AsyncAction.fire_after_thread_switch()
-
- def after_thread_switch(self):
- # this is support logic for the signal module, to help it deliver
- # signals to the main thread.
- action = self.action_after_thread_switch
- if action is not None:
- self.action_after_thread_switch = None
- action.fire()
-
-spacestate = SpaceState()
-spacestate._cleanup_()
+after_thread_switch = lambda: None # hook for signal.py
# Fragile code below. We have to preserve the C-level errno manually...
@@ -94,7 +79,7 @@
e = get_errno()
thread.gil_acquire()
thread.gc_thread_run()
- spacestate.after_thread_switch()
+ after_thread_switch()
set_errno(e)
after_external_call._gctransformer_hint_cannot_collect_ = True
after_external_call._dont_reach_me_in_del_ = True
@@ -112,7 +97,7 @@
# the same thread).
if thread.gil_yield_thread():
thread.gc_thread_run()
- spacestate.after_thread_switch()
+ after_thread_switch()
do_yield_thread._gctransformer_hint_close_stack_ = True
do_yield_thread._dont_reach_me_in_del_ = True
do_yield_thread._dont_inline_ = True
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
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
@@ -48,6 +48,9 @@
ident = self._mainthreadident
return self._valuedict.get(ident, None)
+ def ismainthread(self):
+ return thread.get_ident() == self._mainthreadident
+
def getallvalues(self):
return self._valuedict
diff --git a/rpython/annotator/test/test_annrpython.py
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -2068,7 +2068,23 @@
s = a.build_types(f, [annmodel.SomeString(no_nul=True)])
assert isinstance(s, annmodel.SomeString)
assert s.no_nul
-
+
+ def test_getitem_str0(self):
+ def f(s, n):
+ if n == 1:
+ return s[0]
+ elif n == 2:
+ return s[1]
+ elif n == 3:
+ return s[1:]
+ return s
+ a = self.RPythonAnnotator()
+ a.translator.config.translation.check_str_without_nul = True
+
+ s = a.build_types(f, [annmodel.SomeString(no_nul=True),
+ annmodel.SomeInteger()])
+ assert isinstance(s, annmodel.SomeString)
+ assert s.no_nul
def test_non_none_and_none_with_isinstance(self):
class A(object):
diff --git a/rpython/jit/backend/llsupport/ffisupport.py
b/rpython/jit/backend/llsupport/ffisupport.py
--- a/rpython/jit/backend/llsupport/ffisupport.py
+++ b/rpython/jit/backend/llsupport/ffisupport.py
@@ -42,11 +42,14 @@
@specialize.memo()
def _get_ffi2descr_dict(cpu):
- d = {('v', 0): ('v', None)}
+ def entry(letter, TYPE):
+ return (letter, cpu.arraydescrof(rffi.CArray(TYPE)), rffi.sizeof(TYPE))
+ #
+ d = {('v', 0): ('v', None, 1)}
if cpu.supports_floats:
- d[('f', 0)] = ('f', cpu.arraydescrof(rffi.CArray(lltype.Float)))
+ d[('f', 0)] = entry('f', lltype.Float)
if cpu.supports_singlefloats:
- d[('S', 0)] = ('i', cpu.arraydescrof(rffi.CArray(lltype.SingleFloat)))
+ d[('S', 0)] = entry('i', lltype.SingleFloat)
for SIGNED_TYPE in [rffi.SIGNEDCHAR,
rffi.SHORT,
rffi.INT,
@@ -59,7 +62,7 @@
continue
key = ('L', 0)
kind = 'f'
- d[key] = (kind, cpu.arraydescrof(rffi.CArray(SIGNED_TYPE)))
+ d[key] = entry(kind, SIGNED_TYPE)
for UNSIGNED_TYPE in [rffi.UCHAR,
rffi.USHORT,
rffi.UINT,
@@ -68,7 +71,7 @@
key = ('u', rffi.sizeof(UNSIGNED_TYPE))
if key[1] > rffi.sizeof(lltype.Signed):
continue
- d[key] = ('i', cpu.arraydescrof(rffi.CArray(UNSIGNED_TYPE)))
+ d[key] = entry('i', UNSIGNED_TYPE)
return d
def get_arg_descr(cpu, ffi_type):
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -2567,7 +2567,8 @@
self.history.operations.pop()
arg_boxes = []
for i in range(cif_description.nargs):
- kind, descr = get_arg_descr(self.cpu, cif_description.atypes[i])
+ kind, descr, itemsize = get_arg_descr(self.cpu,
+ cif_description.atypes[i])
if kind == 'i':
box_arg = history.BoxInt()
elif kind == 'f':
@@ -2576,16 +2577,14 @@
assert kind == 'v'
continue
ofs = cif_description.exchange_args[i]
- box_argpos = history.BoxInt()
- self.history.record(rop.INT_ADD,
- [box_exchange_buffer, ConstInt(ofs)],
- box_argpos)
+ assert ofs % itemsize == 0 # alignment check
self.history.record(rop.GETARRAYITEM_RAW,
- [box_argpos, ConstInt(0)],
+ [box_exchange_buffer,
+ ConstInt(ofs // itemsize)],
box_arg, descr)
arg_boxes.append(box_arg)
#
- kind, descr = get_arg_descr(self.cpu, cif_description.rtype)
+ kind, descr, itemsize = get_arg_descr(self.cpu, cif_description.rtype)
if kind == 'i':
box_result = history.BoxInt()
elif kind == 'f':
@@ -2601,12 +2600,10 @@
#
if box_result is not None:
ofs = cif_description.exchange_result
- box_resultpos = history.BoxInt()
- self.history.record(rop.INT_ADD,
- [box_exchange_buffer, ConstInt(ofs)],
- box_resultpos)
+ assert ofs % itemsize == 0 # alignment check (result)
self.history.record(rop.SETARRAYITEM_RAW,
- [box_resultpos, ConstInt(0), box_result],
+ [box_exchange_buffer,
+ ConstInt(ofs // itemsize), box_result],
None, descr)
def direct_call_release_gil(self):
diff --git a/rpython/jit/metainterp/test/test_warmspot.py
b/rpython/jit/metainterp/test/test_warmspot.py
--- a/rpython/jit/metainterp/test/test_warmspot.py
+++ b/rpython/jit/metainterp/test/test_warmspot.py
@@ -401,6 +401,7 @@
assert len(oplabel.getarglist()) == 2 # 'n', 'res' in some order
def test_inline_jit_merge_point(self):
+ py.test.skip("fix the test if you want to re-enable this")
# test that the machinery to inline jit_merge_points in callers
# works. The final user does not need to mess manually with the
# _inline_jit_merge_point_ attribute and similar, it is all nicely
@@ -430,6 +431,7 @@
self.check_resops(int_add=4)
def test_jitdriver_inline(self):
+ py.test.skip("fix the test if you want to re-enable this")
myjitdriver = JitDriver(greens = [], reds = 'auto')
class MyRange(object):
def __init__(self, n):
@@ -462,6 +464,7 @@
self.check_trace_count(1)
def test_jitdriver_inline_twice(self):
+ py.test.skip("fix the test if you want to re-enable this")
myjitdriver = JitDriver(greens = [], reds = 'auto')
def jit_merge_point(a, b):
@@ -492,6 +495,7 @@
self.check_trace_count(2)
def test_jitdriver_inline_exception(self):
+ py.test.skip("fix the test if you want to re-enable this")
# this simulates what happens in a real case scenario: inside the next
# we have a call which we cannot inline (e.g. space.next in the case
# of W_InterpIterable), but we need to put it in a try/except block.
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -578,6 +578,8 @@
pass
def inline(self, call_jit_merge_point):
+ assert False, "@inline off: see skipped failures in test_warmspot."
+ #
assert self.autoreds, "@inline works only with reds='auto'"
self.inline_jit_merge_point = True
def decorate(func):
diff --git a/rpython/rlib/rsignal.py b/rpython/rlib/rsignal.py
--- a/rpython/rlib/rsignal.py
+++ b/rpython/rlib/rsignal.py
@@ -80,6 +80,8 @@
pypysig_poll = external('pypysig_poll', [], rffi.INT, threadsafe=False)
# don't bother releasing the GIL around a call to pypysig_poll: it's
# pointless and a performance issue
+pypysig_pushback = external('pypysig_pushback', [rffi.INT], lltype.Void,
+ threadsafe=False)
# don't use rffi.LONGP because the JIT doesn't support raw arrays so far
struct_name = 'pypysig_long_struct'
diff --git a/rpython/rlib/test/test_jit.py b/rpython/rlib/test/test_jit.py
--- a/rpython/rlib/test/test_jit.py
+++ b/rpython/rlib/test/test_jit.py
@@ -35,6 +35,7 @@
assert driver.reds == ['a', 'b']
assert driver.numreds == 2
[email protected](reason="@inline off: see skipped failures in
test_warmspot.")
def test_jitdriver_inline():
driver = JitDriver(greens=[], reds='auto')
calls = []
@@ -54,6 +55,7 @@
('bar', 40, 2),
]
[email protected](reason="@inline off: see skipped failures in
test_warmspot.")
def test_jitdriver_clone():
def bar(): pass
def foo(): pass
diff --git a/rpython/rlib/test/test_rcomplex.py
b/rpython/rlib/test/test_rcomplex.py
--- a/rpython/rlib/test/test_rcomplex.py
+++ b/rpython/rlib/test/test_rcomplex.py
@@ -260,3 +260,24 @@
rAssertAlmostEqual(expected[1], actual[1],
abs_err=real_abs_err,
msg=error_message)
+
+def test_isnan():
+ assert not c.c_isnan(0, 0)
+ assert c.c_isnan(float('nan'), 0)
+ assert c.c_isnan(1, float('nan'))
+ assert not c.c_isnan(float('inf'), 0)
+
+def test_isinf():
+ assert not c.c_isinf(0, 0)
+ assert c.c_isinf(float('inf'), 0)
+ assert c.c_isinf(float('-inf'), 0)
+ assert c.c_isinf(1, float('inf'))
+ assert not c.c_isinf(float('nan'), 0)
+
+def test_isfinite():
+ assert c.c_isfinite(0, 0)
+ assert not c.c_isfinite(float('nan'), 0)
+ assert not c.c_isfinite(float('-inf'), 0)
+ assert not c.c_isfinite(0, float('nan'))
+ assert not c.c_isfinite(0, float('-inf'))
+
diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py
b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -32,6 +32,15 @@
except ImportError:
class tlsobject(object):
pass
+try:
+ from threading import RLock
+except ImportError:
+ class RLock(object):
+ def __enter__(self):
+ pass
+ def __exit__(self, *args):
+ pass
+rlock = RLock()
_POSIX = os.name == "posix"
_MS_WINDOWS = os.name == "nt"
@@ -694,10 +703,11 @@
return None
def lltype2ctypes(llobj, normalize=True):
- """Convert the lltype object 'llobj' to its ctypes equivalent.
- 'normalize' should only be False in tests, where we want to
- inspect the resulting ctypes object manually.
- """
+ """Convert the lltype object 'llobj' to its ctypes equivalent.
+ 'normalize' should only be False in tests, where we want to
+ inspect the resulting ctypes object manually.
+ """
+ with rlock:
if isinstance(llobj, lltype._uninitialized):
return uninitialized2ctypes(llobj.TYPE)
if isinstance(llobj, llmemory.AddressAsInt):
@@ -875,9 +885,10 @@
return llobj
def ctypes2lltype(T, cobj):
- """Convert the ctypes object 'cobj' to its lltype equivalent.
- 'T' is the expected lltype type.
- """
+ """Convert the ctypes object 'cobj' to its lltype equivalent.
+ 'T' is the expected lltype type.
+ """
+ with rlock:
if T is lltype.Void:
return None
if isinstance(T, lltype.Typedef):
@@ -1176,10 +1187,11 @@
#self.funcptr = ... set later
def __call__(self, *argvalues):
- if self.trampoline is None:
- # lazily build the corresponding ctypes function object
- cfunc = get_ctypes_callable(self.funcptr, self.calling_conv)
- self.trampoline = get_ctypes_trampoline(self.FUNCTYPE, cfunc)
+ with rlock:
+ if self.trampoline is None:
+ # lazily build the corresponding ctypes function object
+ cfunc = get_ctypes_callable(self.funcptr, self.calling_conv)
+ self.trampoline = get_ctypes_trampoline(self.FUNCTYPE, cfunc)
# perform the call
return self.trampoline(*argvalues)
@@ -1215,8 +1227,9 @@
return ctypes2lltype(RESULT, cres)
return invoke_via_ctypes
+
def force_cast(RESTYPE, value):
- """Cast a value to a result type, trying to use the same rules as C."""
+ with rlock:
if not isinstance(RESTYPE, lltype.LowLevelType):
raise TypeError("rffi.cast() first arg should be a TYPE")
if isinstance(value, llmemory.AddressAsInt):
diff --git a/rpython/tool/stdlib_opcode.py b/rpython/tool/stdlib_opcode.py
--- a/rpython/tool/stdlib_opcode.py
+++ b/rpython/tool/stdlib_opcode.py
@@ -71,7 +71,14 @@
def to_globals(self, globals_dict):
"""NOT_RPYTHON. Add individual opcodes to the module constants."""
- globals_dict.update(self.opmap)
+ for name, value in self.opmap.iteritems():
+ # Rename 'STORE_SLICE+0' opcodes
+ if name.endswith('+0'):
+ name = name[:-2]
+ # Ignore 'STORE_SLICE+1' opcodes
+ elif name.endswith(('+1', '+2', '+3')):
+ continue
+ globals_dict[name] = value
def __str__(self):
return "<%s bytecode>" % (self.name,)
diff --git a/rpython/translator/c/src/signals.c
b/rpython/translator/c/src/signals.c
--- a/rpython/translator/c/src/signals.c
+++ b/rpython/translator/c/src/signals.c
@@ -71,7 +71,7 @@
#endif
}
-static void signal_setflag_handler(int signum)
+void pypysig_pushback(int signum)
{
if (0 <= signum && signum < NSIG)
{
@@ -79,6 +79,11 @@
pypysig_occurred = 1;
pypysig_counter.value = -1;
}
+}
+
+static void signal_setflag_handler(int signum)
+{
+ pypysig_pushback(signum);
if (wakeup_fd != -1)
{
diff --git a/rpython/translator/c/src/signals.h
b/rpython/translator/c/src/signals.h
--- a/rpython/translator/c/src/signals.h
+++ b/rpython/translator/c/src/signals.h
@@ -11,6 +11,7 @@
/* utility to poll for signals that arrived */
int pypysig_poll(void); /* => signum or -1 */
+void pypysig_pushback(int signum);
/* When a signal is received, pypysig_counter is set to -1. */
/* This is a struct for the JIT. See rsignal.py. */
diff --git a/rpython/translator/c/src/thread_nt.c
b/rpython/translator/c/src/thread_nt.c
--- a/rpython/translator/c/src/thread_nt.c
+++ b/rpython/translator/c/src/thread_nt.c
@@ -5,6 +5,7 @@
/* Eliminated some memory leaks, [email protected] */
#include <windows.h>
+#include <stdio.h>
#include <limits.h>
#include <process.h>
@@ -112,7 +113,7 @@
mutex->sem = NULL ; /* Just in case */
}
-DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait)
+DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds)
{
return WaitForSingleObject(mutex->sem, milliseconds);
}
@@ -151,26 +152,28 @@
{
/* Fow now, intr_flag does nothing on Windows, and lock acquires are
* uninterruptible. */
- PyLockStatus success;
- PY_TIMEOUT_T milliseconds;
+ RPyLockStatus success;
+ RPY_TIMEOUT_T milliseconds;
if (microseconds >= 0) {
milliseconds = microseconds / 1000;
if (microseconds % 1000 > 0)
++milliseconds;
- if ((DWORD) milliseconds != milliseconds)
- Py_FatalError("Timeout too large for a DWORD, "
- "please check PY_TIMEOUT_MAX");
+ if ((DWORD) milliseconds != milliseconds) {
+ fprintf(stderr, "Timeout too large for a DWORD, "
+ "please check RPY_TIMEOUT_MAX");
+ abort();
+ }
}
else
milliseconds = INFINITE;
if (lock && EnterNonRecursiveMutex(
lock, (DWORD)milliseconds) == WAIT_OBJECT_0) {
- success = PY_LOCK_ACQUIRED;
+ success = RPY_LOCK_ACQUIRED;
}
else {
- success = PY_LOCK_FAILURE;
+ success = RPY_LOCK_FAILURE;
}
return success;
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit