[pypy-svn] r67700 - in pypy/trunk/pypy/rlib: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Sep 15 19:48:49 CEST 2009
Author: arigo
Date: Tue Sep 15 19:48:47 2009
New Revision: 67700
Modified:
pypy/trunk/pypy/rlib/libffi.py
pypy/trunk/pypy/rlib/test/test_libffi.py
Log:
Pass the CDLL instance to the FuncPtr and RawFuncPtr class,
as a keepalive, to prevent dlclose() from being called too early.
Modified: pypy/trunk/pypy/rlib/libffi.py
==============================================================================
--- pypy/trunk/pypy/rlib/libffi.py (original)
+++ pypy/trunk/pypy/rlib/libffi.py Tue Sep 15 19:48:47 2009
@@ -506,8 +506,10 @@
class RawFuncPtr(AbstractFuncPtr):
- def __init__(self, name, argtypes, restype, funcsym, flags=FUNCFLAG_CDECL):
+ def __init__(self, name, argtypes, restype, funcsym, flags=FUNCFLAG_CDECL,
+ keepalive=None):
AbstractFuncPtr.__init__(self, name, argtypes, restype, flags)
+ self.keepalive = keepalive
self.funcsym = funcsym
def call(self, args_ll, ll_result):
@@ -527,9 +529,11 @@
ll_args = lltype.nullptr(rffi.VOIDPP.TO)
ll_result = lltype.nullptr(rffi.VOIDP.TO)
- def __init__(self, name, argtypes, restype, funcsym, flags=FUNCFLAG_CDECL):
+ def __init__(self, name, argtypes, restype, funcsym, flags=FUNCFLAG_CDECL,
+ keepalive=None):
# initialize each one of pointers with null
AbstractFuncPtr.__init__(self, name, argtypes, restype, flags)
+ self.keepalive = keepalive
self.funcsym = funcsym
self.argnum = len(self.argtypes)
self.pushed_args = 0
@@ -609,7 +613,9 @@
lltype.free(ll_libname, flavor='raw')
def __del__(self):
+ print 'in __del__'
if self.lib and self.unload_on_finalization:
+ print 'calling dlclose()'
dlclose(self.lib)
self.lib = lltype.nullptr(rffi.CCHARP.TO)
@@ -617,20 +623,21 @@
# these arguments are already casted to proper ffi
# structures!
return FuncPtr(name, argtypes, restype, dlsym(self.lib, name),
- flags=flags)
+ flags=flags, keepalive=self)
def getrawpointer(self, name, argtypes, restype, flags=FUNCFLAG_CDECL):
# these arguments are already casted to proper ffi
# structures!
return RawFuncPtr(name, argtypes, restype, dlsym(self.lib, name),
- flags=flags)
+ flags=flags, keepalive=self)
def getrawpointer_byordinal(self, ordinal, argtypes, restype,
flags=FUNCFLAG_CDECL):
# these arguments are already casted to proper ffi
# structures!
return RawFuncPtr(name, argtypes, restype,
- dlsym_byordinal(self.lib, ordinal), flags=flags)
+ dlsym_byordinal(self.lib, ordinal), flags=flags,
+ keepalive=self)
def getaddressindll(self, name):
return dlsym(self.lib, name)
Modified: pypy/trunk/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/trunk/pypy/rlib/test/test_libffi.py (original)
+++ pypy/trunk/pypy/rlib/test/test_libffi.py Tue Sep 15 19:48:47 2009
@@ -377,6 +377,37 @@
assert not ALLOCATED
+ def test_cdll_life_time(self):
+ from pypy.translator.tool.cbuild import ExternalCompilationInfo
+ from pypy.translator.platform import platform
+ from pypy.tool.udir import udir
+
+ c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
+ c_file.write(py.code.Source('''
+ long fun(long i) {
+ return i + 42;
+ }
+ '''))
+ eci = ExternalCompilationInfo(export_symbols=['fun'])
+ lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))
+
+ lib = CDLL(lib_name)
+ slong = cast_type_to_ffitype(rffi.LONG)
+ fun = lib.getrawpointer('fun', [slong], slong)
+ del lib # already delete here
+
+ buffer = lltype.malloc(rffi.LONGP.TO, 2, flavor='raw')
+ buffer[0] = 200
+ buffer[1] = -1
+ fun.call([rffi.cast(rffi.VOIDP, buffer)],
+ rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 1)))
+ assert buffer[1] == 242
+
+ lltype.free(buffer, flavor='raw')
+ del fun
+
+ assert not ALLOCATED
+
class TestWin32Handles:
def setup_class(cls):
if sys.platform != 'win32':
More information about the Pypy-commit
mailing list