17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h"
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define GET_WEAKREFS_LISTPTR(o) \
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(weakref_getweakrefcount__doc__,
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"getweakrefcount(object) -- return the number of weak references\n"
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"to 'object'.");
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielweakref_getweakrefcount(PyObject *self, PyObject *object)
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = NULL;
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) {
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list));
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = PyInt_FromLong(0);
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(weakref_getweakrefs__doc__,
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"getweakrefs(object) -- return a list of all weak reference objects\n"
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"that point to 'object'.");
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielweakref_getweakrefs(PyObject *self, PyObject *object)
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = NULL;
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) {
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = PyList_New(count);
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (result != NULL) {
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyWeakReference *current = *list;
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_ssize_t i;
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            for (i = 0; i < count; ++i) {
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyList_SET_ITEM(result, i, (PyObject *) current);
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_INCREF(current);
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                current = current->wr_next;
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = PyList_New(0);
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(weakref_proxy__doc__,
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"proxy(object[, callback]) -- create a proxy object that weakly\n"
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"references 'object'.  'callback', if given, is called with a\n"
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"reference to the proxy when 'object' is about to be finalized.");
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielweakref_proxy(PyObject *self, PyObject *args)
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *object;
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *callback = NULL;
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = NULL;
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) {
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = PyWeakref_NewProxy(object, callback);
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMethodDef
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielweakref_functions[] =  {
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"getweakrefcount", weakref_getweakrefcount,        METH_O,
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     weakref_getweakrefcount__doc__},
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"getweakrefs",     weakref_getweakrefs,            METH_O,
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     weakref_getweakrefs__doc__},
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"proxy",           weakref_proxy,                  METH_VARARGS,
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     weakref_proxy__doc__},
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL, NULL, 0, NULL}
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinit_weakref(void)
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *m;
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    m = Py_InitModule3("_weakref", weakref_functions,
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       "Weak-reference support module.");
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (m != NULL) {
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(&_PyWeakref_RefType);
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyModule_AddObject(m, "ref",
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           (PyObject *) &_PyWeakref_RefType);
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(&_PyWeakref_RefType);
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyModule_AddObject(m, "ReferenceType",
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           (PyObject *) &_PyWeakref_RefType);
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(&_PyWeakref_ProxyType);
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyModule_AddObject(m, "ProxyType",
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           (PyObject *) &_PyWeakref_ProxyType);
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(&_PyWeakref_CallableProxyType);
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyModule_AddObject(m, "CallableProxyType",
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           (PyObject *) &_PyWeakref_CallableProxyType);
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
113