[f-spot] Implemented collection proxy to avoid race conditions



commit 8a52390cc0e949099eeab0e9feacb3db4f241b41
Author: Paul Wellner Bou <paul purecodes org>
Date:   Thu Jul 22 09:45:39 2010 +0200

    Implemented collection proxy to avoid race conditions
    
    https://bugzilla.gnome.org/show_bug.cgi?id=624912

 src/Core/BrowsableCollectionProxy.cs |   92 ++++++++++++++++++++++++++++++++++
 src/Core/Makefile.am                 |    1 +
 src/Import/FileImportSource.cs       |   18 +++---
 src/Import/ImportController.cs       |   10 ++--
 src/Import/ImportSource.cs           |    2 +-
 5 files changed, 108 insertions(+), 15 deletions(-)
---
diff --git a/src/Core/BrowsableCollectionProxy.cs b/src/Core/BrowsableCollectionProxy.cs
new file mode 100644
index 0000000..7f036eb
--- /dev/null
+++ b/src/Core/BrowsableCollectionProxy.cs
@@ -0,0 +1,92 @@
+/*
+ * FSpot.BrowsableCollectionProxy.cs
+ *
+ * Author(s):
+ *    Paul Wellner Bou
+ *
+ * This is free software, See COPYING for details
+ */
+
+using System.Collections.Generic;
+
+namespace FSpot {
+    public class BrowsableCollectionProxy : IBrowsableCollection {
+
+        private IBrowsableCollection collection;
+
+        public IBrowsableCollection Collection {
+            get { return collection; }
+            set {
+                if (collection == value)
+                    return;
+
+                if (collection != null) {
+                    collection.Changed -= ChangedHandler;
+                    collection.ItemsChanged -= ItemsChangedHandler;
+                }
+
+                collection = value;
+
+                if (collection != null) {
+                    collection.Changed += ChangedHandler;
+                    collection.ItemsChanged += ItemsChangedHandler;
+                }
+
+                ChangedHandler (this);
+            }
+        }
+
+        public int Count {
+            get { return collection != null ? collection.Count : 0; }
+        }
+
+        public int IndexOf (IBrowsableItem item)
+        {
+            if (collection == null)
+                return -1;
+            return collection.IndexOf (item);
+        }
+
+        public bool Contains (IBrowsableItem item)
+        {
+            if (collection == null)
+                return false;
+            return collection.Contains (item);
+        }
+
+        public IBrowsableItem this [int index] {
+            get {
+                if (collection == null)
+                    throw new System.IndexOutOfRangeException ();
+                return collection [index];
+            }
+        }
+
+        public void MarkChanged (int num, IBrowsableItemChanges changes)
+        {
+            if (collection != null)
+                collection.MarkChanged (num, changes);
+        }
+
+        public IBrowsableItem [] Items {
+            get {
+                return collection.Items;
+            }
+        }
+
+        protected virtual void ChangedHandler (IBrowsableCollection collection)
+        {
+            if (Changed != null)
+                Changed (this);
+        }
+
+        protected virtual void ItemsChangedHandler (IBrowsableCollection collection, BrowsableEventArgs args)
+        {
+            if (ItemsChanged != null)
+                ItemsChanged (this, args);
+        }
+
+        public event IBrowsableCollectionChangedHandler Changed;
+        public event IBrowsableCollectionItemsChangedHandler ItemsChanged;
+    }
+}
diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am
index 49b7583..dcbbda8 100644
--- a/src/Core/Makefile.am
+++ b/src/Core/Makefile.am
@@ -3,6 +3,7 @@ TARGET = library
 LINK = $(REF_FSPOT_CORE)
 
 SOURCES = \
+	BrowsableCollectionProxy.cs \
 	BrowsableEventArgs.cs \
 	BrowsablePointer.cs \
 	BrowsablePointerChangedEventArgs.cs \
diff --git a/src/Import/FileImportSource.cs b/src/Import/FileImportSource.cs
index 2be73b7..2d78a1b 100644
--- a/src/Import/FileImportSource.cs
+++ b/src/Import/FileImportSource.cs
@@ -33,7 +33,7 @@ namespace FSpot.Import
             }
         }
 
