Author: Armin Rigo <ar...@tunes.org> Branch: cffi-1.0 Changeset: r77362:1dfdc258c12f Date: 2015-05-17 20:30 +0200 http://bitbucket.org/pypy/pypy/changeset/1dfdc258c12f/
Log: test_dlclose diff --git a/pypy/module/_cffi_backend/cdlopen.py b/pypy/module/_cffi_backend/cdlopen.py --- a/pypy/module/_cffi_backend/cdlopen.py +++ b/pypy/module/_cffi_backend/cdlopen.py @@ -1,6 +1,8 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.objectmodel import specialize -from rpython.rlib.rdynload import dlopen, dlsym, dlclose, DLOpenError +from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError + +from pypy.interpreter.error import oefmt from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror from pypy.module._cffi_backend.parse_c_type import ( @@ -121,3 +123,22 @@ "symbol '%s' not found in library '%s': %s", name, self.libname, e.msg) return rffi.cast(rffi.CCHARP, cdata) + + def cdlopen_close(self): + libhandle = self.libhandle + self.libhandle = rffi.cast(DLLHANDLE, 0) + + if not libhandle: + raise oefmt(self.ffi.w_FFIError, "library '%s' is already closed", + self.libname) + + # Clear the dict to force further accesses to do cdlopen_fetch() + # again, and fail because the library was closed. Note that the + # JIT may have elided some accesses, and so has addresses as + # constants. We could work around it with a quasi-immutable flag + # but unsure it's worth it. + self.dict_w.clear() + + if dlclose(libhandle) < 0: + raise oefmt(self.ffi.w_FFIError, "error closing library '%s'", + self.libname) diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py --- a/pypy/module/_cffi_backend/ffi_obj.py +++ b/pypy/module/_cffi_backend/ffi_obj.py @@ -500,9 +500,9 @@ "functions or variables from the library will fail (possibly with a segmentation fault).""" # - from pypy.module._cffi_backend import cdlopen + from pypy.module._cffi_backend.lib_obj import W_LibObject lib = self.space.interp_w(W_LibObject, w_lib) - return cdlopen.ffi_dlclose(self, lib) + lib.cdlopen_close() @unwrap_spec(name=str) diff --git a/pypy/module/_cffi_backend/lib_obj.py b/pypy/module/_cffi_backend/lib_obj.py --- a/pypy/module/_cffi_backend/lib_obj.py +++ b/pypy/module/_cffi_backend/lib_obj.py @@ -220,6 +220,11 @@ def cdlopen_fetch(self, name): raise NotImplementedError + def cdlopen_close(self): + raise oefmt(self.ffi.w_FFIError, + "library '%s' was not created with ffi.dlopen()", + self.libname) + W_LibObject.typedef = TypeDef( 'CompiledLib', diff --git a/pypy/module/_cffi_backend/test/test_re_python.py b/pypy/module/_cffi_backend/test/test_re_python.py --- a/pypy/module/_cffi_backend/test/test_re_python.py +++ b/pypy/module/_cffi_backend/test/test_re_python.py @@ -96,8 +96,7 @@ ffi.dlclose(lib) e = raises(ffi.error, ffi.dlclose, lib) assert str(e.value) == ( - "library '%s' is already closed or was not created with ffi.dlopen()" - % (self.extmod,)) + "library '%s' is already closed" % (self.extmod,)) def test_constant_via_lib(self): from re_python_pysrc import ffi _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit