Code

Replace GC::Managed<>::clearOnceInaccessible with GC::soft_ptr<>
authormental <mental@users.sourceforge.net>
Wed, 15 Mar 2006 04:07:41 +0000 (04:07 +0000)
committermental <mental@users.sourceforge.net>
Wed, 15 Mar 2006 04:07:41 +0000 (04:07 +0000)
ChangeLog
src/Makefile_insert
src/display/nr-arena-item.cpp
src/display/nr-arena-item.h
src/gc-finalized.h
src/gc-managed.h
src/gc-soft-ptr.h [new file with mode: 0644]
src/selection.cpp
src/selection.h

index dbebc8778c12ed0c330de0c65d0f49708251142a..d6a4c057fa77fec46c414d42309fc2b3a434f1d5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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,
index d42c2fa3bd208eaa0c95556d3271e87b0bd584ef..22c1a2209ca217eedb34819455cec68019a0281a 100644 (file)
@@ -228,6 +228,7 @@ libinkpost_a_SOURCES =      \
        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)
@@ -63,13 +63,6 @@ nr_arena_item_class_init (NRArenaItemClass *klass)
        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)
@@ -56,6 +56,7 @@
 #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 
@@ -70,12 +71,10 @@ struct NRGC {
 };
 
 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;
index a31155653e69ba19f45146f82f27847639af3383..046816b60b56581ea68b5dc7912fd4016b3fc60d 100644 (file)
@@ -40,22 +40,17 @@ namespace GC {
  *
  *      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
index fc13b25134a062084a0d94a3a4cf1e7c612d9daf..80d9c94111a43d226d3d98c54df1a52431de3894 100644 (file)
@@ -28,26 +28,6 @@ template <ScanPolicy default_scan=SCANNED,
           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
new file mode 100644 (file)
index 0000000..a055ba3
--- /dev/null
@@ -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 :
index c40b7b546346da91531deac04cb8bc8a53e437e9..09f6a18e3538fe2cb871d3265941dbc34989a7c9 100644 (file)
@@ -39,7 +39,6 @@ Selection::Selection(SPDesktop *desktop) :
     _flags(0),
     _idle(0)
 {
-    clearOnceInaccessible(&_desktop);
 }
 
 Selection::~Selection() {
index 407854406e32bb023d179bc8ae5e581c778fce64..3c2ec5c3264dd547bab770e15cd9b770f203f367 100644 (file)
@@ -25,6 +25,7 @@
 #include "gc-managed.h"
 #include "gc-finalized.h"
 #include "gc-anchored.h"
+#include "gc-soft-ptr.h"
 #include "util/list.h"
 
 class SPItem;
@@ -324,7 +325,7 @@ private:
     mutable GSList *_reprs;
     mutable GSList *_items;
 
-    SPDesktop *_desktop;
+    GC::soft_ptr<SPDesktop> _desktop;
     guint _flags;
     guint _idle;