[Zodb-checkins] CVS: Zope3/src/zodb/btrees - BucketTemplate.c:1.3

Tim Peters tim.one@comcast.net
Sat, 11 Jan 2003 01:35:37 -0500


Update of /cvs-repository/Zope3/src/zodb/btrees
In directory cvs.zope.org:/tmp/cvs-serv30402/src/zodb/btrees

Modified Files:
	BucketTemplate.c 
Log Message:
_bucket__p_resolveConflict:  When this detected a bucket split, the
ConflictError got lost because it returned None (by accident, left over
from an earlier loop) instead of NULL.  This bug appears unique to the
Zope3 version.  Also cleared up many things that could go wrong in
internal error cases.

testBucketSplitConflict:  This attempt to produce an insane BTree merely
raises ConflictError now.  But I had to disable the test:

Problem #1:  The ConflictError it raises isn't the ConflictError the test
module imports.  See XXX comment near the end for the flavor of
ConflictError it is raising.

Problem #2:  If this test runs, lots of later tests (in other test
moduoles!) raise 
    TransactionError: Can't join transaction. Status=XYZ

testResolutionBlowsUp in test_conflict also dies like that then, and a
traceback is given in XXX comments before disabled_testBucketSplitConflict.
I don't understand this.  Maybe I need to clean something up.


=== Zope3/src/zodb/btrees/BucketTemplate.c 1.2 => 1.3 ===
--- Zope3/src/zodb/btrees/BucketTemplate.c:1.2	Wed Dec 25 09:12:16 2002
+++ Zope3/src/zodb/btrees/BucketTemplate.c	Sat Jan 11 01:35:04 2003
@@ -1304,49 +1304,50 @@
 static PyObject *
 _bucket__p_resolveConflict(PyObject *ob_type, PyObject *s[3])
 {
-    PyObject *r = NULL, *meth = NULL, *a = NULL;
-    Bucket *b[3];
+    PyObject *result = NULL;	/* guilty until proved innocent */
+    Bucket *b[3] = {NULL, NULL, NULL};
+    PyObject *meth = NULL;
+    PyObject *a = NULL;
     int i;
 
-    for (i=0; i < 3; i++) {
+    for (i = 0; i < 3; i++) {
+	PyObject *r;
+
 	b[i] = (Bucket*)PyObject_CallObject((PyObject *)ob_type, NULL);
-	if (b[i]) {
-	    if (s[i] == Py_None) /* None is equivalent to empty, for BTrees */
-		continue;
-	    meth = PyObject_GetAttr((PyObject *)b[i], __setstate___str);
-	    if (meth == NULL)
-		goto loop_err;
-	    a = PyTuple_New(1);
-	    if (a == NULL)
-		goto loop_err;
-	    PyTuple_SET_ITEM(a, 0, s[i]);
-	    Py_INCREF(s[i]);
-	    r = PyObject_CallObject(meth, a);
-	    Py_DECREF(a);
-	    Py_DECREF(meth);
-	    if (r) {
-		Py_DECREF(r);
-		continue;
-	    }
-	loop_err:
-	    while (--i >= 0)
-		Py_DECREF(b[i]);
-	    Py_XDECREF(a);
-	    Py_XDECREF(meth);
-	    return NULL;
-	}
+	if (b[i] == NULL)
+	    goto Done;
+	if (s[i] == Py_None) /* None is equivalent to empty, for BTrees */
+	    continue;
+	meth = PyObject_GetAttr((PyObject *)b[i], __setstate___str);
+	if (meth == NULL)
+	    goto Done;
+	a = PyTuple_New(1);
+	if (a == NULL)
+	    goto Done;
+	PyTuple_SET_ITEM(a, 0, s[i]);
+	Py_INCREF(s[i]);
+	r = PyObject_CallObject(meth, a);  /* b[i].__setstate__(s[i]) */
+	if (r == NULL)
+	    goto Done;
+	Py_DECREF(r);
+	Py_DECREF(a);
+	Py_DECREF(meth);
+	a = meth = NULL;
     }
 
     if (b[0]->next != b[1]->next || b[0]->next != b[2]->next)
 	merge_error(-1, -1, -1, 0);
     else
-	r = bucket_merge(b[0], b[1], b[2]);
+	result = bucket_merge(b[0], b[1], b[2]);
 
-    Py_DECREF(b[0]);
-    Py_DECREF(b[1]);
-    Py_DECREF(b[2]);
+Done:
+    Py_XDECREF(meth);
+    Py_XDECREF(a);
+    Py_XDECREF(b[0]);
+    Py_XDECREF(b[1]);
+    Py_XDECREF(b[2]);
 
-    return r;
+    return result;
 }
 
 static PyObject *