コード例 #1
0
		internal MySqlDistributedLock Acquire()
		{
			Logger.TraceFormat("Acquire resource={0}, timeout={1}", _resource, _timeout);

			int insertedObjectCount;
			do
			{
				_cancellationToken.ThrowIfCancellationRequested();

				var timeLeft = _start.Add(_timeout).Subtract(DateTime.UtcNow);
				using (ResourceLock.AcquireOne(
					_connection, _storageOptions.TablesPrefix, 
					timeLeft, _cancellationToken,
					LockableResource.Lock))
				{
					insertedObjectCount = AcquireLock();
				}

				if (ContinueCondition(insertedObjectCount))
				{
					_cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses);
					_cancellationToken.ThrowIfCancellationRequested();
				}
			}
			while (ContinueCondition(insertedObjectCount));

			if (insertedObjectCount == 0)
			{
				throw new MySqlDistributedLockException("cannot acquire lock");
			}

			return this;
		}
コード例 #2
0
 protected ResourceLockDelegator(ResourceLock resLock)
     : this(resLock, resLock.ResourceLockOptions)
 {
     Contract.Requires(resLock != null);
     Contract.Ensures(InnerLock != null);
     Contract.Assert(m_resLock != null);
 }
コード例 #3
0
 /// <summary>
 /// Constructs a RecursionResourceLockModifier object.
 /// </summary>
 /// <param name="resLock">A reference to a ResourceLock object that will not support recursion.</param>
 /// <param name="maxReaders">The maximum number of concurrent reader threads that this 
 /// RecursionResourceLockModifier object should support.</param>
 public RecursionResourceLockModifier(ResourceLock resLock, Int32 maxReaders)
    : base(resLock, ResourceLockOptions.AcquiringThreadMustRelease | ResourceLockOptions.SupportsRecursion |
     (resLock.IsMutualExclusive ? ResourceLockOptions.IsMutualExclusive : 0)) {
    Contract.Requires(resLock != null);
    Contract.Requires(maxReaders >= 0);
    m_ReaderThreadIdsAndRecurseCounts = new ThreadIdAndRecurseCount[maxReaders];
 }
コード例 #4
0
 public TextFileWriter(String fileName, Boolean append, Boolean forceDirectoryCreation)
 {
     Disposed        = false;
     LogFilePath     = RIUtils.DetermineParameterPath(fileName);
     Append          = append;
     CreateDirectory = forceDirectoryCreation;
     FResourceLock   = new ResourceLock(fileName);
 }
コード例 #5
0
 /// <summary>
 /// Constructs a RecursionResourceLockModifier object.
 /// </summary>
 /// <param name="resLock">A reference to a ResourceLock object that will not support recursion.</param>
 /// <param name="maxReaders">The maximum number of concurrent reader threads that this
 /// RecursionResourceLockModifier object should support.</param>
 public RecursionResourceLockModifier(ResourceLock resLock, Int32 maxReaders)
     : base(resLock, ResourceLockOptions.AcquiringThreadMustRelease | ResourceLockOptions.SupportsRecursion |
            (resLock.IsMutualExclusive ? ResourceLockOptions.IsMutualExclusive : 0))
 {
     Contract.Requires(resLock != null);
     Contract.Requires(maxReaders >= 0);
     m_ReaderThreadIdsAndRecurseCounts = new ThreadIdAndRecurseCount[maxReaders];
 }
コード例 #6
0
 public ResourceLock TryAcquireRead()
 {
     if (_lock.TryEnterReadLock(0))
     {
         return(ResourceLock.Reader(this));
     }
     return(null);
 }
コード例 #7
0
        internal MySqlConnection CreateAndOpenConnection()
        {
            var connection = new MySqlConnection(_connectionString);

            connection.Open();
            ResourceLock.ReleaseAll(connection);
            return(connection);
        }
コード例 #8
0
 public ThreadBlockInfo(ResourceLock lockObject, Boolean acquiringExclusively)
     :
     this(lockObject,
          (lockObject.AcquiringThreadMustRelease ? ResourceLockOptions.AcquiringThreadMustRelease : 0) |
          (lockObject.SupportsRecursion ? ResourceLockOptions.SupportsRecursion : 0) |
          (acquiringExclusively ? ResourceLockOptions.IsMutualExclusive : 0))
 {
 }
