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;
if (PyType_Check(v)) {
/* This looks wrong, but it isn't. We use strong references to types /* This looks wrong, but it isn't. We use strong references to types
because they don't have the ring members. because they don't have the ring members.
XXX the result is that we *never* remove classes unless XXX the result is that we *never* remove classes unless
they are modified. they are modified.
We can fix this by using wekrefs uniformly
*/ */
if (v->ob_refcnt <= 1) {
self->klass_count--; self->klass_count--;
if (PyDict_DelItem(self->data, key) < 0) return PyDict_DelItem(self->data, key);
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); meth = PyObject_GetAttr(v, _p_invalidate);
if (!meth) { if (meth == NULL)
PyErr_Clear(); return -1;
return;
} v = PyObject_CallObject(meth, NULL);
err = PyObject_CallObject(meth, NULL);
Py_DECREF(meth); Py_DECREF(meth);
if (!err) return v == NULL ? -1 : 0;
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