Пример #1
0
 //Make a bad one
 private AtomicLockedResource([NotNull] AtomicVault <T> owner)
 {
     _releaseFlag = new ToggleFlag(false);
     _owner       = owner ?? throw new ArgumentNullException(nameof(owner));
     _b           = null;
     _isGood      = false;
 }
Пример #2
0
            internal static AtomicLockedResource TryCreateInternalLockedResource([NotNull] AtomicVault <T> owner,
                                                                                 CancellationToken token, bool spin, bool vaultDisposing = false)
            {
                if (token == CancellationToken.None)
                {
                    throw new ArgumentException("Cancellation token may not be none if no timeout is specified.");
                }
                if (owner == null)
                {
                    throw new ArgumentNullException(nameof(owner));
                }
                if (vaultDisposing && !owner.DisposeInProgress)
                {
                    throw new InvalidOperationException($"The {nameof(vaultDisposing)} parameter indicates this call is part of a vault disposal routine." +
                                                        "  The vault, however, is not performing such a routine.");
                }
                if (!vaultDisposing && owner.IsDisposed)
                {
                    throw new ArgumentException(@"The vault is disposed.", nameof(owner));
                }

                var boxRes = AcquireBoxPointer(owner, null, spin, false, token);

                Debug.Assert(!boxRes.timedOut, "Timeout shouldn't be possible -- no timeout specified.");
                return(boxRes.acquiredBox != null
                    ? new AtomicLockedResource(owner, boxRes.acquiredBox)
                    : new AtomicLockedResource(owner));
            }
Пример #3
0
            internal static AtomicLockedResource TryCreateInternalLockedResource([NotNull] AtomicVault <T> owner,
                                                                                 TimeSpan timeout, CancellationToken token, bool spin, bool vaultDisposing = false)
            {
                if (timeout <= TimeSpan.Zero)
                {
                    throw new ArgumentOutOfRangeException(nameof(timeout), timeout, @"Must be positive.");
                }
                if (owner == null)
                {
                    throw new ArgumentNullException(nameof(owner));
                }
                if (vaultDisposing && !owner.DisposeInProgress)
                {
                    throw new InvalidOperationException($"The {nameof(vaultDisposing)} parameter indicates this call is part of a vault disposal routine." +
                                                        "  The vault, however, is not performing such a routine.");
                }
                if (!vaultDisposing && owner.IsDisposed)
                {
                    throw new ArgumentException(@"The vault is disposed.", nameof(owner));
                }

                var boxRes = AcquireBoxPointer(owner, timeout, spin, false, token);

                return(boxRes.acquiredBox != null
                    ? new AtomicLockedResource(owner, boxRes.acquiredBox)
                    : new AtomicLockedResource(owner));
            }
Пример #4
0
            internal static AtomicLockedResource CreateInternalLockedResource([NotNull] AtomicVault <T> owner,
                                                                              TimeSpan timeout, bool spin, bool vaultDisposing = false)
            {
                if (timeout <= TimeSpan.Zero)
                {
                    throw new ArgumentOutOfRangeException(nameof(timeout), timeout, @"Must be positive.");
                }
                if (owner == null)
                {
                    throw new ArgumentNullException(nameof(owner));
                }
                if (vaultDisposing && !owner.DisposeInProgress)
                {
                    throw new InvalidOperationException($"The {nameof(vaultDisposing)} parameter indicates this call is part of a vault disposal routine." +
                                                        "  The vault, however, is not performing such a routine.");
                }
                if (!vaultDisposing && owner.IsDisposed)
                {
                    throw new ArgumentException(@"The vault is disposed.", nameof(owner));
                }

                var boxRes = AcquireBoxPointer(owner, timeout, spin, false, CancellationToken.None);

                Debug.Assert(!boxRes.cancelled); // we didn't pass a token, so not possible
                if (boxRes.acquiredBox != null)
                {
                    return(new AtomicLockedResource(owner, boxRes.acquiredBox));
                }

                throw new TimeoutException(
                          $"Unable to obtain the lock in {timeout.TotalMilliseconds:F3} milliseconds.");
            }
Пример #5
0
            internal static bool CreateInternalLockedResourceNowOrGiveUp([NotNull] AtomicVault <T> owner, out AtomicLockedResource res)
            {
                bool ret;

                res = default;
                var boxRes = AcquireBoxPointer(owner, null, true, true, CancellationToken.None);

                ret = boxRes.acquiredBox != null;
                return(ret);
            }
Пример #6
0
            private static (Box acquiredBox, bool cancelled, bool timedOut) AcquireBoxPointer(AtomicVault <T> owner,
                                                                                              TimeSpan?timeout, bool spin, bool justOnce, CancellationToken token)
            {
                Box  acquiredPtr;
                bool cancel = false;
                bool timedOut;

                Debug.Assert(timeout != null || token != CancellationToken.None || justOnce);

                DateTime?quitAfter          = DnvTimeStampProvider.MonoLocalNow + timeout;
                TimeSpan ownerSleepInterval = owner.SleepInterval;
                TimeSpan sleepFor           = ownerSleepInterval > TimeSpan.Zero && ownerSleepInterval < timeout ? ownerSleepInterval : FallbackSleepInterval;

                do
                {
                    acquiredPtr = Interlocked.Exchange(ref owner._resourcePtr, null);
                    if (acquiredPtr == null)
                    {
                        cancel = token.IsCancellationRequested;
                        if (!spin && !cancel && !justOnce)
                        {
                            Thread.Sleep(sleepFor);
                        }
                        cancel = token.IsCancellationRequested;
                    }
                } while (!justOnce && !cancel && acquiredPtr == null && (quitAfter == null || DnvTimeStampProvider.MonoLocalNow <= quitAfter));

                if (acquiredPtr != null)
                {
                    timedOut = false;
                }
                else
                {
                    timedOut = !cancel || justOnce;
                    cancel   = !timedOut;
                }

                Debug.Assert(DoPostConditionCheck(acquiredPtr, cancel, timedOut));
                return(acquiredPtr, cancel, timedOut);