summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2014-06-25 19:28:49 +0200
committerArmin Rigo <arigo@tunes.org>2014-06-25 19:28:49 +0200
commit6c00e79d66b0c387ce90835b7cfb5296e01f0603 (patch)
treeeb1cfe8c7886ef9f12673c813a3f47a5fccf2aba
parent015d6932cb9c6229d9bd5d1cdcd683353ee691ba (diff)
downloadcffi-6c00e79d66b0c387ce90835b7cfb5296e01f0603.tar.gz
A test for checking the multithreaded safety of errno (and GetLastError
on Windows).
-rw-r--r--testing/test_verify.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/testing/test_verify.py b/testing/test_verify.py
index d9092fa..9e4f51f 100644
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1905,3 +1905,60 @@ def test_ptr_to_opaque():
p = lib.f2(42)
x = lib.f1(p)
assert x == 42
+
+def _run_in_multiple_threads(test1):
+ test1()
+ import sys
+ try:
+ import thread
+ except ImportError:
+ import _thread as thread
+ errors = []
+ def wrapper(lock):
+ try:
+ test1()
+ except:
+ errors.append(sys.exc_info())
+ lock.release()
+ locks = []
+ for i in range(10):
+ _lock = thread.allocate_lock()
+ _lock.acquire()
+ thread.start_new_thread(wrapper, (_lock,))
+ locks.append(_lock)
+ for _lock in locks:
+ _lock.acquire()
+ if errors:
+ raise errors[0][1]
+
+def test_errno_working_even_with_pypys_jit():
+ ffi = FFI()
+ ffi.cdef("int f(int);")
+ lib = ffi.verify("""
+ #include <errno.h>
+ int f(int x) { return (errno = errno + x); }
+ """)
+ @_run_in_multiple_threads
+ def test1():
+ ffi.errno = 0
+ for i in range(10000):
+ e = lib.f(1)
+ assert e == i + 1
+ assert ffi.errno == e
+ for i in range(10000):
+ ffi.errno = i
+ e = lib.f(42)
+ assert e == i + 42
+
+def test_getlasterror_working_even_with_pypys_jit():
+ if sys.platform != 'win32':
+ py.test.skip("win32-only test")
+ ffi = FFI()
+ ffi.cdef("void SetLastError(DWORD);")
+ lib = ffi.dlopen("Kernel32.dll")
+ @_run_in_multiple_threads
+ def test1():
+ for i in range(10000):
+ n = (1 << 29) + i
+ lib.SetLastError(n)
+ assert ffi.getwinerror()[0] == n