예제 #1
0
        //
        // Constructors.
        //

        public StTimer(bool notificationTimer) {
            if (notificationTimer) {
                tmrEvent = new StNotificationEvent();
            } else {
                tmrEvent = new StSynchronizationEvent();
            }
 
            state = INACTIVE;
            cbparker = new CbParker(TimerCallback);
            timer = new RawTimer(cbparker);        
        }
        //
        // Constructor: registers a wait with a Waitable synchronizer.
        //

        internal StRegisteredWait(StWaitable waitObject,  WaitOrTimerCallback callback,
                                  object cbState, int timeout, bool executeOnce) {

        	//
	        // Validate the arguments.
	        //

            if (timeout == 0) {
                throw new ArgumentOutOfRangeException("\"timeout\" can't be zero");
            }
            if (callback == null) {
                throw new ArgumentOutOfRangeException("\"callback\" can't be null");
            }
            if ((waitObject is StReentrantFairLock) || (waitObject is StReentrantReadWriteLock)) {
                throw new InvalidOperationException("can't register waits on reentrant locks");
            }
            if ((waitObject is StNotificationEvent) && !executeOnce) {
                throw new InvalidOperationException("Notification event can't register waits"
                            + " to execute more than once");
            }

	        //
	        // Initialize the register wait fields
	        //

            waitable = waitObject;
            cbparker = new CbParker(UnparkCallback);
            toTimer = new RawTimer(cbparker);
	        this.timeout = timeout;
            this.executeOnce = executeOnce;
	        this.callback = callback;
	        this.cbState = (cbState != null) ? cbState : this;
        
            //
	        // Execute the WaitAny prologue on the waitable.
	        //
            int ignored = 0;
            waitBlock  = waitObject._WaitAnyPrologue(cbparker, StParkStatus.Success, ref hint,
                                                     ref ignored);

            //
	        // Set the registered wait state to active and enable the
            // unpark callback.
	        //

	        state = ACTIVE;
            int ws = cbparker.EnableCallback(timeout, toTimer);
            if (ws != StParkStatus.Pending) {
		
                //
		        // The acquire operation was already accomplished. To prevent
                // uncontrolled reentrancy, the unpark callback is executed inline.
		        //

		        UnparkCallback(ws);
	        }
        }