[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);
      }
  }