blob: 537e7ebf28781222e0afd69b1923b4aa7506c44e [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 */
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000015#ifndef Py_LIMITED_API
Fred Drake8844d522001-10-05 21:52:26 +000016struct _PyWeakReference {
17 PyObject_HEAD
Tim Petersead8b7a2004-10-30 23:09:22 +000018
19 /* The object to which this is a weak reference, or Py_None if none.
20 * Note that this is a stealth reference: wr_object's refcount is
21 * not incremented to reflect this pointer.
22 */
Fred Drake8844d522001-10-05 21:52:26 +000023 PyObject *wr_object;
Tim Petersead8b7a2004-10-30 23:09:22 +000024
25 /* A callable to invoke when wr_object dies, or NULL if none. */
Fred Drake8844d522001-10-05 21:52:26 +000026 PyObject *wr_callback;
Tim Petersead8b7a2004-10-30 23:09:22 +000027
28 /* A cache for wr_object's hash code. As usual for hashes, this is -1
29 * if the hash code isn't known yet.
30 */
Benjamin Peterson8f67d082010-10-17 20:54:53 +000031 Py_hash_t hash;
Tim Petersead8b7a2004-10-30 23:09:22 +000032
33 /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
34 * terminated list of weak references to it. These are the list pointers.
35 * If wr_object goes away, wr_object is set to Py_None, and these pointers
36 * have no meaning then.
37 */
Fred Drake8844d522001-10-05 21:52:26 +000038 PyWeakReference *wr_prev;
39 PyWeakReference *wr_next;
40};
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000041#endif
Fred Drake8844d522001-10-05 21:52:26 +000042
Mark Hammond91a681d2002-08-12 07:21:58 +000043PyAPI_DATA(PyTypeObject) _PyWeakref_RefType;
44PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType;
45PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType;
Fred Drake8844d522001-10-05 21:52:26 +000046
Fred Drake0a4dd392004-07-02 18:57:45 +000047#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType)
48#define PyWeakref_CheckRefExact(op) \
Christian Heimes90aa7642007-12-19 02:45:37 +000049 (Py_TYPE(op) == &_PyWeakref_RefType)
Fred Drake8844d522001-10-05 21:52:26 +000050#define PyWeakref_CheckProxy(op) \
Christian Heimes90aa7642007-12-19 02:45:37 +000051 ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \
52 (Py_TYPE(op) == &_PyWeakref_CallableProxyType))
Fred Drake0a4dd392004-07-02 18:57:45 +000053
54/* This macro calls PyWeakref_CheckRef() last since that can involve a
55 function call; this makes it more likely that the function call
56 will be avoided. */
Fred Drake8844d522001-10-05 21:52:26 +000057#define PyWeakref_Check(op) \
58 (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op))
59
60
Mark Hammond91a681d2002-08-12 07:21:58 +000061PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob,
Fred Drake8844d522001-10-05 21:52:26 +000062 PyObject *callback);
Mark Hammond91a681d2002-08-12 07:21:58 +000063PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob,
Fred Drake8844d522001-10-05 21:52:26 +000064 PyObject *callback);
Mark Hammond91a681d2002-08-12 07:21:58 +000065PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref);
Fred Drake8844d522001-10-05 21:52:26 +000066
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000067#ifndef Py_LIMITED_API
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
Fred Drake8844d522001-10-05 21:52:26 +000069
Tim Peters403a2032003-11-20 21:21:46 +000070PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000071#endif
Tim Peters403a2032003-11-20 21:21:46 +000072
Antoine Pitrou62a0d6e2012-12-08 21:15:26 +010073/* Explanation for the Py_REFCNT() check: when a weakref's target is part
74 of a long chain of deallocations which triggers the trashcan mechanism,
75 clearing the weakrefs can be delayed long after the target's refcount
76 has dropped to zero. In the meantime, code accessing the weakref will
77 be able to "see" the target object even though it is supposed to be
78 unreachable. See issue #16602. */
79
80#define PyWeakref_GET_OBJECT(ref) \
81 (Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \
82 ? ((PyWeakReference *)(ref))->wr_object \
83 : Py_None)
Fred Drake8844d522001-10-05 21:52:26 +000084
85
86#ifdef __cplusplus
87}
88#endif
89#endif /* !Py_WEAKREFOBJECT_H */