Convert all Monitor code to AutoResetEvent code. Should prevent very obscure
deadlocks, minor improvements in the dispose method (no more spinlock).

 QueuedSqliteDatabase.cs |   37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)


Index: src/Core/Banshee.Base/QueuedSqliteDatabase.cs
===================================================================
--- src/Core/Banshee.Base/QueuedSqliteDatabase.cs	(revision 2121)
+++ src/Core/Banshee.Base/QueuedSqliteDatabase.cs	(working copy)
@@ -33,16 +33,32 @@
 
 namespace Banshee.Database
 {
+    /// <summary>
+    /// A thread-safe wrapper for SQLite.
+    /// </summary>
+    /// <remarks>
+    /// SQLite is not thread-safe by default on Linux. Therefor, we handle 
+    /// all SQL queries on a seperate thread.
+    /// </remarks>
     public class QueuedSqliteDatabase : IDisposable
     {
+        /// <summary>
+        /// Holds queries to be executed.
+        /// </summary>
         private Queue<QueuedSqliteCommand> command_queue = new Queue<QueuedSqliteCommand>();
+
         private SqliteConnection connection;
         private Thread queue_thread;
-        private bool dispose_requested = false;
+        private volatile bool dispose_requested = false;
         private bool processing_queue = false;
         private string dbpath;
-        private bool connected;
+        private volatile bool connected;
         
+        /// <summary>
+        /// Signal used to indicate there is new data in the <see cref="command_queue"/>.
+        /// </summary>
+        private AutoResetEvent queue_signal = new AutoResetEvent(false);
+        
         public QueuedSqliteDatabase(string dbpath)
         {
             this.dbpath = dbpath;
@@ -54,8 +70,8 @@
         public void Dispose()
         {
             dispose_requested = true;
-            WakeUp();
-            while(processing_queue);
+            queue_signal.Set();
+            queue_thread.Join();
         }
         
         private void WaitForConnection()
@@ -68,7 +84,7 @@
             lock(command_queue) {
                 command_queue.Enqueue(command);
             }
-            WakeUp();
+            queue_signal.Set();
         }
         
         public SqliteDataReader Query(DbCommand command)
@@ -123,13 +139,6 @@
                     table))) > 0;
         }
 
-        private void WakeUp()
-        {
-            Monitor.Enter(command_queue);
-            Monitor.Pulse(command_queue);
-            Monitor.Exit(command_queue);
-        }
-        
         private void ProcessQueue()
         {         
             if(connection == null) {
@@ -164,9 +173,7 @@
                     return;
                 }
                 
-                Monitor.Enter(command_queue);
-                Monitor.Wait(command_queue);
-                Monitor.Exit(command_queue);
+                queue_signal.WaitOne();
             }
         }
     }
