From c68bd228d87f63ede3bfc4113d7ef670b7de5881 Mon Sep 17 00:00:00 2001 From: Yichao Yu <yyc1992@gmail.com> Date: Mon, 16 Jun 2014 04:50:36 -0400 Subject: [PATCH] do not assume cffi.new_handle always returns the same address for the same object (need to check) --- pyopencl/_cffi.py | 9 ++++++++- pyopencl/c_wrapper/wrap_cl_core.h | 2 +- pyopencl/cffi_cl.py | 5 ++++- src/c_wrapper/event.cpp | 14 +++++++++----- src/c_wrapper/event.h | 4 ++-- src/c_wrapper/pyhelper.cpp | 4 ++-- src/c_wrapper/pyhelper.h | 2 +- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pyopencl/_cffi.py b/pyopencl/_cffi.py index 953be862..60cb2e69 100644 --- a/pyopencl/_cffi.py +++ b/pyopencl/_cffi.py @@ -187,9 +187,16 @@ def _py_deref(handle): except: pass -@_ffi.callback('void(void*)') +# TODO: +# Not sure if cffi always return the same address for the same object +# Unless it is, this function might return a different pointer from its input +# and should only be called once. +@_ffi.callback('void*(void*)') def _py_ref(handle): + obj = _ffi.from_handle(handle) + handle = _ffi.new_handle(obj) _pyrefs[handle] = handle + return handle @_ffi.callback('void(void*, cl_int)') def _py_call(handle, status): diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h index 7069dcbc..5427fa3c 100644 --- a/pyopencl/c_wrapper/wrap_cl_core.h +++ b/pyopencl/c_wrapper/wrap_cl_core.h @@ -48,7 +48,7 @@ typedef struct { int get_cl_version(); void free_pointer(void*); void free_pointer_array(void**, uint32_t size); -void set_py_funcs(int (*_gc)(), void (*_ref)(void*), void (*_deref)(void*), +void set_py_funcs(int (*_gc)(), void *(*_ref)(void*), void (*_deref)(void*), void (*_call)(void*, cl_int)); int have_gl(); diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index 29d2dec0..1ee6ac73 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -847,7 +847,10 @@ def wait_for_events(wait_for): class NannyEvent(Event): def get_ward(self): - return _ffi.from_handle(_lib.nanny_event__get_ward(self.ptr)) + _handle = _lib.nanny_event__get_ward(self.ptr) + if _handle == _ffi.NULL: + return + return _ffi.from_handle(_handle) # TODO # UserEvent diff --git a/src/c_wrapper/event.cpp b/src/c_wrapper/event.cpp index d7373af4..61af726c 100644 --- a/src/c_wrapper/event.cpp +++ b/src/c_wrapper/event.cpp @@ -143,11 +143,15 @@ event__set_callback(clobj_t _evt, cl_int type, void *pyobj) { auto evt = static_cast<event*>(_evt); return c_handle_error([&] { - evt->set_callback(type, [=] (cl_int status) { - py::call(pyobj, status); - py::deref(pyobj); - }); - py::ref(pyobj); + pyobj = py::ref(pyobj); + try { + evt->set_callback(type, [=] (cl_int status) { + py::call(pyobj, status); + py::deref(pyobj); + }); + } catch (...) { + py::deref(pyobj); + } }); } #endif diff --git a/src/c_wrapper/event.h b/src/c_wrapper/event.h index 7f3d6759..3bcd0902 100644 --- a/src/c_wrapper/event.h +++ b/src/c_wrapper/event.h @@ -43,10 +43,10 @@ private: void *m_ward; public: nanny_event(cl_event evt, bool retain, void *ward=nullptr) - : event(evt, retain), m_ward(ward) + : event(evt, retain), m_ward(nullptr) { if (ward) { - py::ref(ward); + m_ward = py::ref(ward); } } ~nanny_event(); diff --git a/src/c_wrapper/pyhelper.cpp b/src/c_wrapper/pyhelper.cpp index ca18c96a..0000728e 100644 --- a/src/c_wrapper/pyhelper.cpp +++ b/src/c_wrapper/pyhelper.cpp @@ -4,7 +4,7 @@ namespace pyopencl { namespace py { WrapFunc<int()> gc; -WrapFunc<void(void*)> ref; +WrapFunc<void*(void*)> ref; WrapFunc<void(void*)> deref; WrapFunc<void(void*, cl_int)> call; } @@ -12,7 +12,7 @@ WrapFunc<void(void*, cl_int)> call; } void -set_py_funcs(int (*_gc)(), void (*_ref)(void*), void (*_deref)(void*), +set_py_funcs(int (*_gc)(), void *(*_ref)(void*), void (*_deref)(void*), void (*_call)(void*, cl_int)) { pyopencl::py::gc = _gc; diff --git a/src/c_wrapper/pyhelper.h b/src/c_wrapper/pyhelper.h index f336cbae..15a72f47 100644 --- a/src/c_wrapper/pyhelper.h +++ b/src/c_wrapper/pyhelper.h @@ -37,7 +37,7 @@ public: namespace py { extern WrapFunc<int()> gc; -extern WrapFunc<void(void*)> ref; +extern WrapFunc<void*(void*)> ref; extern WrapFunc<void(void*)> deref; extern WrapFunc<void(void*, cl_int)> call; } -- GitLab