コード例 #9
0
 private int AggregateCounter(MySqlConnection connection)
 {
     using (ResourceLock.AcquireOne(
                connection, _options.TablesPrefix, LockableResource.Counter))
     {
         return(connection.Execute(
                    GetAggregationQuery(),
                    new { now = DateTime.UtcNow, count = NumberOfRecordsInSinglePass }));
     }
 }
コード例 #10
0
      protected ResourceLockDelegator(ResourceLock resLock, ResourceLockOptions resourceLockOptions)
         : base(resourceLockOptions) {
         Contract.Requires(resLock != null);
         Contract.Ensures(InnerLock != null);
         m_resLock = resLock;
#if DEADLOCK_DETECTION
         m_resLock.ImmuneFromDeadlockDetection = true;   // The outerlock is used for deadlock detection; not the inner lock
#endif
         Contract.Assert(m_resLock != null);
      }
コード例 #11
0
        protected ResourceLockDelegator(ResourceLock resLock, ResourceLockOptions resourceLockOptions)
            : base(resourceLockOptions)
        {
            Contract.Requires(resLock != null);
            Contract.Ensures(InnerLock != null);
            m_resLock = resLock;
#if DEADLOCK_DETECTION
            m_resLock.ImmuneFromDeadlockDetection = true; // The outerlock is used for deadlock detection; not the inner lock
#endif
            Contract.Assert(m_resLock != null);
        }
コード例 #12
0
        // Called by a thread when it is about to wait on a lock
        private IDisposable BlockForLockI(ResourceLock lockObject, Boolean acquiringExclusively)
        {
            // Some ResourceLock-derived types are ignored (like NullResourceLock)
            if (lockObject.ImmuneFromDeadlockDetection)
            {
                return(null);
            }

            // Create record indicating what the calling thread is waiting on and add to waiting threads list
            BlockThreadAndCheckDeadlock(new ThreadBlockInfo(lockObject, acquiringExclusively));
            return(m_UnblockDueToLockAcquireDisposer);
        }
