From 001911e5023ae13a3299745a8d4a4dea0f52dd6a Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Wed, 2 Mar 2016 12:08:03 -0600
Subject: [PATCH] Make an option to not clRetainXXX in from_int_ptr (Fixes
 #113)

---
 pyopencl/cffi_cl.py          | 12 ++++++++++--
 src/c_wrapper/clobj.h        |  4 ++--
 src/c_wrapper/wrap_cl.cpp    | 30 +++++++++++++++---------------
 src/c_wrapper/wrap_cl_core.h |  2 +-
 4 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index 2b659bde..096ebf79 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -230,10 +230,18 @@ class _Common(object):
         return _lib.clobj__int_ptr(self.ptr)
 
     @classmethod
-    def from_int_ptr(cls, int_ptr_value):
+    def from_int_ptr(cls, int_ptr_value, retain=True):
+        """Constructs a :mod:`pyopencl` handle from a C-level pointer (given as
+        the integer *int_ptr_value*). If *retain* is *True* (the defauult)
+        :mod:`pyopencl` will call ``clRetainXXX`` on the provided object. If
+        the previous owner of the object will *not* release the reference,
+        *retain* should be set to *False*, to effectively transfer ownership to
+        :mod:`pyopencl`.
+        """
         ptr = _ffi.new('clobj_t*')
         _handle_error(_lib.clobj__from_int_ptr(
-            ptr, int_ptr_value, getattr(_lib, 'CLASS_%s' % cls._id.upper())))
+            ptr, int_ptr_value, getattr(_lib, 'CLASS_%s' % cls._id.upper()),
+            retain))
         return cls._create(ptr[0])
 
 # }}}
diff --git a/src/c_wrapper/clobj.h b/src/c_wrapper/clobj.h
index 6d298228..5db08710 100644
--- a/src/c_wrapper/clobj.h
+++ b/src/c_wrapper/clobj.h
@@ -94,9 +94,9 @@ public:
 
 template<typename CLObj>
 static PYOPENCL_INLINE CLObj*
-clobj_from_int_ptr(intptr_t ptr)
+clobj_from_int_ptr(intptr_t ptr, bool retain)
 {
-    return new CLObj(reinterpret_cast<typename CLObj::cl_type>(ptr), true);
+    return new CLObj(reinterpret_cast<typename CLObj::cl_type>(ptr), retain);
 }
 
 template<typename T, typename T2>
diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp
index 5a88c05e..1e001eb4 100644
--- a/src/c_wrapper/wrap_cl.cpp
+++ b/src/c_wrapper/wrap_cl.cpp
@@ -59,34 +59,34 @@ clobj__int_ptr(clobj_t obj)
 }
 
 static PYOPENCL_INLINE clobj_t
-_from_int_ptr(intptr_t ptr, class_t class_)
+_from_int_ptr(intptr_t ptr, class_t class_, bool retain)
 {
     switch(class_) {
     case CLASS_PLATFORM:
-        return clobj_from_int_ptr<platform>(ptr);
+        return clobj_from_int_ptr<platform>(ptr, retain);
     case CLASS_DEVICE:
-        return clobj_from_int_ptr<device>(ptr);
+        return clobj_from_int_ptr<device>(ptr, retain);
     case CLASS_KERNEL:
-        return clobj_from_int_ptr<kernel>(ptr);
+        return clobj_from_int_ptr<kernel>(ptr, retain);
     case CLASS_CONTEXT:
-        return clobj_from_int_ptr<context>(ptr);
+        return clobj_from_int_ptr<context>(ptr, retain);
     case CLASS_COMMAND_QUEUE:
-        return clobj_from_int_ptr<command_queue>(ptr);
+        return clobj_from_int_ptr<command_queue>(ptr, retain);
     case CLASS_BUFFER:
-        return clobj_from_int_ptr<buffer>(ptr);
+        return clobj_from_int_ptr<buffer>(ptr, retain);
     case CLASS_PROGRAM:
-        return clobj_from_int_ptr<program>(ptr);
+        return clobj_from_int_ptr<program>(ptr, retain);
     case CLASS_EVENT:
-        return clobj_from_int_ptr<event>(ptr);
+        return clobj_from_int_ptr<event>(ptr, retain);
     case CLASS_IMAGE:
-        return clobj_from_int_ptr<image>(ptr);
+        return clobj_from_int_ptr<image>(ptr, retain);
     case CLASS_SAMPLER:
-        return clobj_from_int_ptr<sampler>(ptr);
+        return clobj_from_int_ptr<sampler>(ptr, retain);
 #ifdef HAVE_GL
     case CLASS_GL_BUFFER:
-        return clobj_from_int_ptr<gl_buffer>(ptr);
+        return clobj_from_int_ptr<gl_buffer>(ptr, retain);
     case CLASS_GL_RENDERBUFFER:
-        return clobj_from_int_ptr<gl_renderbuffer>(ptr);
+        return clobj_from_int_ptr<gl_renderbuffer>(ptr, retain);
 #endif
     default:
         throw clerror("unknown class", CL_INVALID_VALUE);
@@ -94,10 +94,10 @@ _from_int_ptr(intptr_t ptr, class_t class_)
 }
 
 error*
-clobj__from_int_ptr(clobj_t *out, intptr_t ptr, class_t class_)
+clobj__from_int_ptr(clobj_t *out, intptr_t ptr, class_t class_, int retain)
 {
     return c_handle_error([&] {
-            *out = _from_int_ptr(ptr, class_);
+            *out = _from_int_ptr(ptr, class_, retain);
         });
 }
 
diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h
index 606ff40f..7a5eefa4 100644
--- a/src/c_wrapper/wrap_cl_core.h
+++ b/src/c_wrapper/wrap_cl_core.h
@@ -290,4 +290,4 @@ error *enqueue_copy_buffer_to_image(clobj_t *evt, clobj_t _queue, clobj_t _src,
 intptr_t clobj__int_ptr(clobj_t obj);
 error *clobj__get_info(clobj_t obj, cl_uint param, generic_info *out);
 void clobj__delete(clobj_t obj);
-error *clobj__from_int_ptr(clobj_t *out, intptr_t ptr, class_t);
+error *clobj__from_int_ptr(clobj_t *out, intptr_t ptr, class_t, int);
-- 
GitLab