summaryrefslogtreecommitdiff
path: root/c/minibuffer.h
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2013-01-10 10:01:47 +0100
committerArmin Rigo <arigo@tunes.org>2013-01-10 10:01:47 +0100
commitaad2787c5393130dd8be562f9bcfe7dd2a9ef7b6 (patch)
tree257a4d8d41435d78b4648125c57ae736bc66e324 /c/minibuffer.h
parentd7ce8762a986ba80db597c9425f630b9805eb7ec (diff)
downloadcffi-aad2787c5393130dd8be562f9bcfe7dd2a9ef7b6.tar.gz
minibuffer: weakref support, and keep alive the argument.
Diffstat (limited to 'c/minibuffer.h')
-rw-r--r--c/minibuffer.h48
1 files changed, 42 insertions, 6 deletions
diff --git a/c/minibuffer.h b/c/minibuffer.h
index ebf7f46..3129032 100644
--- a/c/minibuffer.h
+++ b/c/minibuffer.h
@@ -9,6 +9,8 @@ typedef struct {
PyObject_HEAD
char *mb_data;
Py_ssize_t mb_size;
+ PyObject *mb_keepalive;
+ PyObject *mb_weakreflist; /* weakref support */
} MiniBufferObj;
static Py_ssize_t mb_length(MiniBufferObj *self)
@@ -120,6 +122,30 @@ static PyBufferProcs mb_as_buffer = {
(releasebufferproc)0,
};
+static void
+mb_dealloc(MiniBufferObj *ob)
+{
+ PyObject_GC_UnTrack(ob);
+ if (ob->mb_weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *)ob);
+ Py_XDECREF(ob->mb_keepalive);
+ Py_TYPE(ob)->tp_free((PyObject *)ob);
+}
+
+static int
+mb_traverse(MiniBufferObj *ob, visitproc visit, void *arg)
+{
+ Py_VISIT(ob->mb_keepalive);
+ return 0;
+}
+
+static int
+mb_clear(MiniBufferObj *ob)
+{
+ Py_CLEAR(ob->mb_keepalive);
+ return 0;
+}
+
#if PY_MAJOR_VERSION >= 3
/* pfffffffffffff pages of copy-paste from listobject.c */
static PyObject *mb_subscript(MiniBufferObj *self, PyObject *item)
@@ -198,9 +224,9 @@ static PyMappingMethods mb_as_mapping = {
#endif
#if PY_MAJOR_VERSION >= 3
-# define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT)
+# define MINIBUF_TPFLAGS 0
#else
-# define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER)
+# define MINIBUF_TPFLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER)
#endif
static PyTypeObject MiniBuffer_Type = {
@@ -208,7 +234,7 @@ static PyTypeObject MiniBuffer_Type = {
"_cffi_backend.buffer",
sizeof(MiniBufferObj),
0,
- (destructor)PyObject_Del, /* tp_dealloc */
+ (destructor)mb_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -227,15 +253,25 @@ static PyTypeObject MiniBuffer_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&mb_as_buffer, /* tp_as_buffer */
- MINIBUF_TPFLAGS, /* tp_flags */
+ (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ MINIBUF_TPFLAGS), /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)mb_traverse, /* tp_traverse */
+ (inquiry)mb_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(MiniBufferObj, mb_weakreflist), /* tp_weaklistoffset */
};
-static PyObject *minibuffer_new(char *data, Py_ssize_t size)
+static PyObject *minibuffer_new(char *data, Py_ssize_t size,
+ PyObject *keepalive)
{
- MiniBufferObj *ob = PyObject_New(MiniBufferObj, &MiniBuffer_Type);
+ MiniBufferObj *ob = PyObject_GC_New(MiniBufferObj, &MiniBuffer_Type);
if (ob != NULL) {
ob->mb_data = data;
ob->mb_size = size;
+ ob->mb_keepalive = keepalive; Py_INCREF(keepalive);
+ ob->mb_weakreflist = NULL;
+ PyObject_GC_Track(ob);
}
return (PyObject *)ob;
}