blob: e7c0eae5398dfaa60d1e0b8ac5a9e0b12759d2bb [file] [log] [blame]
Fred Drake8844d522001-10-05 21:52:26 +00001/* Weak references objects for Python. */
2
3#ifndef Py_WEAKREFOBJECT_H
4#define Py_WEAKREFOBJECT_H
5#ifdef __cplusplus
6extern "C" {
7#endif
8
9
10typedef struct _PyWeakReference PyWeakReference;
11
Tim Petersead8b7a2004-10-30 23:09:22 +000012/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
13 * and CallableProxyType.
14 */
Fred Drake8844d522001-10-05 21:52:26 +000015struct _PyWeakReference {
16 PyObject_HEAD
Tim Petersead8b7a2004-10-30 23:09:22 +000017
18 /* The object to which this is a weak reference, or Py_None if none.
19 * Note that this is a stealth reference: wr_object's refcount is
20 * not incremented to reflect this pointer.
21 */
Fred Drake8844d522001-10-05 21:52:26 +000022 PyObject *wr_object;
Tim Petersead8b7a2004-10-30 23:09:22 +000023
24 /* A callable to invoke when wr_object dies, or NULL if none. */
Fred Drake8844d522001-10-05 21:52:26 +000025 PyObject *wr_callback;
Tim Petersead8b7a2004-10-30 23:09:22 +000026
27 /* A cache for wr_object's hash code. As usual for hashes, this is -1
28 * if the hash code isn't known yet.
29 */
Fred Drake8844d522001-10-05 21:52:26 +000030 long hash;
Tim Petersead8b7a2004-10-30 23:09:22 +000031
32 /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
33 * terminated list of weak references to it. These are the list pointers.
34 * If wr_object goes away, wr_object is set to Py_None, and these pointers
35 * have no meaning then.
36 */
Fred Drake8844d522001-10-05 21:52:26 +000037 PyWeakReference *wr_prev;
38 PyWeakReference *wr_next;
39};
40
Mark Hammond91a681d2002-08-12 07:21:58 +000041PyAPI_DATA(PyTypeObject) _PyWeakref_RefType;
42PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType;
43PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType;
Fred Drake8844d522001-10-05 21:52:26 +000044
Fred Drake0a4dd392004-07-02 18:57:45 +000045#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType)
46#define PyWeakref_CheckRefExact(op) \
Christian Heimese93237d2007-12-19 02:37:44 +000047 (Py_TYPE(op) == &_PyWeakref_RefType)
Fred Drake8844d522001-10-05 21:52:26 +000048#define PyWeakref_CheckProxy(op) \
Christian Heimese93237d2007-12-19 02:37:44 +000049 ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \
50 (Py_TYPE(op) == &_PyWeakref_CallableProxyType))
Fred Drake0a4dd392004-07-02 18:57:45 +000051
Fred Drake8844d522001-10-05 21:52:26 +000052#define PyWeakref_Check(op) \
53 (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op))
54
55
Mark Hammond91a681d2002-08-12 07:21:58 +000056PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob,
Fred Drake8844d522001-10-05 21:52:26 +000057 PyObject *callback);
Mark Hammond91a681d2002-08-12 07:21:58 +000058PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob,
Fred Drake8844d522001-10-05 21:52:26 +000059 PyObject *callback);
Mark Hammond91a681d2002-08-12 07:21:58 +000060PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref);
Fred Drake8844d522001-10-05 21:52:26 +000061
Neal Norwitzc5e060d2006-08-02 06:14:22 +000062PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
Fred Drake8844d522001-10-05 21:52:26 +000063
Tim Peters403a2032003-11-20 21:21:46 +000064PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
65
Antoine Pitroud38c9902012-12-08 21:15:26 +010066/* Explanation for the Py_REFCNT() check: when a weakref's target is part
67 of a long chain of deallocations which triggers the trashcan mechanism,
68 clearing the weakrefs can be delayed long after the target's refcount
69 has dropped to zero. In the meantime, code accessing the weakref will
70 be able to "see" the target object even though it is supposed to be
71 unreachable. See issue #16602. */
72
73#define PyWeakref_GET_OBJECT(ref) \
74 (Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \
75 ? ((PyWeakReference *)(ref))->wr_object \
76 : Py_None)
Fred Drake8844d522001-10-05 21:52:26 +000077
78
79#ifdef __cplusplus
80}
81#endif
82#endif /* !Py_WEAKREFOBJECT_H */