Make cover loading thread save (Just DB part!!!)
This commit is contained in:
1 parent
e1f4b93d03
commit
542c8a5b37
1 file changed
+117
-99
+117
-99
@@ -53,6 +53,8 @@ namespace Vocaluxe.Base
|
|||||||
private static string _CoverFilePath;
|
private static string _CoverFilePath;
|
||||||
private static string _CreditsRessourcesFilePath;
|
private static string _CreditsRessourcesFilePath;
|
||||||
|
|
||||||
|
//You have to lock all actions using cover connection or transaction, otherwhise order is not guaranted
|
||||||
|
private static readonly object _CoverMutex = new object();
|
||||||
private static SQLiteConnection _ConnectionCover;
|
private static SQLiteConnection _ConnectionCover;
|
||||||
private static SQLiteTransaction _TransactionCover;
|
private static SQLiteTransaction _TransactionCover;
|
||||||
|
|
||||||
@@ -77,7 +79,6 @@ namespace Vocaluxe.Base
|
|||||||
CLog.LogError("Error initializing Credits-DB", true, true);
|
CLog.LogError("Error initializing Credits-DB", true, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
GC.Collect();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,133 +1060,150 @@ namespace Vocaluxe.Base
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ConnectionCover == null)
|
lock (_CoverMutex)
|
||||||
{
|
{
|
||||||
_ConnectionCover = new SQLiteConnection {ConnectionString = "Data Source=" + _CoverFilePath};
|
if (_ConnectionCover == null)
|
||||||
_ConnectionCover.Open();
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var command = new SQLiteCommand(_ConnectionCover))
|
|
||||||
{
|
|
||||||
command.CommandText = "SELECT id, width, height FROM Cover WHERE [Path] = @path";
|
|
||||||
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
|
|
||||||
|
|
||||||
SQLiteDataReader reader = command.ExecuteReader();
|
|
||||||
|
|
||||||
if (reader != null && reader.HasRows)
|
|
||||||
{
|
{
|
||||||
reader.Read();
|
_ConnectionCover = new SQLiteConnection {ConnectionString = "Data Source=" + _CoverFilePath};
|
||||||
int id = reader.GetInt32(0);
|
_ConnectionCover.Open();
|
||||||
int w = reader.GetInt32(1);
|
|
||||||
int h = reader.GetInt32(2);
|
|
||||||
reader.Close();
|
|
||||||
|
|
||||||
command.CommandText = "SELECT Data FROM CoverData WHERE CoverID = @id";
|
|
||||||
command.Parameters.Add("@id", DbType.Int32).Value = id;
|
|
||||||
reader = command.ExecuteReader();
|
|
||||||
|
|
||||||
if (reader.HasRows)
|
|
||||||
{
|
|
||||||
reader.Read();
|
|
||||||
byte[] data = _GetBytes(reader);
|
|
||||||
reader.Dispose();
|
|
||||||
tex = CDraw.EnqueueTexture(w, h, data);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
using (var command = new SQLiteCommand(_ConnectionCover))
|
||||||
{
|
{
|
||||||
if (reader != null)
|
command.CommandText = "SELECT id, width, height FROM Cover WHERE [Path] = @path";
|
||||||
reader.Close();
|
|
||||||
|
|
||||||
if (_TransactionCover == null)
|
|
||||||
_TransactionCover = _ConnectionCover.BeginTransaction();
|
|
||||||
|
|
||||||
Bitmap origin;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
origin = new Bitmap(coverPath);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
CLog.LogError("Error loading Texture: " + coverPath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int w = maxSize;
|
|
||||||
int h = maxSize;
|
|
||||||
byte[] data;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (origin.Width >= origin.Height && origin.Width > w)
|
|
||||||
h = (int)Math.Round((float)w / origin.Width * origin.Height);
|
|
||||||
else if (origin.Height > origin.Width && origin.Height > h)
|
|
||||||
w = (int)Math.Round((float)h / origin.Height * origin.Width);
|
|
||||||
|
|
||||||
using (var bmp = new Bitmap(w, h))
|
|
||||||
{
|
|
||||||
using (Graphics g = Graphics.FromImage(bmp))
|
|
||||||
g.DrawImage(origin, new Rectangle(0, 0, w, h));
|
|
||||||
|
|
||||||
data = new byte[w * h * 4];
|
|
||||||
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
|
||||||
Marshal.Copy(bmpData.Scan0, data, 0, w * h * 4);
|
|
||||||
bmp.UnlockBits(bmpData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
origin.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
tex = CDraw.EnqueueTexture(w, h, data);
|
|
||||||
|
|
||||||
command.CommandText = "INSERT INTO Cover (Path, width, height) VALUES (@path, @w, @h)";
|
|
||||||
command.Parameters.Add("@w", DbType.Int32).Value = w;
|
|
||||||
command.Parameters.Add("@h", DbType.Int32).Value = h;
|
|
||||||
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
|
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
|
||||||
command.ExecuteNonQuery();
|
|
||||||
|
|
||||||
command.CommandText = "SELECT id FROM Cover WHERE [Path] = @path";
|
SQLiteDataReader reader = command.ExecuteReader();
|
||||||
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
|
|
||||||
reader = command.ExecuteReader();
|
|
||||||
|
|
||||||
if (reader != null)
|
if (reader != null && reader.HasRows)
|
||||||
{
|
{
|
||||||
reader.Read();
|
reader.Read();
|
||||||
int id = reader.GetInt32(0);
|
int id = reader.GetInt32(0);
|
||||||
reader.Dispose();
|
int w = reader.GetInt32(1);
|
||||||
command.CommandText = "INSERT INTO CoverData (CoverID, Data) VALUES (@id, @data)";
|
int h = reader.GetInt32(2);
|
||||||
|
reader.Close();
|
||||||
|
|
||||||
|
command.CommandText = "SELECT Data FROM CoverData WHERE CoverID = @id";
|
||||||
command.Parameters.Add("@id", DbType.Int32).Value = id;
|
command.Parameters.Add("@id", DbType.Int32).Value = id;
|
||||||
command.Parameters.Add("@data", DbType.Binary, 20).Value = data;
|
reader = command.ExecuteReader();
|
||||||
command.ExecuteReader();
|
|
||||||
return true;
|
if (reader.HasRows)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
byte[] data = _GetBytes(reader);
|
||||||
|
reader.Dispose();
|
||||||
|
tex = CDraw.EnqueueTexture(w, h, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (reader != null)
|
||||||
|
reader.Close();
|
||||||
|
|
||||||
|
if (_TransactionCover == null)
|
||||||
|
_TransactionCover = _ConnectionCover.BeginTransaction();
|
||||||
|
|
||||||
|
Bitmap origin;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
origin = new Bitmap(coverPath);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
CLog.LogError("Error loading Texture: " + coverPath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = maxSize;
|
||||||
|
int h = maxSize;
|
||||||
|
byte[] data;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (origin.Width >= origin.Height && origin.Width > w)
|
||||||
|
h = (int)Math.Round((float)w / origin.Width * origin.Height);
|
||||||
|
else if (origin.Height > origin.Width && origin.Height > h)
|
||||||
|
w = (int)Math.Round((float)h / origin.Height * origin.Width);
|
||||||
|
|
||||||
|
using (var bmp = new Bitmap(w, h))
|
||||||
|
{
|
||||||
|
using (Graphics g = Graphics.FromImage(bmp))
|
||||||
|
g.DrawImage(origin, new Rectangle(0, 0, w, h));
|
||||||
|
|
||||||
|
data = new byte[w * h * 4];
|
||||||
|
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||||
|
Marshal.Copy(bmpData.Scan0, data, 0, w * h * 4);
|
||||||
|
bmp.UnlockBits(bmpData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
origin.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
tex = CDraw.EnqueueTexture(w, h, data);
|
||||||
|
|
||||||
|
command.CommandText = "INSERT INTO Cover (Path, width, height) VALUES (@path, @w, @h)";
|
||||||
|
command.Parameters.Add("@w", DbType.Int32).Value = w;
|
||||||
|
command.Parameters.Add("@h", DbType.Int32).Value = h;
|
||||||
|
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
|
||||||
|
command.CommandText = "SELECT id FROM Cover WHERE [Path] = @path";
|
||||||
|
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
|
||||||
|
reader = command.ExecuteReader();
|
||||||
|
|
||||||
|
if (reader != null)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
int id = reader.GetInt32(0);
|
||||||
|
reader.Dispose();
|
||||||
|
command.CommandText = "INSERT INTO CoverData (CoverID, Data) VALUES (@id, @data)";
|
||||||
|
command.Parameters.Add("@id", DbType.Int32).Value = id;
|
||||||
|
command.Parameters.Add("@data", DbType.Binary, 20).Value = data;
|
||||||
|
command.ExecuteReader();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CommitCovers()
|
public static void CommitCovers()
|
||||||
|
{
|
||||||
|
lock (_CoverMutex)
|
||||||
|
{
|
||||||
|
_CommitCovers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// You have to hold the CoverMutex when calling this!
|
||||||
|
/// </summary>
|
||||||
|
private static void _CommitCovers()
|
||||||
{
|
{
|
||||||
if (_TransactionCover != null)
|
if (_TransactionCover != null)
|
||||||
{
|
{
|
||||||
_TransactionCover.Commit();
|
_TransactionCover.Commit();
|
||||||
|
_TransactionCover.Dispose();
|
||||||
_TransactionCover = null;
|
_TransactionCover = null;
|
||||||
GC.Collect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Close()
|
public static void Close()
|
||||||
{
|
{
|
||||||
CommitCovers();
|
//Do commit and close atomicly otherwhise we may loose changes
|
||||||
|
lock (_CoverMutex)
|
||||||
if (_ConnectionCover != null)
|
|
||||||
{
|
{
|
||||||
_ConnectionCover.Dispose();
|
CommitCovers();
|
||||||
_ConnectionCover = null;
|
|
||||||
|
if (_ConnectionCover != null)
|
||||||
|
{
|
||||||
|
_ConnectionCover.Dispose();
|
||||||
|
_ConnectionCover = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user