summaryrefslogtreecommitdiff
path: root/src/context
diff options
context:
space:
mode:
authorMorgan Deters <mdeters@gmail.com>2010-05-26 18:02:59 +0000
committerMorgan Deters <mdeters@gmail.com>2010-05-26 18:02:59 +0000
commit055a2a6ac0a2aa8f8c2e031755eca3347164b9df (patch)
treed8eb638bf8d448b3f0c569ff94d8ad1ff3964a8d /src/context
parentcb5cc82b18503783f4433170bbd61b4db752a6dc (diff)
CDMap: fix bug 130
Diffstat (limited to 'src/context')
-rw-r--r--src/context/cdmap.h29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/context/cdmap.h b/src/context/cdmap.h
index 9be4de19b..d4e2e0d28 100644
--- a/src/context/cdmap.h
+++ b/src/context/cdmap.h
@@ -43,6 +43,8 @@ inline std::ostream& operator<<(std::ostream& out, const std::pair<T, U>& p) {
template <class Key, class Data, class HashFcn = __gnu_cxx::hash<Key> >
class CDOmap : public ContextObj {
+ friend class CDMap<Key, Data, HashFcn>;
+
Key d_key;
Data d_data;
CDMap<Key, Data, HashFcn>* d_map;
@@ -67,7 +69,15 @@ class CDOmap : public ContextObj {
//
// FIXME multithreading
if(d_map->d_first == this) {
- d_map->d_first = d_next;
+ Debug("gc") << "remove first-elem " << this << " from map " << d_map << " with next-elem " << d_next << std::endl;
+ if(d_next == this) {
+ Assert(d_prev == this);
+ d_map->d_first = NULL;
+ } else {
+ d_map->d_first = d_next;
+ }
+ } else {
+ Debug("gc") << "remove nonfirst-elem " << this << " from map " << d_map << std::endl;
}
d_next->d_prev = d_prev;
d_prev->d_next = d_next;
@@ -98,10 +108,13 @@ public:
CDOmap*& first = d_map->d_first;
if(first == NULL) {
first = d_next = d_prev = this;
+ Debug("gc") << "add first-elem " << this << " to map " << d_map << std::endl;
} else {
+ Debug("gc") << "add nonfirst-elem " << this << " to map " << d_map << " with first-elem " << first << "[" << first->d_prev << " " << first->d_next << std::endl;
d_prev = first->d_prev;
d_next = first;
- d_prev->d_next = first->d_prev = this;
+ d_prev->d_next = this;
+ first->d_prev = this;
}
}
@@ -286,7 +299,19 @@ public:
// never gets a NULL map and so they leak.
if(j != d_map.end()) {
Element* elt = (*j).second;
+ if(d_first == elt) {
+ if(elt->d_next == elt) {
+ Assert(elt->d_prev == elt);
+ d_first = NULL;
+ } else {
+ d_first = elt->d_next;
+ }
+ } else {
+ elt->d_prev->d_next = elt->d_next;
+ elt->d_next->d_prev = elt->d_prev;
+ }
d_map.erase(j);//FIXME multithreading
+ Debug("gc") << "key " << k << " obliterated zero-scope: " << elt << std::endl;
// was already destructed, so don't call ->deleteSelf()
::operator delete(elt);
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback