Commit fdd857d0 authored by Jim Fulton's avatar Jim Fulton

Changed the strategy for handling invalidation of classes.

No-longer use setklassstate.  Instead, just call _p_invalidate, as
with any other object.  This changes didn't break any tests, so I
assume that this was untested. :(

Change invalidation to not swallow errors. (Swallowing errors here was a
travesty!)
parent 22f1cb74
...@@ -115,7 +115,6 @@ typedef struct { ...@@ -115,7 +115,6 @@ typedef struct {
int klass_count; /* count of persistent classes */ int klass_count; /* count of persistent classes */
PyObject *data; /* oid -> object dict */ PyObject *data; /* oid -> object dict */
PyObject *jar; /* Connection object */ PyObject *jar; /* Connection object */
PyObject *setklassstate; /* ??? */
int cache_size; /* target number of items in cache */ int cache_size; /* target number of items in cache */
/* Most of the time the ring contains only: /* Most of the time the ring contains only:
...@@ -331,58 +330,51 @@ cc_minimize(ccobject *self, PyObject *args) ...@@ -331,58 +330,51 @@ cc_minimize(ccobject *self, PyObject *args)
return lockgc(self, 0); return lockgc(self, 0);
} }
static void static int
_invalidate(ccobject *self, PyObject *key) _invalidate(ccobject *self, PyObject *key)
{ {
static PyObject *_p_invalidate; static PyObject *_p_invalidate = NULL;
PyObject *v = PyDict_GetItem(self->data, key); PyObject *meth, *v;
v = PyDict_GetItem(self->data, key);
if (v == NULL)
return 0;
if (!_p_invalidate) { if (_p_invalidate == NULL)
{
_p_invalidate = PyString_InternFromString("_p_invalidate"); _p_invalidate = PyString_InternFromString("_p_invalidate");
if (!_p_invalidate) { if (_p_invalidate == NULL)
{
/* It doesn't make any sense to ignore this error, but /* It doesn't make any sense to ignore this error, but
the caller ignores all errors. the caller ignores all errors.
XXX and why does it do that? This should be fixed
*/ */
PyErr_Clear(); return -1;
return; }
} }
}
if (!v) if (v->ob_refcnt <= 1 && PyType_Check(v)) {
return; /* This looks wrong, but it isn't. We use strong references to types
if (PyType_Check(v)) { because they don't have the ring members.
/* This looks wrong, but it isn't. We use strong references to types
because they don't have the ring members. XXX the result is that we *never* remove classes unless
they are modified.
We can fix this by using wekrefs uniformly
*/
self->klass_count--;
return PyDict_DelItem(self->data, key);
}
XXX the result is that we *never* remove classes unless meth = PyObject_GetAttr(v, _p_invalidate);
they are modified. if (meth == NULL)
return -1;
*/ v = PyObject_CallObject(meth, NULL);
if (v->ob_refcnt <= 1) { Py_DECREF(meth);
self->klass_count--; return v == NULL ? -1 : 0;
if (PyDict_DelItem(self->data, key) < 0)
PyErr_Clear();
}
else {
v = PyObject_CallFunction(self->setklassstate, "O", v);
if (v)
Py_DECREF(v);
else
PyErr_Clear();
}
} else {
PyObject *meth, *err;
meth = PyObject_GetAttr(v, _p_invalidate);
if (!meth) {
PyErr_Clear();
return;
}
err = PyObject_CallObject(meth, NULL);
Py_DECREF(meth);
if (!err)
PyErr_Clear();
}
} }
static PyObject * static PyObject *
...@@ -391,16 +383,23 @@ cc_invalidate(ccobject *self, PyObject *inv) ...@@ -391,16 +383,23 @@ cc_invalidate(ccobject *self, PyObject *inv)
PyObject *key, *v; PyObject *key, *v;
int i = 0; int i = 0;
if (PyDict_Check(inv)) { if (PyDict_Check(inv))
{
while (PyDict_Next(inv, &i, &key, &v)) while (PyDict_Next(inv, &i, &key, &v))
_invalidate(self, key); {
if (_invalidate(self, key) < 0)
return NULL;
}
PyDict_Clear(inv); PyDict_Clear(inv);
} }
else { else {
if (PyString_Check(inv)) if (PyString_Check(inv))
_invalidate(self, inv); {
if (_invalidate(self, inv) < 0)
return NULL;
}
else { else {
int l; int l, r;
l = PyObject_Length(inv); l = PyObject_Length(inv);
if (l < 0) if (l < 0)
...@@ -409,8 +408,10 @@ cc_invalidate(ccobject *self, PyObject *inv) ...@@ -409,8 +408,10 @@ cc_invalidate(ccobject *self, PyObject *inv)
key = PySequence_GetItem(inv, i); key = PySequence_GetItem(inv, i);
if (!key) if (!key)
return NULL; return NULL;
_invalidate(self, key); r = _invalidate(self, key);
Py_DECREF(key); Py_DECREF(key);
if (r < 0)
return NULL;
} }
/* XXX Do we really want to modify the input? */ /* XXX Do we really want to modify the input? */
PySequence_DelSlice(inv, 0, l); PySequence_DelSlice(inv, 0, l);
...@@ -669,7 +670,7 @@ cc_init(ccobject *self, PyObject *args, PyObject *kwds) ...@@ -669,7 +670,7 @@ cc_init(ccobject *self, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTuple(args, "O|i", &jar, &cache_size)) if (!PyArg_ParseTuple(args, "O|i", &jar, &cache_size))
return -1; return -1;
self->setklassstate = self->jar = NULL; self->jar = NULL;
self->data = PyDict_New(); self->data = PyDict_New();
if (self->data == NULL) { if (self->data == NULL) {
Py_DECREF(self); Py_DECREF(self);
...@@ -686,11 +687,6 @@ cc_init(ccobject *self, PyObject *args, PyObject *kwds) ...@@ -686,11 +687,6 @@ cc_init(ccobject *self, PyObject *args, PyObject *kwds)
non-ghost objects. non-ghost objects.
*/ */
PyObject_GC_UnTrack((void *)self->data); PyObject_GC_UnTrack((void *)self->data);
self->setklassstate = PyObject_GetAttrString(jar, "setklassstate");
if (self->setklassstate == NULL) {
Py_DECREF(self);
return -1;
}
self->jar = jar; self->jar = jar;
Py_INCREF(jar); Py_INCREF(jar);
self->cache_size = cache_size; self->cache_size = cache_size;
...@@ -708,7 +704,6 @@ cc_dealloc(ccobject *self) ...@@ -708,7 +704,6 @@ cc_dealloc(ccobject *self)
{ {
Py_XDECREF(self->data); Py_XDECREF(self->data);
Py_XDECREF(self->jar); Py_XDECREF(self->jar);
Py_XDECREF(self->setklassstate);
PyObject_GC_Del(self); PyObject_GC_Del(self);
} }
...@@ -755,7 +750,6 @@ cc_clear(ccobject *self) ...@@ -755,7 +750,6 @@ cc_clear(ccobject *self)
} }
Py_XDECREF(self->jar); Py_XDECREF(self->jar);
Py_XDECREF(self->setklassstate);
while (PyDict_Next(self->data, &pos, &k, &v)) { while (PyDict_Next(self->data, &pos, &k, &v)) {
Py_INCREF(v); Py_INCREF(v);
...@@ -765,7 +759,6 @@ cc_clear(ccobject *self) ...@@ -765,7 +759,6 @@ cc_clear(ccobject *self)
Py_XDECREF(self->data); Py_XDECREF(self->data);
self->data = NULL; self->data = NULL;
self->jar = NULL; self->jar = NULL;
self->setklassstate = NULL;
return 0; return 0;
} }
...@@ -794,7 +787,6 @@ cc_traverse(ccobject *self, visitproc visit, void *arg) ...@@ -794,7 +787,6 @@ cc_traverse(ccobject *self, visitproc visit, void *arg)
} }
VISIT(self->jar); VISIT(self->jar);
VISIT(self->setklassstate);
here = self->ring_home.r_next; here = self->ring_home.r_next;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment