54
54
* them, but we only hold borrowed references and they may also be destroyed
55
55
* concurrently.
56
56
*
57
- * We can probably solve this by using QSBR to ensure that the memory backing
58
- * either the weakref or the referenced object is not freed until we're ready,
59
- * but for now we've chosen to work around it using a few different strategies:
57
+ * For now we've chosen to address this in a straightforward way:
60
58
*
61
59
* - The weakref's hash is protected using the weakref's per-object lock.
62
60
* - The other mutable is protected by a striped lock owned by the interpreter.
@@ -79,6 +77,7 @@ Py_ssize_t
79
77
_PyWeakref_GetWeakrefCount (PyWeakReference * head )
80
78
{
81
79
Py_ssize_t count = 0 ;
80
+
82
81
while (head != NULL ) {
83
82
++ count ;
84
83
head = head -> wr_next ;
@@ -468,6 +467,12 @@ is_basic_proxy(PyWeakReference *proxy)
468
467
return (proxy -> wr_callback == NULL ) && PyWeakref_CheckProxy (proxy );
469
468
}
470
469
470
+ static int
471
+ is_basic_ref_or_proxy (PyWeakReference * wr )
472
+ {
473
+ return is_basic_ref (wr ) || is_basic_proxy (wr );
474
+ }
475
+
471
476
/* Return the node that `newref` should be inserted after or NULL if `newref`
472
477
* should be inserted at the head of the list.
473
478
*/
@@ -1119,13 +1124,10 @@ PyObject_ClearWeakRefs(PyObject *object)
1119
1124
for (int done = 0 ; !done ;) {
1120
1125
PyObject * callback = NULL ;
1121
1126
LOCK_WEAKREFS (object );
1122
- if (* list != NULL && (* list )-> wr_callback == NULL ) {
1127
+ if (* list != NULL && is_basic_ref_or_proxy (* list )) {
1123
1128
clear_weakref_lock_held (* list , & callback );
1124
- done = (* list == NULL );
1125
- }
1126
- else {
1127
- done = 1 ;
1128
1129
}
1130
+ done = (* list == NULL ) || !is_basic_ref_or_proxy (* list );
1129
1131
UNLOCK_WEAKREFS (object );
1130
1132
Py_XDECREF (callback );
1131
1133
}
@@ -1158,9 +1160,7 @@ PyObject_ClearWeakRefs(PyObject *object)
1158
1160
callback = NULL ;
1159
1161
}
1160
1162
}
1161
- else {
1162
- done = 1 ;
1163
- }
1163
+ done = (* list == NULL );
1164
1164
UNLOCK_WEAKREFS (object );
1165
1165
1166
1166
Py_XDECREF (callback );
0 commit comments