[f-spot/rubenv-gsoc-2009: 75/86] Prevent a rare disposal exception.



commit a433eb8f25572ca04c26ca89ac08cdbf96d7f0a4
Author: Ruben Vermeersch <ruben savanne be>
Date:   Wed Aug 12 17:48:42 2009 +0200

    Prevent a rare disposal exception.

 src/Loaders/GdkImageLoader.cs    |   44 +++++++++++++++++++++++++-------------
 src/Loaders/LibrawImageLoader.cs |   34 ++++++++++++++++++++--------
 2 files changed, 53 insertions(+), 25 deletions(-)
---
diff --git a/src/Loaders/GdkImageLoader.cs b/src/Loaders/GdkImageLoader.cs
index bc3079a..26cf97f 100644
--- a/src/Loaders/GdkImageLoader.cs
+++ b/src/Loaders/GdkImageLoader.cs
@@ -20,7 +20,7 @@ namespace FSpot.Loaders {
 	{
 		Uri uri;
 		object sync_handle = new object ();
-		bool is_disposed = false;
+		volatile bool is_disposed = false;
 		Rectangle damage;
 
 		public ImageLoaderItem ItemsRequested { get; private set; }
@@ -81,16 +81,15 @@ namespace FSpot.Loaders {
 		{
 			if (is_disposed)
 				return;
-
 			is_disposed = true;
+
 			while (Loading)
-				;
+				WaitForPulse ();
 
 			if (image_stream != null)
 				try {
 					image_stream.Close ();
-				} catch (GLib.GException)
-				{
+				} catch (GLib.GException) {
 				}
 			Close ();
 			if (thumbnail != null) {
@@ -160,7 +159,7 @@ namespace FSpot.Loaders {
 					try {
 						DoLoad ();
 					} catch (Exception e) {
-						Log.Debug (e.ToString ());
+						Log.Debug ("[{0}] {1}", this.GetHashCode (), e.ToString ());
 						Log.Debug ("Requested: {0}, Done: {1}", ItemsRequested, ItemsCompleted);
 						Gtk.Application.Invoke (delegate { throw e; });
 					}
@@ -180,6 +179,7 @@ namespace FSpot.Loaders {
 			lock (sync_handle) {
 				Loading = false;
 			}
+			Pulse ();
 		}
 
 		void LoadThumbnail ()
@@ -231,7 +231,12 @@ namespace FSpot.Loaders {
 			}
 
 			while (Loading && !is_disposed) {
-				int byte_read = image_stream.Read (buffer, 0, count);
+				int byte_read = 0;
+
+				try {
+					byte_read = image_stream.Read (buffer, 0, count);
+				} catch (System.ObjectDisposedException) {
+				}
 
 				if (byte_read == 0) {
 					image_stream.Close ();
@@ -250,11 +255,15 @@ namespace FSpot.Loaders {
 
 		void WaitForCompletion (ImageLoaderItem items)
 		{
-			while (!ItemsCompleted.Contains(items)) {
-				Monitor.Enter (sync_handle);
-				Monitor.Wait (sync_handle);
-				Monitor.Exit (sync_handle);
-			}
+			while (!ItemsCompleted.Contains(items))
+				WaitForPulse ();
+		}
+
+		void WaitForPulse ()
+		{
+			Monitor.Enter (sync_handle);
+			Monitor.Wait (sync_handle);
+			Monitor.Exit (sync_handle);
 		}
 
 		void SignalAreaPrepared (ImageLoaderItem item) {
@@ -294,9 +303,7 @@ namespace FSpot.Loaders {
 		{
 			ItemsCompleted |= item;
 
-			Monitor.Enter (sync_handle);
-			Monitor.PulseAll (sync_handle);
-			Monitor.Exit (sync_handle);
+			Pulse ();
 
 			EventHandler<ItemsCompletedEventArgs> eh = Completed;
 			if (eh != null)
@@ -305,6 +312,13 @@ namespace FSpot.Loaders {
 					return false;
 				});
 		}
+
+		void Pulse ()
+		{
+			Monitor.Enter (sync_handle);
+			Monitor.PulseAll (sync_handle);
+			Monitor.Exit (sync_handle);
+		}
 #endregion
 	}
 }	       
diff --git a/src/Loaders/LibrawImageLoader.cs b/src/Loaders/LibrawImageLoader.cs
index fdc0747..bedf73f 100644
--- a/src/Loaders/LibrawImageLoader.cs
+++ b/src/Loaders/LibrawImageLoader.cs
@@ -22,7 +22,7 @@ namespace FSpot.Loaders {
 	{
 		Uri uri;
 		object sync_handle = new object ();
-		bool is_disposed = false;
+		volatile bool is_disposed = false;
 		Rectangle damage;
 
 		public ImageLoaderItem ItemsRequested { get; private set; }
@@ -93,7 +93,13 @@ namespace FSpot.Loaders {
 
 		public void Dispose ()
 		{
+			if (is_disposed)
+				return;
 			is_disposed = true;
+
+			while (Loading)
+				WaitForPulse ();
+
 			if (loader != null) {
 				loader.Aborted = true;
 				loader.Dispose ();
@@ -105,7 +111,6 @@ namespace FSpot.Loaders {
 				large.Dispose ();
 			if (full != null)
 				full.Dispose ();
-			System.GC.Collect ();
 		}
 #endregion
 
@@ -273,11 +278,15 @@ namespace FSpot.Loaders {
 
 		void WaitForCompletion (ImageLoaderItem items)
 		{
-			while (!ItemsCompleted.Contains(items)) {
-				Monitor.Enter (sync_handle);
-				Monitor.Wait (sync_handle);
-				Monitor.Exit (sync_handle);
-			}
+			while (!ItemsCompleted.Contains(items))
+				WaitForPulse ();
+		}
+
+		void WaitForPulse ()
+		{
+			Monitor.Enter (sync_handle);
+			Monitor.Wait (sync_handle);
+			Monitor.Exit (sync_handle);
 		}
 
 		void SignalAreaPrepared (ImageLoaderItem item) {
@@ -317,9 +326,7 @@ namespace FSpot.Loaders {
 		{
 			ItemsCompleted |= item;
 
-			Monitor.Enter (sync_handle);
-			Monitor.PulseAll (sync_handle);
-			Monitor.Exit (sync_handle);
+			Pulse ();
 
 			EventHandler<ItemsCompletedEventArgs> eh = Completed;
 			if (eh != null)
@@ -328,6 +335,13 @@ namespace FSpot.Loaders {
 					return false;
 				});
 		}
+
+		void Pulse ()
+		{
+			Monitor.Enter (sync_handle);
+			Monitor.PulseAll (sync_handle);
+			Monitor.Exit (sync_handle);
+		}
 #endregion
 	}
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]