-        public void StartPhotoScan (ImportController controller)
+        public void StartPhotoScan (ImportController controller, PhotoList photo_list)
         {
             if (PhotoScanner != null) {
                 run_photoscanner = false;
@@ -41,16 +41,16 @@ namespace FSpot.Import
             }
 
             run_photoscanner = true;
-            PhotoScanner = ThreadAssist.Spawn (() => ScanPhotos (controller));
+            PhotoScanner = ThreadAssist.Spawn (() => ScanPhotos (controller, photo_list));
         }
 
-        protected virtual void ScanPhotos (ImportController controller)
+        protected virtual void ScanPhotos (ImportController controller, PhotoList photo_list)
         {
-            ScanPhotoDirectory (controller, Root);
+            ScanPhotoDirectory (controller, Root, photo_list);
             ThreadAssist.ProxyToMain (() => controller.PhotoScanFinished ());
         }
 
-        protected void ScanPhotoDirectory (ImportController controller, SafeUri uri)
+        protected void ScanPhotoDirectory (ImportController controller, SafeUri uri, PhotoList photo_list)
         {
             var enumerator = new RecursiveFileEnumerator (uri) {
                 Recurse = controller.RecurseSubdirectories,
@@ -65,7 +65,7 @@ namespace FSpot.Import
 
                 if (infos.Count % 10 == 0 || infos.Count < 10) {
                     var to_add = infos; // prevents race condition
-                    ThreadAssist.ProxyToMain (() => controller.Photos.Add (to_add.ToArray ()));
+                    ThreadAssist.ProxyToMain (() => photo_list.Add (to_add.ToArray ()));
                     infos = new List<FileImportInfo> ();
                 }
 
@@ -75,7 +75,7 @@ namespace FSpot.Import
 
             if (infos.Count > 0) {
                 var to_add = infos; // prevents race condition
-                ThreadAssist.ProxyToMain (() => controller.Photos.Add (to_add.ToArray ()));
+                ThreadAssist.ProxyToMain (() => photo_list.Add (to_add.ToArray ()));
             }
         }
 
@@ -130,11 +130,11 @@ namespace FSpot.Import
             this.uris = uris;
         }
 
-        protected override void ScanPhotos (ImportController controller)
+        protected override void ScanPhotos (ImportController controller, PhotoList photo_list)
         {
             foreach (var uri in uris) {
                 Log.Debug ("Scanning "+uri);
-                ScanPhotoDirectory (controller, uri);
+                ScanPhotoDirectory (controller, uri, photo_list);
             }
             ThreadAssist.ProxyToMain (() => controller.PhotoScanFinished ());
         }
diff --git a/src/Import/ImportController.cs b/src/Import/ImportController.cs
index b39dc98..b534e23 100644
--- a/src/Import/ImportController.cs
+++ b/src/Import/ImportController.cs
@@ -18,11 +18,11 @@ namespace FSpot.Import
 
     public class ImportController
     {
-        public PhotoList Photos { get; private set; }
+        public BrowsableCollectionProxy Photos { get; private set; }
 
         public ImportController ()
         {
-            Photos = new PhotoList ();
+            Photos = new BrowsableCollectionProxy ();
             LoadPreferences ();
         }
 
@@ -162,12 +162,13 @@ namespace FSpot.Import
 
         void RescanPhotos ()
         {
-            Photos.Clear ();
             if (ActiveSource == null)
                 return;
 
             photo_scan_running = true;
-            ActiveSource.StartPhotoScan (this);
+            PhotoList pl = new PhotoList ();
+            Photos.Collection = pl;
+            ActiveSource.StartPhotoScan (this, pl);
             FireEvent (ImportEvent.PhotoScanStarted);
         }
 
@@ -263,7 +264,6 @@ namespace FSpot.Import
             created_directories = null;
             Photo.ResetMD5Cache ();
             DeactivateSource (ActiveSource);
-            Photos.Clear ();
             System.GC.Collect ();
             App.Instance.Database.Sync = true;
         }
diff --git a/src/Import/ImportSource.cs b/src/Import/ImportSource.cs
index 2ee01de..8b8d2cc 100644
--- a/src/Import/ImportSource.cs
+++ b/src/Import/ImportSource.cs
@@ -7,7 +7,7 @@ namespace FSpot.Import
         string Name { get; }
         string IconName { get; }
 
-        void StartPhotoScan (ImportController controller);
+        void StartPhotoScan (ImportController controller, PhotoList photo_list);
         void Deactivate ();
     }
 }



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