14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h"
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define GET_WEAKREFS_LISTPTR(o) \
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(weakref_getweakrefcount__doc__,
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"getweakrefcount(object) -- return the number of weak references\n"
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"to 'object'.");
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmweakref_getweakrefcount(PyObject *self, PyObject *object)
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *result = NULL;
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) {
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list));
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = PyInt_FromLong(0);
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return result;
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(weakref_getweakrefs__doc__,
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"getweakrefs(object) -- return a list of all weak reference objects\n"
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"that point to 'object'.");
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmweakref_getweakrefs(PyObject *self, PyObject *object)
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *result = NULL;
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) {
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = PyList_New(count);
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (result != NULL) {
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyWeakReference *current = *list;
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_ssize_t i;
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for (i = 0; i < count; ++i) {
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyList_SET_ITEM(result, i, (PyObject *) current);
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_INCREF(current);
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                current = current->wr_next;
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = PyList_New(0);
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return result;
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(weakref_proxy__doc__,
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"proxy(object[, callback]) -- create a proxy object that weakly\n"
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"references 'object'.  'callback', if given, is called with a\n"
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"reference to the proxy when 'object' is about to be finalized.");
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmweakref_proxy(PyObject *self, PyObject *args)
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *object;
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *callback = NULL;
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *result = NULL;
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) {
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = PyWeakref_NewProxy(object, callback);
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return result;
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmweakref_functions[] =  {
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"getweakrefcount", weakref_getweakrefcount,        METH_O,
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     weakref_getweakrefcount__doc__},
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"getweakrefs",     weakref_getweakrefs,            METH_O,
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     weakref_getweakrefs__doc__},
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"proxy",           weakref_proxy,                  METH_VARARGS,
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     weakref_proxy__doc__},
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {NULL, NULL, 0, NULL}
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyMODINIT_FUNC
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylminit_weakref(void)
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = Py_InitModule3("_weakref", weakref_functions,
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                       "Weak-reference support module.");
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m != NULL) {
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(&_PyWeakref_RefType);
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyModule_AddObject(m, "ref",
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           (PyObject *) &_PyWeakref_RefType);
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(&_PyWeakref_RefType);
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyModule_AddObject(m, "ReferenceType",
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           (PyObject *) &_PyWeakref_RefType);
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(&_PyWeakref_ProxyType);
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyModule_AddObject(m, "ProxyType",
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           (PyObject *) &_PyWeakref_ProxyType);
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(&_PyWeakref_CallableProxyType);
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyModule_AddObject(m, "CallableProxyType",
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           (PyObject *) &_PyWeakref_CallableProxyType);
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
113