// Copyright David Abrahams 2002. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include namespace boost { namespace python { namespace objects { struct life_support { PyObject_HEAD PyObject* patient; }; extern "C" { static void life_support_dealloc(PyObject* self) { Py_XDECREF(((life_support*)self)->patient); self->ob_type->tp_free(self); } static PyObject * life_support_call(PyObject *self, PyObject *arg, PyObject * /*kw*/) { // Let the patient die now Py_XDECREF(((life_support*)self)->patient); ((life_support*)self)->patient = 0; // Let the weak reference die. This probably kills us. Py_XDECREF(PyTuple_GET_ITEM(arg, 0)); return ::boost::python::detail::none(); } } PyTypeObject life_support_type = { PyVarObject_HEAD_INIT(NULL, 0)//(&PyType_Type) const_cast("Boost.Python.life_support"), sizeof(life_support), 0, life_support_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, //(reprfunc)func_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ life_support_call, /* tp_call */ 0, /* tp_str */ 0, // PyObject_GenericGetAttr, /* tp_getattro */ 0, // PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */ 0, /* tp_doc */ 0, // (traverseproc)func_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, //offsetof(PyLife_SupportObject, func_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, // func_memberlist, /* tp_members */ 0, //func_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, //offsetof(PyLife_SupportObject, func_dict), /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ #if PYTHON_API_VERSION >= 1012 0 /* tp_del */ #endif }; PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient) { if (nurse == Py_None || nurse == patient) return nurse; if (Py_TYPE(&life_support_type) == 0) { Py_TYPE(&life_support_type) = &PyType_Type; PyType_Ready(&life_support_type); } life_support* system = PyObject_New(life_support, &life_support_type); if (!system) return 0; system->patient = 0; // We're going to leak this reference, but don't worry; the // life_support system decrements it when the nurse dies. PyObject* weakref = PyWeakref_NewRef(nurse, (PyObject*)system); // weakref has either taken ownership, or we have to release it // anyway Py_DECREF(system); if (!weakref) return 0; system->patient = patient; Py_XINCREF(patient); // hang on to the patient until death return weakref; } }}} // namespace boost::python::objects