diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index 7bc77402e..8f64f04db 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -51,7 +51,7 @@ namespace Emby.Server.Implementations.Activity throw new ArgumentNullException("entry"); } - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -76,7 +76,7 @@ namespace Emby.Server.Implementations.Activity public QueryResult GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit) { - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs index 5a4846ccf..dc5d00985 100644 --- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs +++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs @@ -12,7 +12,7 @@ namespace Emby.Server.Implementations.Data public abstract class BaseSqliteRepository : IDisposable { protected string DbFilePath { get; set; } - protected SemaphoreSlim WriteLock = new SemaphoreSlim(1, 1); + protected ReaderWriterLockSlim WriteLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); protected ILogger Logger { get; private set; } protected BaseSqliteRepository(ILogger logger) @@ -130,9 +130,10 @@ namespace Emby.Server.Implementations.Data { lock (_disposeLock) { - WriteLock.Wait(); - - CloseConnection(); + using (WriteLock.Write()) + { + CloseConnection(); + } } } catch (Exception ex) @@ -178,4 +179,51 @@ namespace Emby.Server.Implementations.Data })); } } + + public static class ReaderWriterLockSlimExtensions + { + private sealed class ReadLockToken : IDisposable + { + private ReaderWriterLockSlim _sync; + public ReadLockToken(ReaderWriterLockSlim sync) + { + _sync = sync; + sync.EnterReadLock(); + } + public void Dispose() + { + if (_sync != null) + { + _sync.ExitReadLock(); + _sync = null; + } + } + } + private sealed class WriteLockToken : IDisposable + { + private ReaderWriterLockSlim _sync; + public WriteLockToken(ReaderWriterLockSlim sync) + { + _sync = sync; + sync.EnterWriteLock(); + } + public void Dispose() + { + if (_sync != null) + { + _sync.ExitWriteLock(); + _sync = null; + } + } + } + + public static IDisposable Read(this ReaderWriterLockSlim obj) + { + return new ReadLockToken(obj); + } + public static IDisposable Write(this ReaderWriterLockSlim obj) + { + return new WriteLockToken(obj); + } + } } diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index 79fc893f4..1fbf9b0a9 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -86,7 +86,7 @@ namespace Emby.Server.Implementations.Data cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -127,7 +127,7 @@ namespace Emby.Server.Implementations.Data cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -159,24 +159,27 @@ namespace Emby.Server.Implementations.Data var guidId = displayPreferencesId.GetMD5(); - using (var connection = CreateConnection(true)) + using (WriteLock.Read()) { - var commandText = "select data from userdisplaypreferences where id = ? and userId=? and client=?"; - - var paramList = new List(); - paramList.Add(guidId.ToGuidParamValue()); - paramList.Add(userId.ToGuidParamValue()); - paramList.Add(client); - - foreach (var row in connection.Query(commandText, paramList.ToArray())) + using (var connection = CreateConnection(true)) { - return Get(row); + var commandText = "select data from userdisplaypreferences where id = ? and userId=? and client=?"; + + var paramList = new List(); + paramList.Add(guidId.ToGuidParamValue()); + paramList.Add(userId.ToGuidParamValue()); + paramList.Add(client); + + foreach (var row in connection.Query(commandText, paramList.ToArray())) + { + return Get(row); + } + + return new DisplayPreferences + { + Id = guidId.ToString("N") + }; } - - return new DisplayPreferences - { - Id = guidId.ToString("N") - }; } } @@ -190,16 +193,19 @@ namespace Emby.Server.Implementations.Data { var list = new List(); - using (var connection = CreateConnection(true)) + using (WriteLock.Read()) { - var commandText = "select data from userdisplaypreferences where userId=?"; - - var paramList = new List(); - paramList.Add(userId.ToGuidParamValue()); - - foreach (var row in connection.Query(commandText, paramList.ToArray())) + using (var connection = CreateConnection(true)) { - list.Add(Get(row)); + var commandText = "select data from userdisplaypreferences where userId=?"; + + var paramList = new List(); + paramList.Add(userId.ToGuidParamValue()); + + foreach (var row in connection.Query(commandText, paramList.ToArray())) + { + list.Add(Get(row)); + } } } diff --git a/Emby.Server.Implementations/Data/SqliteUserRepository.cs b/Emby.Server.Implementations/Data/SqliteUserRepository.cs index 5e4b1c7b8..f0e38f8c0 100644 --- a/Emby.Server.Implementations/Data/SqliteUserRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserRepository.cs @@ -83,7 +83,7 @@ namespace Emby.Server.Implementations.Data cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -107,18 +107,21 @@ namespace Emby.Server.Implementations.Data { var list = new List(); - using (var connection = CreateConnection(true)) + using (WriteLock.Read()) { - foreach (var row in connection.Query("select guid,data from users")) + using (var connection = CreateConnection(true)) { - var id = row[0].ReadGuid(); - - using (var stream = _memoryStreamProvider.CreateNew(row[1].ToBlob())) + foreach (var row in connection.Query("select guid,data from users")) { - stream.Position = 0; - var user = _jsonSerializer.DeserializeFromStream(stream); - user.Id = id; - list.Add(user); + var id = row[0].ReadGuid(); + + using (var stream = _memoryStreamProvider.CreateNew(row[1].ToBlob())) + { + stream.Position = 0; + var user = _jsonSerializer.DeserializeFromStream(stream); + user.Id = id; + list.Add(user); + } } } } @@ -142,7 +145,7 @@ namespace Emby.Server.Implementations.Data cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { diff --git a/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index fcf45b0ad..ee900ef33 100644 --- a/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/Emby.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.Notifications { var result = new NotificationResult(); - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { @@ -103,7 +103,7 @@ namespace Emby.Server.Implementations.Notifications { var result = new NotificationsSummary(); - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { @@ -214,7 +214,7 @@ namespace Emby.Server.Implementations.Notifications cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -273,7 +273,7 @@ namespace Emby.Server.Implementations.Notifications { cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -289,7 +289,7 @@ namespace Emby.Server.Implementations.Notifications { cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index f4cb42d29..f6163b80a 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -63,7 +63,7 @@ namespace Emby.Server.Implementations.Security cancellationToken.ThrowIfCancellationRequested(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -195,7 +195,7 @@ namespace Emby.Server.Implementations.Security throw new ArgumentNullException("id"); } - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { diff --git a/Emby.Server.Implementations/Social/SharingRepository.cs b/Emby.Server.Implementations/Social/SharingRepository.cs index e09b7f5b9..9065ee108 100644 --- a/Emby.Server.Implementations/Social/SharingRepository.cs +++ b/Emby.Server.Implementations/Social/SharingRepository.cs @@ -50,7 +50,7 @@ namespace Emby.Server.Implementations.Social throw new ArgumentNullException("info.Id"); } - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -75,7 +75,7 @@ namespace Emby.Server.Implementations.Social throw new ArgumentNullException("id"); } - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { diff --git a/Emby.Server.Implementations/Sync/SyncRepository.cs b/Emby.Server.Implementations/Sync/SyncRepository.cs index fbc5772f3..2877a8ffd 100644 --- a/Emby.Server.Implementations/Sync/SyncRepository.cs +++ b/Emby.Server.Implementations/Sync/SyncRepository.cs @@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.Sync throw new ArgumentNullException("id"); } - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { @@ -206,7 +206,7 @@ namespace Emby.Server.Implementations.Sync CheckDisposed(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -259,7 +259,7 @@ namespace Emby.Server.Implementations.Sync CheckDisposed(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { @@ -281,7 +281,7 @@ namespace Emby.Server.Implementations.Sync CheckDisposed(); - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { @@ -379,7 +379,7 @@ namespace Emby.Server.Implementations.Sync CheckDisposed(); - lock (WriteLock) + using (WriteLock.Read()) { var guid = new Guid(id); @@ -407,7 +407,7 @@ namespace Emby.Server.Implementations.Sync throw new ArgumentNullException("query"); } - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { @@ -487,7 +487,7 @@ namespace Emby.Server.Implementations.Sync var now = DateTime.UtcNow; - lock (WriteLock) + using (WriteLock.Read()) { using (var connection = CreateConnection(true)) { @@ -650,7 +650,7 @@ namespace Emby.Server.Implementations.Sync CheckDisposed(); - lock (WriteLock) + using (WriteLock.Write()) { using (var connection = CreateConnection()) { diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 6a1583094..09996e1d3 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -996,7 +996,7 @@ namespace MediaBrowser.MediaEncoding.Probing { _splitWhiteList = new List { - "AC/DV" + "AC/DC" }; }