Пример #1
0
        /// <summary>
        /// Implements the ResourceLock's DoneWriting behavior.
        /// </summary>
        protected override void OnLeave(Boolean exclusive)
        {
            // Pre-condition:  Lock's state must be Owned
            // Post-condition: Lock's state must become Free (the lock is never passed)

            // Phase 1: Free the lock
            Int32 ls = InterlockedEx.And(ref m_LockState, ~c_lsOwned);

            if (ls == c_lsOwned)
            {
                StressPause();
                // If no waiters, nothing to do, we can just return
            }
            else
            {
                // Phase 2: Possibly wake waiters
                // If lock is free, try to subtract 1 from the number of waiters
                ls &= ~c_lsOwned;
                if (IfThen(ref m_LockState, ls, ls - c_1Waiter))
                {
                    StressPause();
                    // We sucessfully subtracted 1, wake 1 waiter
                    m_WaiterLock.Release(1);
                    StressPause();
                }
                else
                {
                    // Lock's state changed by other thread, other thread will deal with it
                    StressPause();
                }
            }
        }
Пример #2
0
        /// <summary>
        ///     Waits for the event to be set.
        /// </summary>
        /// <param name="millisecondsTimeout">The number of milliseconds to wait.</param>
        /// <returns>Whether the event was set before the timeout period elapsed.</returns>
        public bool Wait(int millisecondsTimeout)
        {
            // 1. [Optional] If Value = 1, Return.
            // 2. [Optional] If Timeout = 0 And Value = 0, Return.
            // 3. [Optional] Reference the Global Event.
            // 4. [Optional] If Global Event is present, skip Step 5.
            // 5. Create Event.
            // 6. Global Event = Event only if Global Event is not present.
            // 7. If Value = 1, Return (rather, go to Step 9).
            // 8. Wait for Global Event.
            // 9. [Optional] Dereference the Global Event.


            int result = _autoReset ? InterlockedEx.And(ref _value, ~EventSet) : _value;

            // Shortcut: return immediately if the event is set.
            if ((result & EventSet) != 0)
            {
                return(true);
            }

            // Shortcut: if the timeout is 0, return immediately if
            // the event isn't set.
            if (millisecondsTimeout == 0)
            {
                return(false);
            }

            // Prevent the event from being closed or invalidated.
            RefEvent();

            // Shortcut: don't bother creating an event if we already have one.
            CEvent newEvent = _event;

            // If we don't have an event, create one and try to set it.
            if (newEvent == null)
            {
                // Create an event. We might not need it, though.
                newEvent = new CEvent(_autoReset, false);

                // Atomically use the event only if we don't already
                // have one.
                if (Interlocked.CompareExchange(ref _event, newEvent, null) != null)
                {
                    // Someone else set the event before we did.
                    newEvent.Close();
                }
            }

            try
            {
                // Check the value to see if we are meant to wait. This step
                // is essential, because if someone set the event before we
                // created the event (previous step), we would be waiting
                // on an event no one knows about.
                if ((_value & EventSet) != 0)
                {
                    return(true);
                }

                return(_event.Wait(millisecondsTimeout));
            }
            finally
            {
                // We don't need the event anymore.
                DerefEvent();
            }
        }
Пример #3
0
 /// <summary>
 ///     Resets the event.
 /// </summary>
 public void Reset()
 {
     InterlockedEx.And(ref _value, ~EventSet);
 }
Пример #4
0
		public static AtomicValue<T> operator &(AtomicValue<T> lhs, int rhs)
			{
			InterlockedEx.And (ref lhs.m_value, -rhs);

			return lhs;
			}