Author: Armin Rigo <ar...@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: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit