<commit_before>using System;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using Autofac;
using Orchard.Data;
using Orchard.Environment;
using Orchard.Exceptions;
using Orchard.Logging;
using Orchard.Services;
using Orchard.Tasks.Locking.Records;

namespace Orchard.Tasks.Locking.Services {

    public class DistributedLockService : Component, IDistributedLockService {
        private readonly IMachineNameProvider _machineNameProvider;
        private readonly ILifetimeScope _lifetimeScope;
        private readonly IClock _clock;
        private readonly object _transactionManagerLock = new object();
        private readonly IThreadProvider _threadProvider;

        public DistributedLockService(IMachineNameProvider machineNameProvider, IThreadProvider threadProvider, ILifetimeScope lifetimeScope, IClock clock) {
            _machineNameProvider = machineNameProvider;
            _lifetimeScope = lifetimeScope;
            _clock = clock;
            _threadProvider = threadProvider;
        }

        public bool TryAcquireLockForMachine(string name, TimeSpan maxValidFor, TimeSpan? timeout, out DistributedLock @lock) {
            return TryAcquireLock(name, maxValidFor, timeout, GetMachineName(), null, out @lock);
        }

        public DistributedLock AcquireLockForMachine(string name, TimeSpan maxValidFor, TimeSpan? timeout) {
            return AcquireLock(name, maxValidFor, timeout, GetMachineName(), null);
        }

        public bool TryAcquireLockForThread(string name, TimeSpan maxValidFor, TimeSpan? timeout, out DistributedLock @lock) {
            return TryAcquireLock(name, maxValidFor, timeout, GetMachineName(), GetThreadId(), out @lock);
        }

        public DistributedLock AcquireLockForThread(string name, TimeSpan maxValidFor, TimeSpan? timeout) {
            return AcquireLock(name, maxValidFor, timeout, GetMachineName(), GetThreadId());
        }

        public void ReleaseLock(DistributedLock @lock) {
            lock (_transactionManagerLock) {
                var childLifetimeScope = CreateChildLifetimeScope(@lock.Name);

                try {
                    var repository = childLifetimeScope.Resolve<IRepository<DistributedLockRecord>>();
                    var transactionManager = childLifetimeScope.Resolve<ITransactionManager>();
                    transactionManager.RequireNew(IsolationLevel.ReadCommitted);
                    var lockId = Int32.Parse(@lock.Id);
                    var record = repository.Get(lockId);

                    if (record == null)
                        throw new ObjectDisposedException("@lock", "No lock record could be found for the specified lock to be released.");

                    if (record.Count <= 0)
                        throw new ObjectDisposedException("@lock", "The specified lock has already been released.");

                    record.Count--;
                }
                catch (Exception ex) {
                    if (ex.IsFatal()) throw;
                    Logger.Error(ex, "An non-fatal error occurred while trying to dispose a distributed lock with name '{0}' and ID {1}.", @lock.Name, @lock.Id);
                }
                finally {
                    childLifetimeScope.Dispose();
                }
            }
        }

        private bool TryAcquireLock(string name, TimeSpan maxValidFor, TimeSpan? timeout, string machineName, int? threadId, out DistributedLock @lock) {
            @lock = AcquireLockInternal(name, maxValidFor, machineName, threadId, timeout.GetValueOrDefault());
            if (@lock != null)
                return true;

            Logger.Debug("Could not acquire a lock named '{0}'.", name);
            return false;
        }

        private DistributedLock AcquireLock(string name, TimeSpan maxValidFor, TimeSpan? timeout, string machineName, int? threadId) {
            var @lock = AcquireLockInternal(name, maxValidFor, machineName, threadId, timeout);<commit_msg>Non-functional change but more explicit.<commit_after>using System;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using Autofac;
using Orchard.Data;
using Orchard.Environment;
using Orchard.Exceptions;
using Orchard.Logging;
using Orchard.Services;
using Orchard.Tasks.Locking.Records;

namespace Orchard.Tasks.Locking.Services {

    public class DistributedLockService : Component, IDistributedLockService {
        private readonly IMachineNameProvider _machineNameProvider;
        private readonly ILifetimeScope _lifetimeScope;
        private readonly IClock _clock;
        private readonly object _transactionManagerLock = new object();
        private readonly IThreadProvider _threadProvider;

        public DistributedLockService(IMachineNameProvider machineNameProvider, IThreadProvider threadProvider, ILifetimeScope lifetimeScope, IClock clock) {
            _machineNameProvider = machineNameProvider;
            _lifetimeScope = lifetimeScope;
            _clock = clock;
            _threadProvider = threadProvider;
        }

        public bool TryAcquireLockForMachine(string name, TimeSpan maxValidFor, TimeSpan? timeout, out DistributedLock @lock) {
            return TryAcquireLock(name, maxValidFor, timeout, GetMachineName(), null, out @lock);
        }

        public DistributedLock AcquireLockForMachine(string name, TimeSpan maxValidFor, TimeSpan? timeout) {
            return AcquireLock(name, maxValidFor, timeout, GetMachineName(), null);
        }

        public bool TryAcquireLockForThread(string name, TimeSpan maxValidFor, TimeSpan? timeout, out DistributedLock @lock) {
            return TryAcquireLock(name, maxValidFor, timeout, GetMachineName(), GetThreadId(), out @lock);
        }

        public DistributedLock AcquireLockForThread(string name, TimeSpan maxValidFor, TimeSpan? timeout) {
            return AcquireLock(name, maxValidFor, timeout, GetMachineName(), GetThreadId());
        }

        public void ReleaseLock(DistributedLock @lock) {
            lock (_transactionManagerLock) {
                var childLifetimeScope = CreateChildLifetimeScope(@lock.Name);

                try {
                    var repository = childLifetimeScope.Resolve<IRepository<DistributedLockRecord>>();
                    var transactionManager = childLifetimeScope.Resolve<ITransactionManager>();
                    transactionManager.RequireNew(IsolationLevel.ReadCommitted);
                    var lockId = Int32.Parse(@lock.Id);
                    var record = repository.Get(lockId);

                    if (record == null)
                        throw new ObjectDisposedException("@lock", "No lock record could be found for the specified lock to be released.");

                    if (record.Count <= 0)
                        throw new ObjectDisposedException("@lock", "The specified lock has already been released.");

                    record.Count--;
                }
                catch (Exception ex) {
                    if (ex.IsFatal()) throw;
                    Logger.Error(ex, "An non-fatal error occurred while trying to dispose a distributed lock with name '{0}' and ID {1}.", @lock.Name, @lock.Id);
                }
                finally {
                    childLifetimeScope.Dispose();
                }
            }
        }

        private bool TryAcquireLock(string name, TimeSpan maxValidFor, TimeSpan? timeout, string machineName, int? threadId, out DistributedLock @lock) {
            @lock = AcquireLockInternal(name, maxValidFor, machineName, threadId, timeout ?? TimeSpan.Zero);
            if (@lock != null)
                return true;

            Logger.Debug("Could not acquire a lock named '{0}'.", name);
            return false;
        }

        private DistributedLock AcquireLock(string name, TimeSpan maxValidFor, TimeSpan? timeout, string machineName, int? threadId) {
            var @lock = AcquireLockInternal(name, maxValidFor, machineName, threadId, timeout);
{'fraction_non_alphanumeric': 0.07855891918939205, 'fraction_numerical': 0.0015011258443832875, 'mean_word_length': 2.5964912280701755, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7390008', 'n_tokens_mistral': 1978, 'n_tokens_neox': 1874, 'n_words': 550}