コード例 #13
0
        public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken)
        {
            if (queues is null || !queues.Any())
            {
                throw new ArgumentException("Queue array must be non-empty.", nameof(queues));
            }

            var token = Guid.NewGuid().ToString();
            // I'm not sure if this is used correctly...
            var expiration = _options.InvisibilityTimeout;
            // the connection variable is mutable, it job is claimed then this connection
            // is passed to job itself, and variable is set to null so it does not get
            // disposed here in such case
            var connection = _storage.CreateAndOpenConnection();

            try
            {
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    using (ResourceLock.AcquireOne(
                               connection, _options.TablesPrefix, LockableResource.Queue))
                    {
                        var updated = ClaimJob(connection, queues, expiration, token);

                        if (updated != 0)
                        {
                            var fetchedJob = FetchJobByToken(connection, token);
                            return(new MySqlFetchedJob(
                                       _storage, _options,
                                       Interlocked.Exchange(ref connection, null),
                                       fetchedJob));
                        }
                    }

                    cancellationToken.WaitHandle.WaitOne(_options.QueuePollInterval);
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
            catch (MySqlException ex)
            {
                Logger.ErrorException(ex.Message, ex);
                throw;
            }
            finally
            {
                if (connection != null)
                {
                    _storage.ReleaseConnection(connection);
                }
            }
        }
コード例 #14
0
        public void RemoveFromQueue()
        {
            Logger.TraceFormat("RemoveFromQueue JobId={0}", JobId);

            using (ResourceLock.AcquireOne(
                       _connection, _options.TablesPrefix, LockableResource.Queue))
            {
                _connection.Execute(
                    $"delete from `{_options.TablesPrefix}JobQueue` where Id = @id",
                    new { id = _id });
            }

            _removed = true;
        }
コード例 #15
0
        public void Requeue()
        {
            Logger.TraceFormat("Requeue JobId={0}", JobId);

            using (ResourceLock.AcquireOne(
                       _connection, _options.TablesPrefix, LockableResource.Queue))
            {
                _connection.Execute(
                    $"update `{_options.TablesPrefix}JobQueue` set FetchedAt = null where Id = @id",
                    new { id = _id });
            }

            _requeued = true;
        }
コード例 #16
0
        private async Task HandleCommandAsync(SocketMessage messageParam)
        {
            // Don't process the command if it was a system message
            var message = messageParam as SocketUserMessage;

            if (message == null)
            {
                return;
            }

            // Create a number to track where the prefix ends and the command begins
            int argPos = 0;

            // Determine if the message is a command based on the prefix and make sure no bots trigger commands
            if (!(message.HasCharPrefix('!', ref argPos) ||
                  message.HasMentionPrefix(_client.CurrentUser, ref argPos)) ||
                message.Author.IsBot)
            {
                return;
            }

            // Create a WebSocket-based command context based on the message
            var context = new CustomCommandContext(_client, message);

#if !DEBUG
            // We try to lock the channel so that only one Discord Client instance handles the message
            if (!await ResourceLock.AcquireLock(messageParam.Channel.Id.ToString()))
            {
                // If we didn't manage to acquire the lock, we don't do a thing, another client should already be working on it
                this._telemetryClient.TrackTrace($"Lock failed on channel {messageParam.Channel.Id} ({messageParam.Channel.Name})", SeverityLevel.Information);
                return;
            }
#endif
            // Execute the command with the command context we just
            // created, along with the service provider for precondition checks.

            // Keep in mind that result does not indicate a return value
            // rather an object stating if the command executed successfully.
            var result = await _commands.ExecuteAsync(
                context : context,
                argPos : argPos,
                services : this._serviceProvider);

            // Optionally, we may inform the user if the command fails
            // to be executed; however, this may not always be desired,
            // as it may clog up the request queue should a user spam a
            // command.
            // if (!result.IsSuccess)
            // await context.Channel.SendMessageAsync(result.ErrorReason);
        }
コード例 #17
0
		internal void Release()
		{
			Logger.TraceFormat("Release resource={0}", _resource);

			using (ResourceLock.AcquireOne(
				_connection, _storageOptions.TablesPrefix, 
				_timeout, CancellationToken.None,
				LockableResource.Lock))
			{
				_connection.Execute(
					$"DELETE FROM `{_storageOptions.TablesPrefix}DistributedLock`  " +
					"WHERE Resource = @resource",
					new { resource = _resource });
			}
		}
コード例 #18
0
 public override void Commit()
 {
     _storage.UseTransaction(transaction => {
         using (ResourceLock.AcquireMany(
                    transaction, _storageOptions.TablesPrefix,
                    TimeSpan.FromSeconds(30), CancellationToken.None,
                    _resources.ToArray()))
         {
             foreach (var command in _commandQueue)
             {
                 command(transaction);
             }
         }
     });
 }
コード例 #19
0
        private void Enqueue(
            IDbConnection connection, IDbTransaction transaction, string queue, string jobId)
        {
            Logger.TraceFormat("Enqueue JobId={0} Queue={1}", jobId, queue);

            using (ResourceLock.AcquireOne(
                       connection, transaction, _options.TablesPrefix, LockableResource.Queue))
            {
                connection.Execute(
                    $@"/* MySqlJobQueue.Enqueue */
                    insert into `{_options.TablesPrefix}JobQueue` (JobId, Queue)
                    values (@jobId, @queue)",
                    new { jobId, queue },
                    transaction);
            }
        }
コード例 #20
0
        public void Dispose()
        {
            lock (this)
            {
                if (!Disposed)
                {
                    Disposed = true;
                    GC.SuppressFinalize(this);

                    if (FResourceLock != null)
                    {
                        FResourceLock.Dispose();
                        FResourceLock = null;
                    }
                }
            }
        }
コード例 #21
0
      public ExclusiveOwnerResourceLockHelper(ResourceLock resLock) {
         Contract.Requires(resLock != null);
         if (!resLock.IsMutualExclusive)
            throw new ArgumentException("resLock must identify a ResourceLock that is really a mutual-exclusive lock");

         if (resLock.SupportsRecursion)
            throw new ArgumentException("resLock must identify a ResourceLock that does not support recursion");

         m_owningThreadId = 0;

         // C# requires that all fields be assigned to before 'this' is used (when newing the Disposer objects)
         m_afterWaitDisposer = null;
         m_afterReleaseDisposer = null;

         m_afterWaitDisposer = new Disposer(AfterWait);
         m_afterReleaseDisposer = new Disposer(AfterRelease);
      }
コード例 #22
0
        private void ReleaseLockI(Object lockObject)
        {
            // Some ResourceLock-derived types are ignored (like NullResourceLock)
            ResourceLock rl = lockObject as ResourceLock;

            if ((rl != null) && rl.ImmuneFromDeadlockDetection)
            {
                return;
            }

            Int32 threadId = Thread.CurrentThread.ManagedThreadId;

            // The calling thread no longer owns this lock.
            lock (m_syncLock) {
                // Find the record representing the acquired lock being released
                Int32 index = m_AcquiredLocks.FindIndex(delegate(ThreadBlockInfo tli) {
                    // If the lock doesn't have to be released by the owning thread, we have a match
                    if (!tli.AcquiringThreadMustRelease)
                    {
                        return(true);
                    }

                    // Lock must be released by owning thread; we have a match if owning thread Id matches releasing thread Id
                    return(tli.BlockedThreadId == threadId);
                });

                // If not found, then we have an error
                if (index == -1)
                {
                    throw new InvalidOperationException("This thread is trying to release a lock that is not owned");
                }

                // Sanity check: Is the lock is a thread-owned lock, ensure that the thread releasing it is the owner
                if (m_AcquiredLocks[index].AcquiringThreadMustRelease && (m_AcquiredLocks[index].BlockedThreadId != Thread.CurrentThread.ManagedThreadId))
                {
                    throw new InvalidOperationException("This thread is trying to release a thread-owned lock that is owned by another thread");
                }

                m_AcquiredLocks.RemoveAt(index);
            }
        }
コード例 #23
0
        public ExclusiveOwnerResourceLockHelper(ResourceLock resLock)
        {
            Contract.Requires(resLock != null);
            if (!resLock.IsMutualExclusive)
            {
                throw new ArgumentException("resLock must identify a ResourceLock that is really a mutual-exclusive lock");
            }

            if (resLock.SupportsRecursion)
            {
                throw new ArgumentException("resLock must identify a ResourceLock that does not support recursion");
            }

            m_owningThreadId = 0;

            // C# requires that all fields be assigned to before 'this' is used (when newing the Disposer objects)
            m_afterWaitDisposer    = null;
            m_afterReleaseDisposer = null;

            m_afterWaitDisposer    = new Disposer(AfterWait);
            m_afterReleaseDisposer = new Disposer(AfterRelease);
        }
コード例 #24
0
        /// <summary>
        /// Gets the specified name.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name">The name.</param>
        /// <param name="bSlidingTimeWindow">if set to <c>true</c> [b sliding time window].</param>
        /// <param name="callback">The callback.</param>
        /// <param name="args">The arguments.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">callback</exception>
        public T Get <T>(string name, bool bSlidingTimeWindow, Func <string, object[], CacheDataInfo <T> > callback = null, params object[] args)
        {
            var node = GetCachedNode(name, bSlidingTimeWindow);

            if (node == null)
            {
                if (callback == null)
                {
                    return(default(T));
                }

                using (var rLock = new ResourceLock(name))
                {
                    rLock.EnterWriteLock();
                    try
                    {
                        node = GetCachedNode(name, bSlidingTimeWindow);
                        if (node == null)
                        {
                            var cData = callback(name, args);
                            if (cData == null)
                            {
                                return(default(T));
                            }

                            Set(name, cData.NewCacheData, cData.KeepAlive);
                            return(cData.NewCacheData);
                        }
                    }
                    finally
                    {
                        rLock.ExitWriteLock();
                    }
                }
            }

            return((T)node.Data);
        }
コード例 #25
0
        public static void Upgrade(MySqlConnection connection, string tablesPrefix = null)
        {
            if (connection == null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            var prefix = tablesPrefix ?? string.Empty;

            using (ResourceLock.AcquireOne(
                       connection, prefix,
                       MigrationTimeout, CancellationToken.None,
                       LockableResource.Migration))
            {
                var resourceName = $"{typeof(MySqlObjectsInstaller).Namespace}.Migrations.xml";
                var document     = XElement.Parse(GetStringResource(resourceName));

                EnsureMigrationsTable(connection, prefix);

                var migrations = document
                                 .Elements("migration")
                                 .Select(e => new { id = e.Attribute("id")?.Value, script = e.Value })
                                 .ToArray();

                foreach (var migration in migrations)
                {
                    var alreadyApplied = IsMigrationApplied(connection, prefix, migration.id);
                    if (alreadyApplied)
                    {
                        continue;
                    }

                    ApplyMigration(connection, migration.script, prefix, migration.id);
                }
            }
        }
 public StatisticsGatheringResourceLockObserver(ResourceLock resLock)
    : base(resLock) {
    Contract.Requires(resLock != null);
 }
コード例 #27
0
 public StatisticsGatheringResourceLockObserver(ResourceLock resLock)
     : base(resLock)
 {
     Contract.Requires(resLock != null);
 }
コード例 #28
0
 /// <summary>Constructs a TimeoutNotifierResourceLockObserver object.</summary>
 /// <param name="resLock">Indicates the inner ResourceLock.</param>
 /// <param name="timeout">Indicates how long any thread should wait on the inner lock before throwing an exception. This value is in milliseconds.</param>
 public TimeoutNotifierResourceLockObserver(ResourceLock resLock, Int64 timeout)
     : base(resLock)
 {
     Contract.Requires(resLock != null);
     m_timeout = timeout;
 }
コード例 #29
0
 public ThreadSafeCheckerResourceLockObserver(ResourceLock resLock)
     : base(resLock)
 {
     Contract.Requires(resLock != null);
 }
コード例 #30
0
 /// <summary>
 /// Constructs a ResourceLockObserver.
 /// </summary>
 /// <param name="resLock"></param>
 protected ResourceLockObserver(ResourceLock resLock)
    : base(resLock) {
       Contract.Requires(resLock != null);
 }
コード例 #31
0
        public async void Updated(SocketGuildUser before, SocketGuildUser after)
        {
            if (before?.Activity?.Name == after?.Activity?.Name ||
                string.IsNullOrWhiteSpace(after?.Activity?.Name))
            {
                //We don't want to overload the bot by trying to do things when the activity name didn't change (ie: status change, match details change in the activity, ...)
                return;
            }

            // Try to lock the user
            if (!await ResourceLock.AcquireLock($"{after.Id}"))
            {
                // If we can't another client is already handling it
                this._telemetry.TrackEvent($"Lock failed on user {after.Id} ({after.Username}#{after.DiscriminatorValue})");
                return;
            }

            this._telemetry.TrackEvent("Handling a user status update");

            var guild = await SearchTable <Guild>(g => g.RowKey == after.Guild.Id.ToString()).GetOneAsync();

            if (guild == null)
            {
                //On aurait pu prendre le guild id du before, pas comme si ça allait changer
                guild = new Guild(after.Guild);

                await guild.InsertAsync();

                //On vient d'ajouter le serveur (guild) à la liste des serveurs connnus, on a plus rien a faire, puisque aucun binding n'existe
                return;
            }

            //On charge les consignes d'assignation
            await guild.LoadChildrens(g => g.RoleAssignations);

            if (!guild.RoleAssignations.Any())
            {
                //Rien a faire, pas d'assignations
                return;
            }

            var orderedAssignations = guild.RoleAssignations.OrderBy(ra => ra.Order).ToList();

            foreach (var orderedAssignation in orderedAssignations)
            {
                try
                {
                    if (orderedAssignation.IsRegExp)
                    {
                        var regexp = new Regex(orderedAssignation.GameName, RegexOptions.IgnoreCase);

                        if (regexp.IsMatch(after.Activity.Name))
                        {
                            var role = after.Guild.GetRole(orderedAssignation.RoleId);

                            await after.AddRoleAsync(role, RequestOptions.Default);

                            return;
                        }
                    }
                    else
                    {
                        if (after.Activity.Name.ToLowerInvariant().Contains(orderedAssignation.GameName.ToLowerInvariant()))
                        {
                            var role = after.Guild.GetRole(orderedAssignation.RoleId);

                            await after.AddRoleAsync(role, RequestOptions.Default);

                            return;
                        }
                    }
                }
                catch (Exception e)
                {
                    this._telemetry.TrackException(e);
                    continue;
                }
            }
        }
コード例 #32
0
 public ThreadSafeCheckerResourceLockObserver(ResourceLock resLock)
    : base(resLock) {
       Contract.Requires(resLock != null);
 }
コード例 #33
0
        // Called by a thread when it is about to wait on a lock
        private IDisposable BlockForLockI(ResourceLock lockObject, Boolean acquiringExclusively) {
            // Some ResourceLock-derived types are ignored (like NullResourceLock)
            if (lockObject.ImmuneFromDeadlockDetection) return null;

            // Create record indicating what the calling thread is waiting on and add to waiting threads list
            BlockThreadAndCheckDeadlock(new ThreadBlockInfo(lockObject, acquiringExclusively));
            return m_UnblockDueToLockAcquireDisposer;
        }
コード例 #34
0
 /// <summary>Tells the DeadlockDetector that a thread is about to block waiting for a lock.</summary>
 /// <param name="lockObject">The lock that the thread is about to block on.</param>
 /// <param name="acquiringExclusively">true if the thread is acquiring the lock exclusively.</param>
 /// <returns>An object that tells the DeadlockDetector that the thread is no longer blocked.</returns>
 public static IDisposable BlockForLock(ResourceLock lockObject, Boolean acquiringExclusively) {
     return s_deadlockDetector.BlockForLockI(lockObject, acquiringExclusively);
 }
コード例 #35
0
 public ResourceLock AcquireUpgradableRead()
 {
     UnsafeEnterUpgradableRead();
     return(ResourceLock.UpgradableReader(this));
 }
コード例 #36
0
 protected ResourceLockDelegator(ResourceLock resLock)
    : this(resLock, resLock.ResourceLockOptions) {
       Contract.Requires(resLock != null);
       Contract.Ensures(InnerLock != null);
       Contract.Assert(m_resLock != null);
 }
コード例 #37
0
 /// <summary>Constructs a ResourceLockModifier object.</summary>
 /// <param name="resLock">Identifies the inner ResourceLock object.</param>
 /// <param name="resourceLockOptions">Identifies the flags associted with the innter ResourceLock object.</param>
 protected ResourceLockModifier(ResourceLock resLock, ResourceLockOptions resourceLockOptions)
    : base(resLock, resourceLockOptions) {
       Contract.Requires(resLock != null);
 }
コード例 #38
0
 public StatisticsGatheringResourceLock(ResourceLock resLock)
     : base(resLock, resLock.IsMutualExclusive)
 {
 }
コード例 #39
0
 /// <summary>
 /// Constructs an ExclusiveOwnerResourceLockModifier over the specified ResourceLock.
 /// </summary>
 /// <param name="resLock"></param>
 public ExclusiveOwnerResourceLockModifier(ResourceLock resLock)
    : base(resLock, ResourceLockOptions.AcquiringThreadMustRelease | ResourceLockOptions.IsMutualExclusive) {
       Contract.Requires(resLock != null);
    m_exclusiveOwner = new ExclusiveOwnerResourceLockHelper(resLock);
 }
コード例 #40
0
 public ThreadSafeCheckerResourceLock(ResourceLock resLock)
     : base(resLock, resLock.IsMutualExclusive)
 {
 }
コード例 #41
0
 /// <summary>Constructs a TimeoutNotifierResourceLockObserver object.</summary>
 /// <param name="resLock">Indicates the inner ResourceLock.</param>
 /// <param name="timeout">Indicates how long any thread should wait on the inner lock before throwing an exception.</param>
 public TimeoutNotifierResourceLockObserver(ResourceLock resLock, TimeSpan timeout)
     : this(resLock, (Int64)timeout.TotalMilliseconds)
 {
     Contract.Requires(resLock != null);
 }
コード例 #42
0
 public ThreadBlockInfo(ResourceLock lockObject, Boolean acquiringExclusively)
     :
      this(lockObject,
          (lockObject.AcquiringThreadMustRelease ? ResourceLockOptions.AcquiringThreadMustRelease : 0) |
          (lockObject.SupportsRecursion ? ResourceLockOptions.SupportsRecursion : 0) |
          (acquiringExclusively ? ResourceLockOptions.IsMutualExclusive : 0)) { }
コード例 #43
0
 protected DiagnosticResourceLock(ResourceLock resLock)
     : this(resLock, resLock.IsMutualExclusive)
 {
 }
コード例 #44
0
 public ResourceLock AcquireRead()
 {
     UnsafeEnterRead();
     return(ResourceLock.Reader(this));
 }
コード例 #45
0
 /// <summary>Constructs a TimeoutNotifierResourceLockObserver object.</summary>
 /// <param name="resLock">Indicates the inner ResourceLock.</param>
 /// <param name="timeout">Indicates how long any thread should wait on the inner lock before throwing an exception. This value is in milliseconds.</param>
 public TimeoutNotifierResourceLockObserver(ResourceLock resLock, Int64 timeout)
    : base(resLock) {
       Contract.Requires(resLock != null);
    m_timeout = timeout;
 }
コード例 #46
0
 public ResourceLock AcquireWrite()
 {
     UnsafeEnterWrite();
     return(ResourceLock.Writer(this));
 }
コード例 #47
0
 /// <summary>Constructs a TimeoutNotifierResourceLockObserver object.</summary>
 /// <param name="resLock">Indicates the inner ResourceLock.</param>
 /// <param name="timeout">Indicates how long any thread should wait on the inner lock before throwing an exception.</param>
 public TimeoutNotifierResourceLockObserver(ResourceLock resLock, TimeSpan timeout)
    : this(resLock, (Int64) timeout.TotalMilliseconds) {
    Contract.Requires(resLock != null);
 }