[pypy-commit] pypy ffi-backend: Change cerrno to be thread-safe.
arigo
noreply at buildbot.pypy.org
Thu Jul 26 23:15:57 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r56487:2e0907ceb229
Date: 2012-07-26 23:15 +0200
http://bitbucket.org/pypy/pypy/changeset/2e0907ceb229/
Log: Change cerrno to be thread-safe.
diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -150,7 +150,7 @@
ll_userdata - a special structure which holds necessary information
(what the real callback is for example), casted to VOIDP
"""
- cerrno.save_errno()
+ e = cerrno.get_real_errno()
ll_res = rffi.cast(rffi.CCHARP, ll_res)
unique_id = rffi.cast(lltype.Signed, ll_userdata)
callback = global_callback_mapping.get(unique_id)
@@ -168,7 +168,10 @@
SIZE_OF_FFI_ARG * llmemory.sizeof(lltype.Char))
return
#
+ ec = None
try:
+ ec = cerrno.get_errno_container(callback.space)
+ cerrno.save_errno_into(ec, e)
try:
callback.invoke(ll_args, ll_res)
except OperationError, e:
@@ -185,4 +188,5 @@
except OSError:
pass
callback.write_error_return_value(ll_res)
- cerrno.restore_errno()
+ if ec is not None:
+ cerrno.restore_errno_from(ec)
diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py
--- a/pypy/module/_cffi_backend/cerrno.py
+++ b/pypy/module/_cffi_backend/cerrno.py
@@ -1,24 +1,29 @@
from pypy.rlib import rposix
+from pypy.interpreter.executioncontext import ExecutionContext
from pypy.interpreter.gateway import unwrap_spec
-class ErrnoContainer(object):
- # XXXXXXXXXXXXXX! thread-safety
- errno = 0
+ExecutionContext._cffi_saved_errno = 0
-errno_container = ErrnoContainer()
+def get_errno_container(space):
+ return space.getexecutioncontext()
-def restore_errno():
- rposix.set_errno(errno_container.errno)
+get_real_errno = rposix.get_errno
-def save_errno():
- errno_container.errno = rposix.get_errno()
+
+def restore_errno_from(ec):
+ rposix.set_errno(ec._cffi_saved_errno)
+
+def save_errno_into(ec, errno):
+ ec._cffi_saved_errno = errno
def get_errno(space):
- return space.wrap(errno_container.errno)
+ ec = get_errno_container(space)
+ return space.wrap(ec._cffi_saved_errno)
@unwrap_spec(errno=int)
def set_errno(space, errno):
- errno_container.errno = errno
+ ec = get_errno_container(space)
+ ec._cffi_saved_errno = errno
diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -142,12 +142,14 @@
argtype.convert_from_object(data, w_obj)
resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
- cerrno.restore_errno()
+ ec = cerrno.get_errno_container(space)
+ cerrno.restore_errno_from(ec)
clibffi.c_ffi_call(cif_descr.cif,
rffi.cast(rffi.VOIDP, funcaddr),
resultdata,
buffer_array)
- cerrno.save_errno()
+ e = cerrno.get_real_errno()
+ cerrno.save_errno_into(ec, e)
if self.ctitem.is_primitive_integer:
if BIG_ENDIAN:
More information about the pypy-commit
mailing list