Fix locking

This commit is contained in:
Flamefire committed 2014-09-25 13:06:20 +02:00
1 parent bf7eec4233
commit 3bce89eecf
2 files changed
+61 -43

No files matched your search

+13 -12
View File
@@ -35,28 +35,29 @@ namespace Vocaluxe.Lib.Database
{ {
public class CCoverDB : CDatabaseBase public class CCoverDB : CDatabaseBase
{ {
//You have to lock all actions using cover connection or transaction, otherwhise order is not guaranted
private readonly object _CoverMutex = new object();
private SQLiteTransaction _TransactionCover; private SQLiteTransaction _TransactionCover;
public CCoverDB(string filePath) : base(filePath) {} public CCoverDB(string filePath) : base(filePath) {}
public override bool Init() public override bool Init()
{ {
if (!base.Init()) lock (_Mutex)
return false; {
if (!base.Init())
return false;
if (_Version < 0) if (_Version < 0)
return _CreateCoverDB(); return _CreateCoverDB();
if (_Version < CSettings.DatabaseCoverVersion) if (_Version < CSettings.DatabaseCoverVersion)
throw new NotImplementedException("Upgrading of cover DB not implemented"); throw new NotImplementedException("Upgrading of cover DB not implemented");
}
return true; return true;
} }
public override void Close() public override void Close()
{ {
//Do commit and close atomicly otherwhise we may loose changes //Do commit and close atomicly otherwhise we may loose changes
lock (_CoverMutex) lock (_Mutex)
{ {
_CommitCovers(); _CommitCovers();
@@ -74,7 +75,7 @@ namespace Vocaluxe.Lib.Database
return false; return false;
} }
lock (_CoverMutex) lock (_Mutex)
{ {
//Double check here because we may have just closed our connection //Double check here because we may have just closed our connection
if (_Connection == null) if (_Connection == null)
@@ -147,7 +148,7 @@ namespace Vocaluxe.Lib.Database
tex = CDraw.EnqueueTexture(size.Width, size.Height, data); tex = CDraw.EnqueueTexture(size.Width, size.Height, data);
lock (_CoverMutex) lock (_Mutex)
{ {
//Double check here because we may have just closed our connection //Double check here because we may have just closed our connection
if (_Connection == null) if (_Connection == null)
@@ -184,7 +185,7 @@ namespace Vocaluxe.Lib.Database
public void CommitCovers() public void CommitCovers()
{ {
lock (_CoverMutex) lock (_Mutex)
{ {
_CommitCovers(); _CommitCovers();
} }
+48 -31
View File
@@ -17,7 +17,6 @@
using System; using System;
using System.IO; using System.IO;
using Vocaluxe.Base;
#if WIN #if WIN
using System.Data.SQLite; using System.Data.SQLite;
@@ -27,61 +26,72 @@ using Mono.Data.Sqlite;
namespace Vocaluxe.Lib.Database namespace Vocaluxe.Lib.Database
{ {
public class CDatabaseBase public abstract class CDatabaseBase
{ {
protected readonly string _FilePath; protected readonly string _FilePath;
protected SQLiteConnection _Connection; protected SQLiteConnection _Connection;
//You have to lock all actions using connection or transaction, otherwhise order is not guaranted
protected readonly object _Mutex = new object();
protected int _Version; //Version of the database (value of row "Value" in table "Version") or -1 if none protected int _Version; //Version of the database (value of row "Value" in table "Version") or -1 if none
public CDatabaseBase(string filePath) protected CDatabaseBase(string filePath)
{ {
_FilePath = filePath; _FilePath = filePath;
} }
public virtual bool Init() public virtual bool Init()
{ {
_Connection = new SQLiteConnection("Data Source=" + _FilePath); lock (_Mutex)
try
{ {
_Connection.Open(); if (_Connection != null)
} return false;
catch (Exception) _Connection = new SQLiteConnection("Data Source=" + _FilePath);
{
_Connection.Dispose();
_Connection = null;
return false;
}
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT Value FROM Version";
SQLiteDataReader reader = null;
try try
{ {
reader = command.ExecuteReader(); _Connection.Open();
}
catch (Exception)
{
_Connection.Dispose();
_Connection = null;
return false;
} }
catch (Exception) {}
if (reader == null || !reader.Read() || reader.FieldCount == 0) using (var command = new SQLiteCommand(_Connection))
_Version = -1; {
else command.CommandText = "SELECT Value FROM Version";
_Version = reader.GetInt32(0);
if (reader != null) SQLiteDataReader reader = null;
reader.Dispose();
try
{
reader = command.ExecuteReader();
}
catch (Exception) {}
if (reader == null || !reader.Read() || reader.FieldCount == 0)
_Version = -1;
else
_Version = reader.GetInt32(0);
if (reader != null)
reader.Dispose();
}
} }
return true; return true;
} }
public virtual void Close() public virtual void Close()
{ {
if (_Connection != null) lock (_Mutex)
{ {
_Connection.Dispose(); if (_Connection != null)
_Connection = null; {
_Connection.Dispose();
_Connection = null;
}
} }
} }
@@ -92,6 +102,13 @@ namespace Vocaluxe.Lib.Database
return t70.Ticks; return t70.Ticks;
} }
/// <summary>
/// Reads the contents of a field as a byte array <br />
/// Assumes you did the locking!
/// </summary>
/// <param name="reader"></param>
/// <param name="field">Field number to read from (default=first)</param>
/// <returns></returns>
protected static byte[] _GetBytes(SQLiteDataReader reader, int field = 0) protected static byte[] _GetBytes(SQLiteDataReader reader, int field = 0)
{ {
const int chunkSize = 2 * 1024; const int chunkSize = 2 * 1024;