diff options
author | Michael Hutchinson <m.j.hutchinson@gmail.com> | 2013-03-06 02:53:49 +0400 |
---|---|---|
committer | Michael Hutchinson <m.j.hutchinson@gmail.com> | 2013-06-20 02:36:00 +0400 |
commit | 0d1b8bed3193881e03b3363508509d91077c565a (patch) | |
tree | 187b128cee715d6079ea0eff7efe83b8bd35045c /mcs/class/Mono.Cairo | |
parent | abc2892889e7d6b98b3670fda0f5cee2b2793d55 (diff) |
[Mono.Cairo] Add mechanism to debug missing Dispose calls
by setting a new MONO_CAIRO_DEBUG_DISPOSE env var
Diffstat (limited to 'mcs/class/Mono.Cairo')
-rw-r--r-- | mcs/class/Mono.Cairo/Mono.Cairo/Context.cs | 55 | ||||
-rw-r--r-- | mcs/class/Mono.Cairo/Mono.Cairo/FontFace.cs | 10 | ||||
-rw-r--r-- | mcs/class/Mono.Cairo/Mono.Cairo/FontOptions.cs | 10 | ||||
-rw-r--r-- | mcs/class/Mono.Cairo/Mono.Cairo/Path.cs | 10 | ||||
-rw-r--r-- | mcs/class/Mono.Cairo/Mono.Cairo/Pattern.cs | 25 | ||||
-rw-r--r-- | mcs/class/Mono.Cairo/Mono.Cairo/ScaledFont.cs | 12 | ||||
-rw-r--r-- | mcs/class/Mono.Cairo/Mono.Cairo/Surface.cs | 14 |
7 files changed, 93 insertions, 43 deletions
diff --git a/mcs/class/Mono.Cairo/Mono.Cairo/Context.cs b/mcs/class/Mono.Cairo/Mono.Cairo/Context.cs index 5d6b7679aac..da6bde5b4b6 100644 --- a/mcs/class/Mono.Cairo/Mono.Cairo/Context.cs +++ b/mcs/class/Mono.Cairo/Mono.Cairo/Context.cs @@ -41,6 +41,49 @@ using Cairo; namespace Cairo { + static class CairoDebug + { + static System.Collections.Generic.Dictionary<IntPtr,string> traces; + + public static readonly bool Enabled; + + static CairoDebug () + { + var dbg = Environment.GetEnvironmentVariable ("MONO_CAIRO_DEBUG_DISPOSE"); + if (dbg == null) + return; + Enabled = true; + traces = new System.Collections.Generic.Dictionary<IntPtr,string> (); + } + + public static void OnAllocated (IntPtr obj) + { + if (!Enabled) + throw new InvalidOperationException (); + + traces.Add (obj, Environment.StackTrace); + } + + public static void OnDisposed<T> (IntPtr obj, bool disposing) + { + if (disposing && !Enabled) + throw new InvalidOperationException (); + + if (!disposing) { + Console.Error.WriteLine ("{0} is leaking, programmer is missing a call to Dispose", typeof(T).FullName); + if (Enabled) { + Console.Error.WriteLine ("Allocated from:"); + Console.Error.WriteLine (traces[obj]); + } else { + Console.Error.WriteLine ("Set MONO_CAIRO_DEBUG_DISPOSE to track allocation traces"); + } + } + + if (Enabled) + traces.Remove (obj); + } + } + public struct Point { public Point (int x, int y) @@ -188,6 +231,8 @@ namespace Cairo { public Context (IntPtr state) { this.state = state; + if (CairoDebug.Enabled) + CairoDebug.OnAllocated (state); } ~Context () @@ -203,12 +248,10 @@ namespace Cairo { protected virtual void Dispose (bool disposing) { - if (!disposing){ - Console.Error.WriteLine ("Cairo.Context: called from finalization thread, programmer is missing a call to Dispose"); - return; - } - - if (state == IntPtr.Zero) + if (!disposing || CairoDebug.Enabled) + CairoDebug.OnDisposed<Context> (state, disposing); + + if (!disposing|| state == IntPtr.Zero) return; //Console.WriteLine ("Destroying"); diff --git a/mcs/class/Mono.Cairo/Mono.Cairo/FontFace.cs b/mcs/class/Mono.Cairo/Mono.Cairo/FontFace.cs index b24e9dfb1bd..ca1de265c1f 100644 --- a/mcs/class/Mono.Cairo/Mono.Cairo/FontFace.cs +++ b/mcs/class/Mono.Cairo/Mono.Cairo/FontFace.cs @@ -61,13 +61,11 @@ namespace Cairo protected virtual void Dispose (bool disposing) { - if (handle == IntPtr.Zero) - return; + if (!disposing || CairoDebug.Enabled) + CairoDebug.OnDisposed<FontFace> (handle, disposing); - if (!disposing) { - Console.Error.WriteLine ("Cairo.FontFace: called from finalization thread, programmer is missing a call to Dispose"); + if (!disposing|| handle == IntPtr.Zero) return; - } NativeMethods.cairo_font_face_destroy (handle); handle = IntPtr.Zero; @@ -77,6 +75,8 @@ namespace Cairo public FontFace (IntPtr handle) { this.handle = handle; + if (CairoDebug.Enabled) + CairoDebug.OnAllocated (handle); } public IntPtr Handle { diff --git a/mcs/class/Mono.Cairo/Mono.Cairo/FontOptions.cs b/mcs/class/Mono.Cairo/Mono.Cairo/FontOptions.cs index fa3e84f094b..c0583f10c89 100644 --- a/mcs/class/Mono.Cairo/Mono.Cairo/FontOptions.cs +++ b/mcs/class/Mono.Cairo/Mono.Cairo/FontOptions.cs @@ -47,6 +47,8 @@ namespace Cairo internal FontOptions (IntPtr handle) { this.handle = handle; + if (CairoDebug.Enabled) + CairoDebug.OnAllocated (handle); } public FontOptions Copy () @@ -68,13 +70,11 @@ namespace Cairo protected virtual void Dispose (bool disposing) { - if (handle == IntPtr.Zero) - return; + if (!disposing || CairoDebug.Enabled) + CairoDebug.OnDisposed<FontOptions> (handle, disposing); - if (!disposing) { - Console.Error.WriteLine ("Cairo.FontOptions: called from finalization thread, programmer is missing a call to Dispose"); + if (!disposing|| handle == IntPtr.Zero) return; - } NativeMethods.cairo_font_options_destroy (handle); handle = IntPtr.Zero; diff --git a/mcs/class/Mono.Cairo/Mono.Cairo/Path.cs b/mcs/class/Mono.Cairo/Mono.Cairo/Path.cs index f3dbff648c1..54818827ef4 100644 --- a/mcs/class/Mono.Cairo/Mono.Cairo/Path.cs +++ b/mcs/class/Mono.Cairo/Mono.Cairo/Path.cs @@ -41,6 +41,8 @@ namespace Cairo { internal Path (IntPtr handle) { this.handle = handle; + if (CairoDebug.Enabled) + CairoDebug.OnAllocated (handle); } ~Path () @@ -57,12 +59,10 @@ namespace Cairo { protected virtual void Dispose (bool disposing) { - if (!disposing) { - Console.Error.WriteLine ("Cairo.Path: called from finalization thread, programmer is missing a call to Dispose"); - return; - } + if (!disposing || CairoDebug.Enabled) + CairoDebug.OnDisposed<Path> (handle, disposing); - if (handle == IntPtr.Zero) + if (!disposing|| handle == IntPtr.Zero) return; NativeMethods.cairo_path_destroy (handle); diff --git a/mcs/class/Mono.Cairo/Mono.Cairo/Pattern.cs b/mcs/class/Mono.Cairo/Mono.Cairo/Pattern.cs index 7bf97bd1704..46e0cb593b7 100644 --- a/mcs/class/Mono.Cairo/Mono.Cairo/Pattern.cs +++ b/mcs/class/Mono.Cairo/Mono.Cairo/Pattern.cs @@ -66,12 +66,15 @@ namespace Cairo { static Hashtable patterns = new Hashtable (); - internal Pattern (IntPtr ptr) + internal Pattern (IntPtr handle) { lock (patterns){ patterns [ptr] = this; } - pattern = ptr; + + Handle = handle; + if (CairoDebug.Enabled) + CairoDebug.OnAllocated (handle); } ~Pattern () @@ -98,16 +101,14 @@ namespace Cairo { protected virtual void Dispose (bool disposing) { - if (!disposing) { - Console.Error.WriteLine ("Cairo.Pattern: called from finalization thread, programmer is missing a call to Dispose"); - return; - } + if (!disposing || CairoDebug.Enabled) + CairoDebug.OnDisposed<Pattern> (Handle, disposing); - if (pattern == IntPtr.Zero) + if (!disposing|| Handle == IntPtr.Zero) return; - NativeMethods.cairo_pattern_destroy (pattern); - pattern = IntPtr.Zero; + NativeMethods.cairo_pattern_destroy (Handle); + Handle = IntPtr.Zero; lock (patterns){ patterns.Remove (this); } @@ -116,7 +117,7 @@ namespace Cairo { [Obsolete ("Use Dispose()")] public void Destroy () { - Dispose (); + NativeMethods.cairo_pattern_destroy (pattern); } public Status Status @@ -142,6 +143,10 @@ namespace Cairo { } } + public IntPtr Handle { + get { return pattern; } + private set { pattern = value; } + } public IntPtr Pointer { get { return pattern; } } diff --git a/mcs/class/Mono.Cairo/Mono.Cairo/ScaledFont.cs b/mcs/class/Mono.Cairo/Mono.Cairo/ScaledFont.cs index a15958dae91..27a875db136 100644 --- a/mcs/class/Mono.Cairo/Mono.Cairo/ScaledFont.cs +++ b/mcs/class/Mono.Cairo/Mono.Cairo/ScaledFont.cs @@ -35,11 +35,13 @@ namespace Cairo { internal ScaledFont (IntPtr handle) { this.handle = handle; + if (CairoDebug.Enabled) + CairoDebug.OnAllocated (handle); } public ScaledFont (FontFace fontFace, Matrix matrix, Matrix ctm, FontOptions options) + : this (NativeMethods.cairo_scaled_font_create (fontFace.Handle, matrix, ctm, options.Handle)) { - handle = NativeMethods.cairo_scaled_font_create (fontFace.Handle, matrix, ctm, options.Handle); } ~ScaledFont () @@ -99,13 +101,11 @@ namespace Cairo { protected virtual void Dispose (bool disposing) { - if (handle == IntPtr.Zero) - return; + if (!disposing || CairoDebug.Enabled) + CairoDebug.OnDisposed<ScaledFont> (handle, disposing); - if (!disposing) { - Console.Error.WriteLine ("Cairo.ScaledFont: called from finalization thread, programmer is missing a call to Dispose"); + if (!disposing|| handle == IntPtr.Zero) return; - } NativeMethods.cairo_scaled_font_destroy (handle); handle = IntPtr.Zero; diff --git a/mcs/class/Mono.Cairo/Mono.Cairo/Surface.cs b/mcs/class/Mono.Cairo/Mono.Cairo/Surface.cs index 977019a169f..955c81fa491 100644 --- a/mcs/class/Mono.Cairo/Mono.Cairo/Surface.cs +++ b/mcs/class/Mono.Cairo/Mono.Cairo/Surface.cs @@ -43,6 +43,7 @@ namespace Cairo { protected static Hashtable surfaces = new Hashtable (); internal IntPtr surface = IntPtr.Zero; + [Obsolete] protected Surface() { } @@ -55,6 +56,8 @@ namespace Cairo { } if (!owns) NativeMethods.cairo_surface_reference (ptr); + if (CairoDebug.Enabled) + CairoDebug.OnAllocated (ptr); } static internal Surface LookupExternalSurface (IntPtr p) @@ -147,13 +150,12 @@ namespace Cairo { protected virtual void Dispose (bool disposing) { - if (surface == IntPtr.Zero) - return; - if (!disposing) { - Console.Error.WriteLine ("Cairo.Surface: called from finalization thread, programmer is missing a call to Dispose"); - return; - } + if (!disposing || CairoDebug.Enabled) + CairoDebug.OnDisposed<Surface> (surface, disposing); + if (!disposing|| surface == IntPtr.Zero) + return; + lock (surfaces.SyncRoot) surfaces.Remove (surface); |