]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/python/src/object/life_support.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / python / src / object / life_support.cpp
1 // Copyright David Abrahams 2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #include <boost/python/object/life_support.hpp>
6 #include <boost/python/detail/none.hpp>
7 #include <boost/python/refcount.hpp>
8
9 namespace boost { namespace python { namespace objects {
10
11 struct life_support
12 {
13 PyObject_HEAD
14 PyObject* patient;
15 };
16
17 extern "C"
18 {
19 static void
20 life_support_dealloc(PyObject* self)
21 {
22 Py_XDECREF(((life_support*)self)->patient);
23 self->ob_type->tp_free(self);
24 }
25
26 static PyObject *
27 life_support_call(PyObject *self, PyObject *arg, PyObject * /*kw*/)
28 {
29 // Let the patient die now
30 Py_XDECREF(((life_support*)self)->patient);
31 ((life_support*)self)->patient = 0;
32 // Let the weak reference die. This probably kills us.
33 Py_XDECREF(PyTuple_GET_ITEM(arg, 0));
34 return ::boost::python::detail::none();
35 }
36 }
37
38 PyTypeObject life_support_type = {
39 PyVarObject_HEAD_INIT(NULL, 0)//(&PyType_Type)
40 const_cast<char*>("Boost.Python.life_support"),
41 sizeof(life_support),
42 0,
43 life_support_dealloc, /* tp_dealloc */
44 0, /* tp_print */
45 0, /* tp_getattr */
46 0, /* tp_setattr */
47 0, /* tp_compare */
48 0, //(reprfunc)func_repr, /* tp_repr */
49 0, /* tp_as_number */
50 0, /* tp_as_sequence */
51 0, /* tp_as_mapping */
52 0, /* tp_hash */
53 life_support_call, /* tp_call */
54 0, /* tp_str */
55 0, // PyObject_GenericGetAttr, /* tp_getattro */
56 0, // PyObject_GenericSetAttr, /* tp_setattro */
57 0, /* tp_as_buffer */
58 Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */
59 0, /* tp_doc */
60 0, // (traverseproc)func_traverse, /* tp_traverse */
61 0, /* tp_clear */
62 0, /* tp_richcompare */
63 0, //offsetof(PyLife_SupportObject, func_weakreflist), /* tp_weaklistoffset */
64 0, /* tp_iter */
65 0, /* tp_iternext */
66 0, /* tp_methods */
67 0, // func_memberlist, /* tp_members */
68 0, //func_getsetlist, /* tp_getset */
69 0, /* tp_base */
70 0, /* tp_dict */
71 0, /* tp_descr_get */
72 0, /* tp_descr_set */
73 0, //offsetof(PyLife_SupportObject, func_dict), /* tp_dictoffset */
74 0, /* tp_init */
75 0, /* tp_alloc */
76 0, /* tp_new */
77 0, /* tp_free */
78 0, /* tp_is_gc */
79 0, /* tp_bases */
80 0, /* tp_mro */
81 0, /* tp_cache */
82 0, /* tp_subclasses */
83 0, /* tp_weaklist */
84 #if PYTHON_API_VERSION >= 1012
85 0 /* tp_del */
86 #endif
87 };
88
89 PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient)
90 {
91 if (nurse == Py_None || nurse == patient)
92 return nurse;
93
94 if (Py_TYPE(&life_support_type) == 0)
95 {
96 Py_TYPE(&life_support_type) = &PyType_Type;
97 PyType_Ready(&life_support_type);
98 }
99
100 life_support* system = PyObject_New(life_support, &life_support_type);
101 if (!system)
102 return 0;
103
104 system->patient = 0;
105
106 // We're going to leak this reference, but don't worry; the
107 // life_support system decrements it when the nurse dies.
108 PyObject* weakref = PyWeakref_NewRef(nurse, (PyObject*)system);
109
110 // weakref has either taken ownership, or we have to release it
111 // anyway
112 Py_DECREF(system);
113 if (!weakref)
114 return 0;
115
116 system->patient = patient;
117 Py_XINCREF(patient); // hang on to the patient until death
118 return weakref;
119 }
120
121 }}} // namespace boost::python::objects