Пример #1
0
                public void UnregisterWait(WaitableObject waitableObject)
                {
                    s_lock.VerifyIsLocked();
                    Debug.Assert(waitableObject != null);

                    WaitedListNode previous = _previous;
                    WaitedListNode next     = _next;

                    if (previous != null)
                    {
                        previous._next = next;
                        _previous      = null;
                    }
                    else
                    {
                        Debug.Assert(waitableObject.WaitersHead == this);
                        waitableObject.WaitersHead = next;
                    }

                    if (next != null)
                    {
                        next._previous = previous;
                        _next          = null;
                    }
                    else
                    {
                        Debug.Assert(waitableObject.WaitersTail == this);
                        waitableObject.WaitersTail = previous;
                    }
                }
Пример #2
0
                public void RegisterPrioritizedWait(WaitableObject waitableObject)
                {
                    s_lock.VerifyIsLocked();
                    Debug.Assert(_waitInfo.Thread == Thread.CurrentThread);

                    Debug.Assert(waitableObject != null);

                    Debug.Assert(_previous == null);
                    Debug.Assert(_next == null);

                    WaitedListNode head = waitableObject.WaitersHead;

                    if (head != null)
                    {
                        _next          = head;
                        head._previous = this;
                    }
                    else
                    {
                        waitableObject.WaitersTail = this;
                    }
                    waitableObject.WaitersHead = this;
                }
Пример #3
0
                public void RegisterWait(WaitableObject waitableObject)
                {
                    s_lock.VerifyIsLocked();
                    Debug.Assert(_waitInfo.Thread == Thread.CurrentThread);

                    Debug.Assert(waitableObject != null);

                    Debug.Assert(_previous == null);
                    Debug.Assert(_next == null);

                    WaitedListNode tail = waitableObject.WaitersTail;

                    if (tail != null)
                    {
                        _previous  = tail;
                        tail._next = this;
                    }
                    else
                    {
                        waitableObject.WaitersHead = this;
                    }
                    waitableObject.WaitersTail = this;
                }
Пример #4
0
            private WaitedListNode[] GetWaitedListNodeArray(int requiredCapacity)
            {
                Debug.Assert(_thread == Thread.CurrentThread);
                Debug.Assert(_waitedCount == 0);

                int currentLength = _waitedListNodes.Length;

                if (currentLength < requiredCapacity)
                {
                    WaitedListNode[] newItems = new WaitedListNode[Math.Max(requiredCapacity,
                                                                            Math.Min(WaitHandle.MaxWaitHandles, 2 * currentLength))];

                    Array.Copy(_waitedListNodes, 0, newItems, 0, currentLength);
                    for (int i = currentLength; i < newItems.Length; i++)
                    {
                        newItems[i] = new WaitedListNode(this, i);
                    }

                    _waitedListNodes = newItems;
                }

                return(_waitedListNodes);
            }
Пример #5
0
            public bool TrySignalToSatisfyWait(WaitedListNode registeredListNode, bool isAbandonedMutex)
            {
                s_lock.VerifyIsLocked();
                Debug.Assert(_thread != Thread.CurrentThread);

                Debug.Assert(registeredListNode != null);
                Debug.Assert(registeredListNode.WaitInfo == this);
                Debug.Assert(registeredListNode.WaitedObjectIndex >= 0);
                Debug.Assert(registeredListNode.WaitedObjectIndex < _waitedCount);

                Debug.Assert(_waitedCount > (_isWaitForAll ? 1 : 0));

                int  signaledWaitedObjectIndex = registeredListNode.WaitedObjectIndex;
                bool isWaitForAll = _isWaitForAll;
                bool wouldAnyMutexReacquireCountOverflow = false;

                if (isWaitForAll)
                {
                    // Determine if all waits would be satisfied
                    if (!WaitableObject.WouldWaitForAllBeSatisfiedOrAborted(
                            _thread,
                            _waitedObjects,
                            _waitedCount,
                            signaledWaitedObjectIndex,
                            ref wouldAnyMutexReacquireCountOverflow,
                            ref isAbandonedMutex))
                    {
                        return(false);
                    }
                }

                // The wait would be satisfied. Before making changes to satisfy the wait, acquire the monitor and verify that
                // the thread can accept a signal.
                _waitMonitor.Acquire();

                if (!IsWaiting)
                {
                    _waitMonitor.Release();
                    return(false);
                }

                if (isWaitForAll && !wouldAnyMutexReacquireCountOverflow)
                {
                    // All waits would be satisfied, accept the signals
                    WaitableObject.SatisfyWaitForAll(this, _waitedObjects, _waitedCount, signaledWaitedObjectIndex);
                }

                UnregisterWait();

                Debug.Assert(_waitedObjectIndexThatSatisfiedWait < 0);
                if (wouldAnyMutexReacquireCountOverflow)
                {
                    _waitSignalState = WaitSignalState.NotWaiting_SignaledToAbortWaitDueToMaximumMutexReacquireCount;
                }
                else
                {
                    _waitedObjectIndexThatSatisfiedWait = signaledWaitedObjectIndex;
                    _waitSignalState =
                        isAbandonedMutex
                            ? WaitSignalState.NotWaiting_SignaledToSatisfyWaitWithAbandonedMutex
                            : WaitSignalState.NotWaiting_SignaledToSatisfyWait;
                }

                _waitMonitor.Signal_Release();
                return(!wouldAnyMutexReacquireCountOverflow);
            }