summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 360aad6)
raw | patch | inline | side by side (parent: 360aad6)
author | mental <mental@users.sourceforge.net> | |
Wed, 15 Mar 2006 04:07:41 +0000 (04:07 +0000) | ||
committer | mental <mental@users.sourceforge.net> | |
Wed, 15 Mar 2006 04:07:41 +0000 (04:07 +0000) |
ChangeLog | patch | blob | history | |
src/Makefile_insert | patch | blob | history | |
src/display/nr-arena-item.cpp | patch | blob | history | |
src/display/nr-arena-item.h | patch | blob | history | |
src/gc-finalized.h | patch | blob | history | |
src/gc-managed.h | patch | blob | history | |
src/gc-soft-ptr.h | [new file with mode: 0644] | patch | blob |
src/selection.cpp | patch | blob | history | |
src/selection.h | patch | blob | history |
diff --git a/ChangeLog b/ChangeLog
index dbebc8778c12ed0c330de0c65d0f49708251142a..d6a4c057fa77fec46c414d42309fc2b3a434f1d5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
+2006-03-14 MenTaLguY <mental@rydia.net>
+
+ * src/Makefile_insert, src/display/nr-arena-item.cpp,
+ src/display/nr-arena-item.cpp, src/gc-finalized.h, src/gc-managed.h,
+ src/gc-soft-ptr.h, src/selection.h, src/selection.cpp:
+
+ Replace GC::Managed<>::clearOnceInaccessible with GC::soft_ptr<>
+
2006-03-14 MenTaLguY <mental@rydia.net>
* src/debug/event.h, src/debug/gc-heap.h, src/debug/heap.h,
diff --git a/src/Makefile_insert b/src/Makefile_insert
index d42c2fa3bd208eaa0c95556d3271e87b0bd584ef..22c1a2209ca217eedb34819455cec68019a0281a 100644 (file)
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
gc-core.h \
gc-finalized.h \
gc-managed.h \
+ gc-soft-ptr.h \
gc.cpp \
gradient-chemistry.cpp gradient-chemistry.h \
memeq.h \
index ccabe7b2861b0e194dfb709ac1a550a35b810617..e816460b90e494cf88e6a27db732e01f096c36c9 100644 (file)
object_class->cpp_ctor = NRObject::invoke_ctor<NRArenaItem>;
}
-NRArenaItem::NRArenaItem() {
- // clear all reverse-pointing pointers before finalization
- clearOnceInaccessible(&arena);
- clearOnceInaccessible(&parent);
- clearOnceInaccessible(&prev);
-}
-
static void
nr_arena_item_init (NRArenaItem *item)
{
index f43152ff9ba74363d202a532b6acb323b553bbd0..737fed879f916612e67fb4e56d11a47d1db91791 100644 (file)
#include <libnr/nr-rect-l.h>
#include <libnr/nr-pixblock.h>
#include <libnr/nr-object.h>
+#include "gc-soft-ptr.h"
#include "nr-arena-forward.h"
// My testing shows that disabling cache reduces the amount
};
struct NRArenaItem : public NRObject {
- NRArenaItem();
-
- NRArena *arena;
- NRArenaItem *parent;
+ Inkscape::GC::soft_ptr<NRArena> arena;
+ Inkscape::GC::soft_ptr<NRArenaItem> parent;
NRArenaItem *next;
- NRArenaItem *prev;
+ Inkscape::GC::soft_ptr<NRArenaItem> prev;
/* Item state */
unsigned int state : 16;
diff --git a/src/gc-finalized.h b/src/gc-finalized.h
index a31155653e69ba19f45146f82f27847639af3383..046816b60b56581ea68b5dc7912fd4016b3fc60d 100644 (file)
--- a/src/gc-finalized.h
+++ b/src/gc-finalized.h
*
* The best way to limit this effect is to only make "leaf" objects
* (i.e. those that don't point to other finalizaable objects)
- * finalizable, or if the object also derives from GC::Managed<>,
- * use GC::Managed<>::clearOnceInaccessible to register those links
- * to be cleared once the object is made inacecssible (and before it's
- * finalized).
+ * finalizable, and otherwise use GC::soft_ptr<> instead of a regular
+ * pointer for "backreferences" (e.g. parent pointers in a tree
+ * structure), so that those references can be cleared to break any
+ * finalization cycles.
*
- * In a tree structure that has parent links and finalized nodes,
- * you will almost always want to do this with the parent links
- * if you can't avoid having them.
- *
- * @see Inkscape::GC::Managed<>::clearOnceInaccessible
- * @see Inkscape::GC::Managed<>::cancelClearOnceInacessible
+ * @see Inkscape::GC::soft_ptr<>
*
* 2. Because there is no guarantee when the collector will destroy
* objects, there is no guarantee when the destructor will get called.
*
- * It may not get called until the very end of the program, or never.
+ * It may not get called until the very end of the program, or ever.
*
* 3. If allocated in arrays, only the first object in the array will
* have its destructor called, unless you make other arrangements by
diff --git a/src/gc-managed.h b/src/gc-managed.h
index fc13b25134a062084a0d94a3a4cf1e7c612d9daf..80d9c94111a43d226d3d98c54df1a52431de3894 100644 (file)
--- a/src/gc-managed.h
+++ b/src/gc-managed.h
CollectionPolicy default_collect=AUTO>
class Managed {
public:
- /** @brief Registers a pointer to be cleared when this object becomes
- * inaccessible.
- */
- template <typename T>
- void clearOnceInaccessible(T **p_ptr) {
- Core::general_register_disappearing_link(
- reinterpret_cast<void **>(p_ptr), Core::base(this)
- );
- }
-
- /** @brief Cancels the registration of a pointer, so it will not be
- * cleared when this object becomes inacessible.
- */
- template <typename T>
- void cancelClearOnceInaccessible(T **p_ptr) {
- Core::unregister_disappearing_link(
- reinterpret_cast<void **>(p_ptr)
- );
- }
-
void *operator new(std::size_t size,
ScanPolicy scan=default_scan,
CollectionPolicy collect=default_collect)
diff --git a/src/gc-soft-ptr.h b/src/gc-soft-ptr.h
--- /dev/null
+++ b/src/gc-soft-ptr.h
@@ -0,0 +1,74 @@
+/** \file
+ * Inkscape::GC::soft_ptr - "soft" pointers to avoid finalization cycles
+ *
+ * Copyright 2006 MenTaLguY <mental@rydia.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See the file COPYING for details.
+ *
+ */
+
+#ifndef SEEN_INKSCAPE_GC_SOFT_PTR_H
+#define SEEN_INKSCAPE_GC_SOFT_PTR_H
+
+#include "gc-core.h"
+
+namespace Inkscape {
+
+namespace GC {
+
+/** @brief A class for pointers which can be automatically cleared to break
+ * finalization cycles.
+ */
+template <typename T>
+class soft_ptr {
+public:
+ soft_ptr(T * const &pointer=NULL) : _pointer(pointer) {
+ _register();
+ }
+ soft_ptr(soft_ptr const &other) : _pointer(other._pointer) {
+ _register();
+ }
+
+ operator T *() const { return _pointer; }
+ T &operator*() const { return *_pointer; }
+ T *operator->() const { return _pointer; }
+ T &operator[](int i) const { return _pointer[i]; }
+
+ soft_ptr &operator=(T * const &pointer) {
+ _pointer = pointer;
+ return *this;
+ }
+
+ // default copy
+
+private:
+ void _register() {
+ void *base=Core::base(this);
+ if (base) {
+ Core::general_register_disappearing_link((void **)&_pointer, base);
+ }
+ }
+
+ T *_pointer;
+};
+
+}
+
+}
+
+#endif
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/selection.cpp b/src/selection.cpp
index c40b7b546346da91531deac04cb8bc8a53e437e9..09f6a18e3538fe2cb871d3265941dbc34989a7c9 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
_flags(0),
_idle(0)
{
- clearOnceInaccessible(&_desktop);
}
Selection::~Selection() {
diff --git a/src/selection.h b/src/selection.h
index 407854406e32bb023d179bc8ae5e581c778fce64..3c2ec5c3264dd547bab770e15cd9b770f203f367 100644 (file)
--- a/src/selection.h
+++ b/src/selection.h
#include "gc-managed.h"
#include "gc-finalized.h"
#include "gc-anchored.h"
+#include "gc-soft-ptr.h"
#include "util/list.h"
class SPItem;
mutable GSList *_reprs;
mutable GSList *_items;
- SPDesktop *_desktop;
+ GC::soft_ptr<SPDesktop> _desktop;
guint _flags;
guint _idle;