[Python-checkins] CVS: python/dist/src/Objects weakrefobject.c,1.6,1.7
Fred L. Drake
fdrake@users.sourceforge.net
Mon, 10 Dec 2001 15:44:57 -0800
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv25850/Objects
Modified Files:
weakrefobject.c
Log Message:
Make sure that when we invoke callback functions associated with weak
references, we do not allow any outstanding exceptions "leak" into the
callback's execution state.
This closes SF bug #478534.
Index: weakrefobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** weakrefobject.c 2001/11/28 21:01:56 1.6
--- weakrefobject.c 2001/12/10 23:44:54 1.7
***************
*** 656,662 ****
! /* This is the implementation of the PyObject_ClearWeakRefs() function; it
! * is installed in the init_weakref() function. It is called by the
! * tp_dealloc handler to clear weak references.
*
* This iterates through the weak references for 'object' and calls callbacks
--- 656,671 ----
! static void
! handle_callback(PyWeakReference *ref, PyObject *callback)
! {
! PyObject *cbresult = PyObject_CallFunction(callback, "O", ref);
!
! if (cbresult == NULL)
! PyErr_WriteUnraisable(callback);
! else
! Py_DECREF(cbresult);
! }
!
! /* This function is called by the tp_dealloc handler to clear weak references.
*
* This iterates through the weak references for 'object' and calls callbacks
***************
*** 683,705 ****
}
if (*list != NULL) {
! int count = _PyWeakref_GetWeakrefCount(*list);
if (count == 1) {
- PyWeakReference *current = *list;
PyObject *callback = current->wr_callback;
- PyObject *cbresult;
! Py_INCREF(callback);
clear_weakref(current);
! cbresult = PyObject_CallFunction(callback, "O", current);
! if (cbresult == NULL)
! PyErr_WriteUnraisable(callback);
! else
! Py_DECREF(cbresult);
Py_DECREF(callback);
}
else {
PyObject *tuple = PyTuple_New(count * 2);
- PyWeakReference *current = *list;
int i = 0;
--- 692,712 ----
}
if (*list != NULL) {
! PyWeakReference *current = *list;
! int count = _PyWeakref_GetWeakrefCount(current);
! int restore_error = PyErr_Occurred() ? 1 : 0;
! PyObject *err_type, *err_value, *err_tb;
+ if (restore_error)
+ PyErr_Fetch(&err_type, &err_value, &err_tb);
if (count == 1) {
PyObject *callback = current->wr_callback;
! current->wr_callback = NULL;
clear_weakref(current);
! handle_callback(current, callback);
Py_DECREF(callback);
}
else {
PyObject *tuple = PyTuple_New(count * 2);
int i = 0;
***************
*** 711,715 ****
PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
current->wr_callback = NULL;
- next = current->wr_next;
clear_weakref(current);
current = next;
--- 718,721 ----
***************
*** 718,730 ****
PyObject *current = PyTuple_GET_ITEM(tuple, i * 2);
PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
! PyObject *cbresult = PyObject_CallFunction(callback, "O",
! current);
! if (cbresult == NULL)
! PyErr_WriteUnraisable(callback);
! else
! Py_DECREF(cbresult);
}
Py_DECREF(tuple);
}
}
}
--- 724,734 ----
PyObject *current = PyTuple_GET_ITEM(tuple, i * 2);
PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
!
! handle_callback((PyWeakReference *)current, callback);
}
Py_DECREF(tuple);
}
+ if (restore_error)
+ PyErr_Restore(err_type, err_value, err_tb);
}
}