diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-12-11 00:12:00 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-12-11 00:12:00 -0500 |
| commit | a9a808a9c407a14af9e041cff20e7fe6af3e5061 (patch) | |
| tree | d4ebcc94333e1b7604f3b88d4daf749cfa822dc9 /Emby.Server.Implementations/Data/BaseSqliteRepository.cs | |
| parent | 0c2489059d80fd5d56fc0c894cfe6e784fc685fa (diff) | |
fix db locking errors
Diffstat (limited to 'Emby.Server.Implementations/Data/BaseSqliteRepository.cs')
| -rw-r--r-- | Emby.Server.Implementations/Data/BaseSqliteRepository.cs | 114 |
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); } } |
