aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-12-11 00:12:00 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-12-11 00:12:00 -0500
commita9a808a9c407a14af9e041cff20e7fe6af3e5061 (patch)
treed4ebcc94333e1b7604f3b88d4daf749cfa822dc9 /Emby.Server.Implementations/Data/BaseSqliteRepository.cs
parent0c2489059d80fd5d56fc0c894cfe6e784fc685fa (diff)
fix db locking errors
Diffstat (limited to 'Emby.Server.Implementations/Data/BaseSqliteRepository.cs')
-rw-r--r--Emby.Server.Implementations/Data/BaseSqliteRepository.cs114
1 files changed, 101 insertions, 13 deletions
diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
index f132c9765..bef2ce149 100644
--- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
+++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
@@ -20,27 +20,34 @@ namespace Emby.Server.Implementations.Data
{
Logger = logger;
- WriteLock = AllowLockRecursion ?
- new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion) :
- new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
+ WriteLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
}
- protected virtual bool AllowLockRecursion
+ protected TransactionMode TransactionMode
{
- get { return false; }
+ get { return TransactionMode.Immediate; }
}
- protected TransactionMode TransactionMode
+ protected TransactionMode ReadTransactionMode
{
- get { return TransactionMode.Immediate; }
+ get { return TransactionMode.Deferred; }
}
+ internal static int ThreadSafeMode { get; set; }
+
static BaseSqliteRepository()
{
SQLite3.EnableSharedCache = false;
int rc = raw.sqlite3_config(raw.SQLITE_CONFIG_MEMSTATUS, 0);
//CheckOk(rc);
+
+ rc = raw.sqlite3_config(raw.SQLITE_CONFIG_MULTITHREAD, 1);
+ //CheckOk(rc);
+
+ rc = raw.sqlite3_enable_shared_cache(1);
+
+ ThreadSafeMode = raw.sqlite3_threadsafe();
}
private static bool _versionLogged;
@@ -61,16 +68,19 @@ namespace Emby.Server.Implementations.Data
if (isReadOnly)
{
//Logger.Info("Opening read connection");
+ //connectionFlags = ConnectionFlags.ReadOnly;
+ connectionFlags = ConnectionFlags.Create;
+ connectionFlags |= ConnectionFlags.ReadWrite;
}
else
{
//Logger.Info("Opening write connection");
+ connectionFlags = ConnectionFlags.Create;
+ connectionFlags |= ConnectionFlags.ReadWrite;
}
- connectionFlags = ConnectionFlags.Create;
- connectionFlags |= ConnectionFlags.ReadWrite;
- connectionFlags |= ConnectionFlags.SharedCached;
- //connectionFlags |= ConnectionFlags.NoMutex;
+ //connectionFlags |= ConnectionFlags.SharedCached;
+ connectionFlags |= ConnectionFlags.NoMutex;
var db = SQLite3.Open(DbFilePath, connectionFlags, null);
@@ -114,7 +124,8 @@ namespace Emby.Server.Implementations.Data
db.ExecuteAll(string.Join(";", queries.ToArray()));
}
}
- else*/ if (queries.Count > 0)
+ else*/
+ if (queries.Count > 0)
{
db.ExecuteAll(string.Join(";", queries.ToArray()));
}
@@ -122,6 +133,26 @@ namespace Emby.Server.Implementations.Data
return db;
}
+ public IStatement PrepareStatement(IDatabaseConnection connection, string sql)
+ {
+ return connection.PrepareStatement(sql);
+ }
+
+ public IStatement PrepareStatementSafe(IDatabaseConnection connection, string sql)
+ {
+ return connection.PrepareStatement(sql);
+ }
+
+ public List<IStatement> PrepareAll(IDatabaseConnection connection, string sql)
+ {
+ return connection.PrepareAll(sql).ToList();
+ }
+
+ public List<IStatement> PrepareAllSafe(IDatabaseConnection connection, string sql)
+ {
+ return connection.PrepareAll(sql).ToList();
+ }
+
protected void RunDefaultInitialization(IDatabaseConnection db)
{
var queries = new List<string>
@@ -288,12 +319,69 @@ namespace Emby.Server.Implementations.Data
}
}
+ public class DummyToken : IDisposable
+ {
+ public void Dispose()
+ {
+ }
+ }
+
public static IDisposable Read(this ReaderWriterLockSlim obj)
{
- return new ReadLockToken(obj);
+ //if (BaseSqliteRepository.ThreadSafeMode > 0)
+ //{
+ // return new DummyToken();
+ //}
+ return new WriteLockToken(obj);
}
public static IDisposable Write(this ReaderWriterLockSlim obj)
{
+ //if (BaseSqliteRepository.ThreadSafeMode > 0)
+ //{
+ // return new DummyToken();
+ //}
+ return new WriteLockToken(obj);
+ }
+ }
+
+ public static class SemaphpreSlimExtensions
+ {
+ private sealed class WriteLockToken : IDisposable
+ {
+ private SemaphoreSlim _sync;
+ public WriteLockToken(SemaphoreSlim sync)
+ {
+ _sync = sync;
+ var task = sync.WaitAsync();
+ Task.WaitAll(task);
+ }
+ public void Dispose()
+ {
+ if (_sync != null)
+ {
+ _sync.Release();
+ _sync = null;
+ }
+ }
+ }
+
+ public class DummyToken : IDisposable
+ {
+ public void Dispose()
+ {
+ }
+ }
+
+ public static IDisposable Read(this SemaphoreSlim obj)
+ {
+ return Write(obj);
+ }
+ public static IDisposable Write(this SemaphoreSlim obj)
+ {
+ //if (BaseSqliteRepository.ThreadSafeMode > 0)
+ //{
+ // return new DummyToken();
+ //}
return new WriteLockToken(obj);
}
}