Author: rolf
Date: 2007-08-30 15:02:25 -0400 (Thu, 30 Aug 2007)
New Revision: 85065
Added:
trunk/moon/src/debug.cpp
trunk/moon/src/debug.h
Modified:
trunk/moon/ChangeLog
trunk/moon/moon.mdp
trunk/moon/plugin/ChangeLog
trunk/moon/plugin/downloader.cpp
trunk/moon/plugin/plugin-class.cpp
trunk/moon/plugin/plugin-class.h
trunk/moon/plugin/plugin-glue.cpp
trunk/moon/src/ChangeLog
trunk/moon/src/Makefile.am
trunk/moon/src/animation.cpp
trunk/moon/src/animation.h
trunk/moon/src/clock.cpp
trunk/moon/src/dependencyobject.cpp
trunk/moon/src/dependencyobject.h
trunk/moon/src/runtime.cpp
trunk/moon/src/type.cpp
trunk/moon/src/type.cpp.in
trunk/moon/src/xaml.cpp
Log:
* src/xaml.cpp: Unref the namescope.
* src/debug.h, src/debug.cpp: Added. Implemented get_stack_trace and
print_stack_trace.
* src/clock.cpp: Unref the _instance.
* src/dependencyobject.h, src/dependencyobject.cpp: Implement object
tracking for debug purposes. It's able to log to console object
creation, destruction, ref/unrefs with a stacktrace with C++
unmangled function names, file and line number. Keep a count of
created and destroyed objects, and a list of objects still alive.
Ref and unref attached objects, and free the attachees when we're
deleted.
* src/animation.h, src/animation.cpp: Add animation_destroy, and
destroy the default dependency property for a few properties.
* src/type.cpp, src/type.cpp.in: Initialize Type::types to NULL.
* src/runtime.cpp: Add a g_type_inited to avoid initializing g_types
several types. Call animation_destroy on shutdown, and add some
object tracking output to runtime_init and runtime_shutdown.
* src/Makefile.am, moon.mdp: Added debug.*.
* plugin/downloader.cpp: Added downloader_destroy.
* plugin/plugin-class.cpp, plugin/plugin-class.h: Add
plugin_destroy_classes, and remove a duplicate creation of
MoonlightPointClass.
* plugin/plugin-glue.cpp: Try shutting down everything correctly, if it
can be shutdown, if not, don't initialize twice (vm and gtk).
Modified: trunk/moon/ChangeLog
===================================================================
--- trunk/moon/ChangeLog 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/ChangeLog 2007-08-30 19:02:25 UTC (rev 85065)
@@ -1,3 +1,7 @@
+2007-08-30 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
+
+ * moon.mdp: Added debug.*.
+
2007-08-29 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
* moon.mdp, moon.mds: Created a MonoDevelop project with the source
files.
Modified: trunk/moon/moon.mdp
===================================================================
--- trunk/moon/moon.mdp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/moon.mdp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -168,6 +168,8 @@
<File name="./TODO" subtype="Code" buildaction="Nothing" />
<File name="./wishlist" subtype="Code" buildaction="Nothing" />
<File name="./AUTHORS" subtype="Code" buildaction="Nothing" />
+ <File name="./src/debug.cpp" subtype="Code" buildaction="Nothing" />
+ <File name="./src/debug.h" subtype="Code" buildaction="Nothing" />
</Contents>
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True"
RelativeMakefileName="./Makefile.am" BuildTargetName="install"
IsAutotoolsProject="True" RelativeConfigureInPath="./">
<BuildFilesVar />
Modified: trunk/moon/plugin/ChangeLog
===================================================================
--- trunk/moon/plugin/ChangeLog 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/plugin/ChangeLog 2007-08-30 19:02:25 UTC (rev 85065)
@@ -1,3 +1,11 @@
+2007-08-30 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
+
+ * downloader.cpp: Added downloader_destroy.
+ * plugin-class.cpp, plugin-class.h: Add plugin_destroy_classes, and
remove a
+ duplicate creation of MoonlightPointClass.
+ * plugin-glue.cpp: Try shutting down everything correctly, if it can be
+ shutdown, if not, don't initialize twice (vm and gtk).
+
2007-08-29 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
* plugin-class.cpp: Javascript expects the sender of a FullScreenChange
Modified: trunk/moon/plugin/downloader.cpp
===================================================================
--- trunk/moon/plugin/downloader.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/plugin/downloader.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -110,3 +110,7 @@
p_downloader_abort);
}
+void
+downloader_destroy ()
+{
+}
\ No newline at end of file
Modified: trunk/moon/plugin/plugin-class.cpp
===================================================================
--- trunk/moon/plugin/plugin-class.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/plugin/plugin-class.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -3370,9 +3370,36 @@
MoonlightStoryboardClass = new MoonlightStoryboardType ();
MoonlightTextBlockClass = new MoonlightTextBlockType ();
MoonlightRectClass = new MoonlightRectType ();
- MoonlightPointClass = new MoonlightPointType ();
MoonlightDurationClass = new MoonlightDurationType ();
MoonlightTimeSpanClass = new MoonlightTimeSpanType ();
MoonlightEventListenerClass = new MoonlightEventListenerType ();
}
+void
+plugin_destroy_classes ()
+{
+
+ delete MoonlightCollectionClass; MoonlightCollectionClass = NULL;
+ delete MoonlightContentClass; MoonlightContentClass = NULL;
+ delete MoonlightControlClass; MoonlightControlClass = NULL;
+ delete MoonlightEventObjectClass; MoonlightEventObjectClass = NULL;
+ delete MoonlightDependencyObjectClass; MoonlightDependencyObjectClass =
NULL;
+ delete MoonlightDownloaderClass; MoonlightDownloaderClass = NULL;
+ delete MoonlightErrorEventArgsClass; MoonlightErrorEventArgsClass =
NULL;
+ delete MoonlightImageBrushClass; MoonlightImageBrushClass = NULL;
+ delete MoonlightImageClass; MoonlightImageClass = NULL;
+ delete MoonlightMediaElementClass; MoonlightMediaElementClass = NULL;
+ delete MoonlightMouseEventArgsClass; MoonlightMouseEventArgsClass =
NULL;
+ delete MoonlightKeyboardEventArgsClass; MoonlightKeyboardEventArgsClass
= NULL;
+ delete MoonlightObjectClass; MoonlightObjectClass = NULL;
+ delete MoonlightScriptableObjectClass; MoonlightScriptableObjectClass =
NULL;
+ delete MoonlightScriptControlClass; MoonlightScriptControlClass = NULL;
+ delete MoonlightSettingsClass; MoonlightSettingsClass = NULL;
+ delete MoonlightStoryboardClass; MoonlightStoryboardClass = NULL;
+ delete MoonlightTextBlockClass; MoonlightTextBlockClass = NULL;
+ delete MoonlightRectClass; MoonlightRectClass = NULL;
+ delete MoonlightPointClass; MoonlightPointClass = NULL;
+ delete MoonlightDurationClass; MoonlightDurationClass = NULL;
+ delete MoonlightTimeSpanClass; MoonlightTimeSpanClass = NULL;
+ delete MoonlightEventListenerClass; MoonlightEventListenerClass = NULL;
+}
Modified: trunk/moon/plugin/plugin-class.h
===================================================================
--- trunk/moon/plugin/plugin-class.h 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/plugin/plugin-class.h 2007-08-30 19:02:25 UTC (rev 85065)
@@ -19,6 +19,7 @@
void plugin_init_classes (void);
+void plugin_destroy_classes (void);
/*** EventListenerProxy */
typedef void (*EventArgsWrapper)(NPP instance, gpointer calldata, NPVariant
*value);
Modified: trunk/moon/plugin/plugin-glue.cpp
===================================================================
--- trunk/moon/plugin/plugin-glue.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/plugin/plugin-glue.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -180,23 +180,33 @@
}
void downloader_initialize ();
+void downloader_destroy ();
+static bool vm_initialized = false;
+static bool gtk_initialized = false;
static bool already_initialized = false;
+static bool runtime_initialized = false;
NPError
NPP_Initialize (void)
{
// We dont need to initialize mono vm and gtk more than one time.
- if (!already_initialized) {
- already_initialized = true;
+ if (!gtk_initialized) {
+ gtk_initialized = true;
gtk_init (0, 0);
- downloader_initialize ();
+ }
+ if (!vm_initialized) {
+ vm_initialized = true;
vm_init ();
+ }
+ downloader_initialize ();
+
+ if (!runtime_initialized) {
+ runtime_initialized = true;
runtime_init ();
-
- plugin_init_classes ();
}
- TimeManager::Instance()->Start();
+
+ plugin_init_classes ();
return NPERR_NO_ERROR;
}
@@ -204,8 +214,11 @@
void
NPP_Shutdown (void)
{
+ plugin_destroy_classes ();
// runtime_shutdown is broken at moment so let us just shutdown
TimeManager,
// when fixed please uncomment above line and remove time manger
shutdown.
- //runtime_shutdown ();
- TimeManager::Instance()->Shutdown ();
+ runtime_shutdown ();
+ //TimeManager::Instance()->Shutdown ();
+ runtime_initialized = false;
+ downloader_destroy ();
}
Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/ChangeLog 2007-08-30 19:02:25 UTC (rev 85065)
@@ -1,3 +1,23 @@
+2007-08-30 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
+
+ * xaml.cpp: Unref the namescope.
+ * debug.h, debug.cpp: Added. Implemented get_stack_trace and
+ print_stack_trace.
+ * clock.cpp: Unref the _instance.
+ * dependencyobject.h, dependencyobject.cpp: Implement object tracking
for
+ debug purposes. It's able to log to console object creation,
+ destruction, ref/unrefs with a stacktrace with C++ unmangled function
+ names, file and line number. Keep a count of created and destroyed
+ objects, and a list of objects still alive. Ref and unref attached
+ objects, and free the attachees when we're deleted.
+ * animation.h, animation.cpp: Add animation_destroy, and destroy the
default
+ dependency property for a few properties.
+ * type.cpp, type.cpp.in: Initialize Type::types to NULL.
+ * runtime.cpp: Add a g_type_inited to avoid initializing g_types several
+ types. Call animation_destroy on shutdown, and add some object
tracking
+ output to runtime_init and runtime_shutdown.
+ * Makefile.am: Added debug.*.
+
2007-08-30 Sebastien Pouliot <[EMAIL PROTECTED]>
* shape.cpp: In some degenerate cases Radius[X|Y] can be ignored
Modified: trunk/moon/src/Makefile.am
===================================================================
--- trunk/moon/src/Makefile.am 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/Makefile.am 2007-08-30 19:02:25 UTC (rev 85065)
@@ -15,6 +15,7 @@
clock.h \
collection.h \
control.h \
+ debug.h \
dependencyobject.h \
downloader.h \
error.h \
@@ -53,6 +54,7 @@
clock.cpp \
collection.cpp \
control.cpp \
+ debug.cpp \
dependencyobject.cpp \
dirty.h \
dirty.cpp \
Modified: trunk/moon/src/animation.cpp
===================================================================
--- trunk/moon/src/animation.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/animation.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -1612,6 +1612,13 @@
PointAnimationUsingKeyFrames::KeyFramesProperty =
DependencyObject::Register (Type::POINTANIMATIONUSINGKEYFRAMES, "KeyFrames",
Type::POINTKEYFRAME_COLLECTION);
}
+void
+animation_destroy ()
+{
+
SplineDoubleKeyFrame::KeySplineProperty->default_value->AsDependencyObject
()->unref ();
+
SplineColorKeyFrame::KeySplineProperty->default_value->AsDependencyObject
()->unref ();
+
SplinePointKeyFrame::KeySplineProperty->default_value->AsDependencyObject
()->unref ();
+}
/* The nullable setters/getters for the various animation types */
SET_NULLABLE_FUNC(double)
Modified: trunk/moon/src/animation.h
===================================================================
--- trunk/moon/src/animation.h 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/animation.h 2007-08-30 19:02:25 UTC (rev 85065)
@@ -612,6 +612,7 @@
void animation_init (void);
+void animation_destroy (void);
G_END_DECLS
Modified: trunk/moon/src/clock.cpp
===================================================================
--- trunk/moon/src/clock.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/clock.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -121,6 +121,9 @@
}
child_clocks = NULL;
+
+ _instance->unref ();
+ _instance = NULL;
}
gboolean
Added: trunk/moon/src/debug.cpp
===================================================================
--- trunk/moon/src/debug.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/debug.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -0,0 +1,234 @@
+/*
+ * debug.cpp:
+ *
+ * Copyright 2007 Novell, Inc. (http://www.novell.com)
+ *
+ * See the LICENSE file included with the distribution for details.
+ *
+ */
+
+#include "debug.h"
+
+#if STACK_DEBUG
+
+char* get_stack_trace ()
+{
+ return get_stack_trace_prefix ("\t");
+}
+void print_stack_trace ()
+{
+ print_stack_trace_prefix ("\t");
+}
+
+typedef struct Addr2LineData Addr2LineData;
+
+struct Addr2LineData {
+ Addr2LineData *next;
+ FILE *pipein;
+ FILE *pipeout;
+ char *binary;
+ int child_pid;
+ gpointer base;
+};
+
+static Addr2LineData *addr2line_pipes = NULL;
+
+static char*
+library_of_ip (gpointer ip, gpointer* base_address)
+{
+ /* non-linux platforms will need different code here */
+
+ FILE* maps = fopen ("/proc/self/maps", "r");
+ char * buffer = NULL;
+ size_t buffer_length = 0;
+ char* result = NULL;
+ char* current_library = NULL;
+ gpointer current_base_address = NULL;
+ gpointer start, end;
+
+ while (true) {
+ gint64 buffer_read = getline (&buffer, &buffer_length, maps);
+
+ if (buffer_read < 0)
+ break;
+
+ if (buffer_read < 20)
+ continue;
+
+ buffer [buffer_read - 1] = 0; // Strip off the newline.
+
+ const char delimiters[] = " ";
+ char* range = strtok (buffer, delimiters);
+ char* dummy = strtok (NULL, delimiters);
+ dummy = strtok (NULL, delimiters);
+ dummy = strtok (NULL, delimiters);
+ dummy = strtok (NULL, delimiters);
+ char* lib = strtok (NULL, delimiters);
+
+ if (lib == NULL) {
+ current_library = NULL;
+ continue;
+ }
+
+ char* start_range = strtok (range, "-");
+ char* end_range = strtok (NULL, "-");
+
+ char* tail;
+ start = (gpointer) strtoull (start_range, &tail, 16);
+ end = (gpointer) strtoull (end_range, &tail, 16);
+
+ if (current_library == NULL || strcmp (lib, current_library) !=
0) {
+ current_library = lib;
+ current_base_address = start;
+ }
+
+ if (start <= ip && end >= ip) {
+ result = g_strdup (lib);
+ *base_address = current_base_address;
+ // printf ("IP %p is in library %s\n", ip, result);
+ break;
+ }
+ }
+
+ free (buffer);
+ fclose (maps);
+
+ return result;
+}
+
+
+static char*
+addr2line (gpointer ip)
+{
+ char *res;
+ Addr2LineData *addr2line;
+ gpointer base_address;
+
+ char* binary = library_of_ip (ip, &base_address);
+
+ if (binary == NULL)
+ return NULL;
+
+ for (addr2line = addr2line_pipes; addr2line; addr2line =
addr2line->next) {
+ if (strcmp (binary, addr2line->binary) == 0)
+ break;
+ }
+
+ if (!addr2line) {
+ const char *addr_argv[] = {"addr2line", "-f", "-e", binary,
"-C", NULL};
+ int child_pid;
+ int ch_in, ch_out;
+
+ if (!g_spawn_async_with_pipes (NULL, (char**)addr_argv, NULL,
G_SPAWN_SEARCH_PATH, NULL, NULL,
+ &child_pid, &ch_in, &ch_out, NULL, NULL)) {
+ return g_strdup (binary);
+ }
+
+ addr2line = g_new0 (Addr2LineData, 1);
+ addr2line->base = base_address;
+ addr2line->child_pid = child_pid;
+ addr2line->binary = g_strdup (binary);
+ addr2line->pipein = fdopen (ch_in, "w");
+ addr2line->pipeout = fdopen (ch_out, "r");
+ addr2line->next = addr2line_pipes;
+ addr2line_pipes = addr2line;
+ }
+
+ gpointer offset;
+ offset = (gpointer) (((size_t) ip) - ((size_t) addr2line->base));
+
+ // printf ("Checking ip: %p, offset: %p, base: %p\n", ip, offset,
addr2line->base);
+ fprintf (addr2line->pipein, "%p\n", offset);
+ fflush (addr2line->pipein);
+
+ /* we first get the func name and then file:lineno in a second line */
+ char buf [1024];
+ char* first;
+ char* second;
+ char* result;
+ int result_length;
+
+ result = fgets (buf, sizeof (buf), addr2line->pipeout);
+
+ if (result == NULL)
+ return g_strdup (binary);
+
+ if (result [0] == '?' || result [0] == 0)
+ return g_strdup (binary);
+
+ result_length = strlen (result);
+ result [result_length - 1] = 0;
+ first = result;
+
+ result = fgets (buf + result_length, sizeof (buf) - result_length,
addr2line->pipeout);
+
+ if (result == NULL)
+ return g_strdup (first);
+
+ result_length = strlen (result);
+ result [result_length - 1] = 0;
+ second = result;
+
+ res = g_strdup_printf ("%s [%p] %s %s", addr2line->binary, ip, first,
second);
+
+ // printf ("Final result: %s\n", res);
+
+ return res;
+}
+
+char*
+get_stack_trace_prefix (const char* prefix)
+{
+ int address_count;
+ gpointer ip;
+ int total_length = 0;
+ int prefix_length = strlen (prefix);
+ void *ips [MAX_STACK_FRAMES];
+ char *frames [MAX_STACK_FRAMES];
+ char **names;
+
+ address_count = backtrace (ips, MAX_STACK_FRAMES);
+
+ for (int i = 2; i < address_count; i++) {
+ ip = ips [i];
+
+ char* frame = addr2line (ip);
+
+ if (frame == NULL || strlen (frame) == 0 || strcmp ("??",
frame) == 0) {
+ g_free (frame);
+ names = backtrace_symbols (&ip, 1);
+ frame = g_strdup (names [0]);
+ free (names);
+ }
+ frames [i] = frame;
+ total_length += prefix_length + strlen (frame) + 1;
+ }
+
+ char* result = (char*) g_malloc0 (total_length);
+ int position = 0;
+ for (int i = 2; i < address_count; i++) {
+ char* frame = frames [i];
+ size_t frame_length = strlen (frame);
+
+ memcpy (result + position, prefix, prefix_length);
+ position += prefix_length;
+ memcpy (result + position, frame, frame_length);
+ position += frame_length;
+ memcpy (result + position, "\n", 1);
+ position ++;
+
+ g_free (frame);
+ }
+
+ return result;
+}
+
+void
+print_stack_trace_prefix (const char* prefix)
+{
+ char* st = get_stack_trace_prefix (prefix);
+ printf (st);
+ g_free (st);
+}
+
+#endif
Added: trunk/moon/src/debug.h
===================================================================
--- trunk/moon/src/debug.h 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/debug.h 2007-08-30 19:02:25 UTC (rev 85065)
@@ -0,0 +1,38 @@
+/*
+ * debug.h:
+ *
+ * Copyright 2007 Novell, Inc. (http://www.novell.com)
+ *
+ * See the LICENSE file included with the distribution for details.
+ *
+ */
+
+#ifndef __MONOLIGHT_DEBUG_H__
+#define __MONOLIGHT_DEBUG_H__
+
+// Define STACK_DEBUG here to enable debugging with stack frames.
+// Object tracking depends on this being defined in order to work.
+
+#define STACK_DEBUG 0
+
+#if STACK_DEBUG
+
+#include <glib.h>
+#include <unistd.h>
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_STACK_FRAMES 15
+
+char* get_stack_trace_prefix (const char* prefix);
+void print_stack_trace_prefix (const char* prefix);
+
+char* get_stack_trace ();
+void print_stack_trace ();
+
+#endif
+
+#endif
+
Modified: trunk/moon/src/dependencyobject.cpp
===================================================================
--- trunk/moon/src/dependencyobject.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/dependencyobject.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -8,7 +8,6 @@
*/
#include <config.h>
-
#include <stdio.h>
#include <stdlib.h>
@@ -19,14 +18,45 @@
#include "collection.h"
#include "dependencyobject.h"
+#if OBJECT_TRACKING
+// Define the ID of the object you want to track
+// Object creation, destruction and all ref/unrefs
+// are logged to the console, with a stacktrace.
+#define OBJECT_TRACK_ID 23
+
+int Base::objects_created = 0;
+int Base::objects_destroyed = 0;
+GList* Base::objects_alive = NULL;
+
+void
+Base::Track (const char* done, const char* typname)
+{
+#if OBJECT_TRACK_ID
+ if (id == OBJECT_TRACK_ID) {
+ printf ("%s tracked object of type '%s': %i, current refcount:
%i\n", done, typname, id, refcount);
+ PrintStackTrace ();
+ }
+#endif
+}
+
+char*
+Base::GetStackTrace (const char* prefix)
+{
+ return get_stack_trace_prefix (prefix);
+}
+
+void
+Base::PrintStackTrace ()
+{
+ print_stack_trace ();
+}
+
void
Base::ref ()
{
refcount++;
-
-#if DEBUG_REFCNT
- printf ("refcount++ %p (%s), refcnt = %d\n", this, GetTypeName (),
refcount);
-#endif
+
+ Track ("Ref", GetTypeName ());
}
void
@@ -34,18 +64,28 @@
{
refcount--;
-#if DEBUG_REFCNT
- printf ("refcount-- %p (%s), refcnt = %d\n", this, GetTypeName
(), refcount);
-#endif
+ Track ("Unref", GetTypeName ());
if (refcount == 0) {
-#if DEBUG_REFCNT
- printf ("destroying object %p (%s)\n", this, GetTypeName ());
-#endif
delete this;
}
}
+Base::Base () : refcount(1)
+{
+ id = ++objects_created;
+ objects_alive = g_list_prepend (objects_alive, this);
+ Track ("Created", "");
+}
+
+Base::~Base ()
+{
+ objects_destroyed++;
+ objects_alive = g_list_remove (objects_alive, this);
+ Track ("Destroyed", "");
+}
+#endif
+
void
base_ref (Base *base)
{
@@ -75,6 +115,7 @@
{
Attachee *att = new Attachee ();
att->dob = container;
+ att->dob->ref ();
att->prop = property;
attached_list = g_slist_append (attached_list, att);
}
@@ -87,6 +128,7 @@
if (att->dob == container && att->prop == property) {
attached_list = g_slist_remove_link (attached_list, l);
+ att->dob->unref ();
delete att;
break;
}
@@ -305,9 +347,18 @@
return Type::DEPENDENCY_OBJECT;
}
+void free_attachee (gpointer data, gpointer user_data)
+{
+ delete (Attachee*) data;
+}
+
DependencyObject::~DependencyObject ()
{
g_hash_table_destroy (current_values);
+ if (attached_list != NULL) {
+ g_slist_foreach (attached_list, free_attachee, NULL);
+ g_slist_free (attached_list);
+ }
}
DependencyProperty *
Modified: trunk/moon/src/dependencyobject.h
===================================================================
--- trunk/moon/src/dependencyobject.h 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/dependencyobject.h 2007-08-30 19:02:25 UTC (rev 85065)
@@ -12,7 +12,12 @@
#include "value.h"
#include "enums.h"
+#include "debug.h"
+#if STACK_DEBUG
+#define OBJECT_TRACKING 1
+#endif
+
class EventObject;
typedef void (*EventHandler) (EventObject *sender, gpointer calldata, gpointer
closure);
@@ -29,11 +34,33 @@
class Base {
public:
guint32 refcount;
- Base () : refcount(1) { }
- virtual ~Base () { }
+
+#if OBJECT_TRACKING
+ static int objects_created;
+ static int objects_destroyed;
+ static GList* objects_alive;
+ int id;
+
+ char* GetStackTrace (const char* prefix);
+ char* GetStackTrace () { return GetStackTrace (""); }
+ void PrintStackTrace ();
+ void Track (const char* done, const char* typname);
+ Base ();
+ virtual ~Base ();
void ref ();
void unref ();
+#else
+ Base () : refcount(1) {}
+ virtual ~Base () {}
+ void ref () { refcount++; }
+ void unref ()
+ {
+ refcount--;
+ if (refcount == 0)
+ delete this;
+ }
+#endif
virtual Type::Kind GetObjectType () = 0;
Modified: trunk/moon/src/runtime.cpp
===================================================================
--- trunk/moon/src/runtime.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/runtime.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -923,7 +923,7 @@
}
static bool inited = false;
-
+static bool g_type_inited = false;
void
runtime_init (void)
{
@@ -937,10 +937,20 @@
printf ("*** is being run against version %s.\n",
cairo_version_string ());
printf ("*** Proceed at your own risk\n");
}
+
+#if OBJECT_TRACKING
+ printf ("Runtime created. Object tracking summary:\n");
+ printf ("\tObjects created: %i\n", Base::objects_created);
+ printf ("\tObjects destroyed: %i\n", Base::objects_destroyed);
+ printf ("\tDifference: %i\n", Base::objects_created -
Base::objects_destroyed);
+#endif
inited = true;
- g_type_init ();
+ if (!g_type_inited) {
+ g_type_inited = true;
+ g_type_init ();
+ }
TimeManager::Instance()->Start();
@@ -981,16 +991,38 @@
g_source_remove (source_id);
}
+#if OBJECT_TRACKING
+void
+print_object_data (gpointer key, gpointer user_data)
+{
+ Base* obj = (Base*) key;
+ if (--*(int*)user_data >= 0)
+ printf ("\t\t%i = %s, refcount: %i\n", obj->id,
obj->GetTypeName (), obj->refcount);
+}
+#endif
+
void
runtime_shutdown ()
{
if (!inited)
return;
-
+
+ animation_destroy ();
TimeManager::Instance()->Shutdown ();
- Type::Shutdown ();
DependencyObject::Shutdown ();
+#if OBJECT_TRACKING
+ printf ("Runtime destroyed. Object tracking summary:\n");
+ printf ("\tObjects created: %i\n", Base::objects_created);
+ printf ("\tObjects destroyed: %i\n", Base::objects_destroyed);
+ printf ("\tDifference: %i\n", Base::objects_created -
Base::objects_destroyed);
+ int counter = 10;
+ Base::objects_alive = g_list_reverse (Base::objects_alive);
+ g_list_foreach (Base::objects_alive, print_object_data, &counter);
+#endif
+
+ Type::Shutdown ();
inited = false;
+
}
Modified: trunk/moon/src/type.cpp
===================================================================
--- trunk/moon/src/type.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/type.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -27,7 +27,7 @@
Type implementation
*/
-Type** Type::types;
+Type** Type::types = NULL;
GHashTable* Type::types_by_name = NULL;
Type::Type (const char *name, Type::Kind type, Type::Kind parent)
Modified: trunk/moon/src/type.cpp.in
===================================================================
--- trunk/moon/src/type.cpp.in 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/type.cpp.in 2007-08-30 19:02:25 UTC (rev 85065)
@@ -22,7 +22,7 @@
Type implementation
*/
-Type** Type::types;
+Type** Type::types = NULL;
GHashTable* Type::types_by_name = NULL;
Type::Type (const char *name, Type::Kind type, Type::Kind parent)
Modified: trunk/moon/src/xaml.cpp
===================================================================
--- trunk/moon/src/xaml.cpp 2007-08-30 18:24:28 UTC (rev 85064)
+++ trunk/moon/src/xaml.cpp 2007-08-30 19:02:25 UTC (rev 85065)
@@ -147,6 +147,7 @@
g_string_free (char_data_buffer, TRUE);
if (top_element)
delete top_element;
+ namescope->unref ();
}
};
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches