Пример #1
0
 private void OperationCompleteHandler(object source, OperationStateEventArgs stateEventArgs)
 {
     lock (this.syncObject)
     {
         IThrottleOperation item = source as IThrottleOperation;
         int index = -1;
         if (stateEventArgs.OperationState == OperationState.StartComplete)
         {
             index = this.startOperationQueue.IndexOf(item);
             if (index != -1)
             {
                 this.startOperationQueue.RemoveAt(index);
             }
         }
         else
         {
             index = this.startOperationQueue.IndexOf(item);
             if (index != -1)
             {
                 this.startOperationQueue.RemoveAt(index);
             }
             index = this.stopOperationQueue.IndexOf(item);
             if (index != -1)
             {
                 this.stopOperationQueue.RemoveAt(index);
             }
             item.IgnoreStop = true;
         }
     }
     this.RaiseThrottleManagerEvents();
     this.StartOneOperationFromQueue();
 }
        /// <summary>
        /// Handler which handles state change for the object which implements
        /// the <see cref="System.Management.Automation.Remoting.IThrottleOperation"/>
        /// interface.
        /// </summary>
        /// <param name="source">Sender of the event.</param>
        /// <param name="stateEventArgs">Event information object which describes the event
        /// which triggered this method</param>
        private void OperationCompleteHandler(object source, OperationStateEventArgs stateEventArgs)
        {
            // An item has completed operation. If it's a start operation which completed
            // remove the instance from the startOperationqueue. If it's a stop operation
            // which completed, then remove the instance from both queues
            lock (_syncObject)
            {
                IThrottleOperation operation = source as IThrottleOperation;

                Dbg.Assert(operation != null, "Source of event should not be null");

                int index = -1;

                if (stateEventArgs.OperationState == OperationState.StartComplete)
                {
                    // A stop operation can be initiated before a start operation completes.
                    // A stop operation handler cleans up an outstanding start operation.
                    // So it is possible that a start operation complete callback will find the
                    // operation removed from the queue by an earlier stop operation complete.
                    index = _startOperationQueue.IndexOf(operation);
                    if (index != -1)
                    {
                        _startOperationQueue.RemoveAt(index);
                    }
                }
                else
                {
                    // for a stop operation, the same operation object would have been
                    // added to the stopOperationQueue as well. So we need to
                    // remove both the instances.
                    index = _startOperationQueue.IndexOf(operation);
                    if (index != -1)
                    {
                        _startOperationQueue.RemoveAt(index);
                    }

                    index = _stopOperationQueue.IndexOf(operation);
                    if (index != -1)
                    {
                        _stopOperationQueue.RemoveAt(index);
                    }

                    // if an operation signals a stopcomplete, it can mean
                    // that the operation has completed. In this case, we
                    // need to set the isStopped to true
                    operation.IgnoreStop = true;
                }
            }

            // It's possible that all operations are completed at this point
            // and submit is complete. So raise event
            RaiseThrottleManagerEvents();

            // Do necessary things for starting operation for the next item in the queue
            StartOneOperationFromQueue();
        }
Пример #3
0
 internal void AddOperation(IThrottleOperation operation)
 {
     lock (this.syncObject)
     {
         if (this.submitComplete)
         {
             throw new InvalidOperationException();
         }
         this.operationsQueue.Add(operation);
     }
     this.StartOperationsFromQueue();
 }
Пример #4
0
 internal void AddOperation(IThrottleOperation operation)
 {
     lock (this.syncObject)
     {
         if (this.submitComplete)
         {
             throw new InvalidOperationException();
         }
         this.operationsQueue.Add(operation);
     }
     this.StartOperationsFromQueue();
 }
Пример #5
0
        private void StartOneOperationFromQueue()
        {
            IThrottleOperation item = null;

            lock (this.syncObject)
            {
                if (this.operationsQueue.Count > 0)
                {
                    item = this.operationsQueue[0];
                    this.operationsQueue.RemoveAt(0);
                    item.OperationComplete += new EventHandler <OperationStateEventArgs>(this.OperationCompleteHandler);
                    this.startOperationQueue.Add(item);
                }
            }
            if (item != null)
            {
                item.StartOperation();
            }
        }
        /// <summary>
        /// Method used to start the operation on one item in the queue.
        /// </summary>
        private void StartOneOperationFromQueue()
        {
            IThrottleOperation operation = null;

            lock (_syncObject)
            {
                if (_operationsQueue.Count > 0)
                {
                    operation = _operationsQueue[0];
                    _operationsQueue.RemoveAt(0);
                    operation.OperationComplete += OperationCompleteHandler;
                    _startOperationQueue.Add(operation);
                }
            }

            if (operation != null)
            {
                operation.StartOperation();
            }
        }
Пример #7
0
        internal void StopAllOperations()
        {
            bool flag = false;

            lock (this.syncObject)
            {
                if (!this.stopping)
                {
                    this.stopping = true;
                }
                else
                {
                    flag = true;
                }
            }
            if (flag)
            {
                this.RaiseThrottleManagerEvents();
            }
            else
            {
                IThrottleOperation[] operationArray;
                lock (this.syncObject)
                {
                    this.submitComplete = true;
                    this.operationsQueue.Clear();
                    operationArray = new IThrottleOperation[this.startOperationQueue.Count];
                    this.startOperationQueue.CopyTo(operationArray);
                    foreach (IThrottleOperation operation in operationArray)
                    {
                        this.stopOperationQueue.Add(operation);
                        operation.IgnoreStop = true;
                    }
                }
                foreach (IThrottleOperation operation2 in operationArray)
                {
                    operation2.StopOperation();
                }
                this.RaiseThrottleManagerEvents();
            }
        }
        /// <summary>
        /// Stop the specified operation.
        /// </summary>
        /// <param name="operation">Operation which needs to be stopped.</param>
        internal void StopOperation(IThrottleOperation operation)
        {
            // StopOperation is being called a second time
            // or the stop operation has already completed
            // - in either case just return
            if (operation.IgnoreStop)
            {
                return;
            }

            // If the operation has not yet been started, then
            // remove it from the pending queue
            if (_operationsQueue.IndexOf(operation) != -1)
            {
                lock (_syncObject)
                {
                    if (_operationsQueue.IndexOf(operation) != -1)
                    {
                        _operationsQueue.Remove(operation);
                        RaiseThrottleManagerEvents();
                        return;
                    }
                }
            }

            // The operation has already started, then add it
            // to the inprocess queue and call stop. Refer to
            // comment in StopAllOperations() as to why this is
            // being added a second time
            lock (_syncObject)
            {
                _stopOperationQueue.Add(operation);

                operation.IgnoreStop = true;
            }

            // stop the operation outside of the lock
            operation.StopOperation();
        }
        /// <summary>
        /// Add a single operation to the queue.
        /// </summary>
        /// <param name="operation">Operation to be added.</param>
        internal void AddOperation(IThrottleOperation operation)
        {
            // add item to the queue
            lock (_syncObject)
            {
                // operations can be submitted only until submitComplete
                // is not set to true (happens when EndSubmitOperations is called)
                if (!_submitComplete)
                {
                    Dbg.Assert(operation != null,
                               "Operation submitComplete to throttle manager cannot be null");

                    _operationsQueue.Add(operation);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            // start operations from queue if possible
            StartOperationsFromQueue();
        }
Пример #10
0
 internal void StopOperation(IThrottleOperation operation)
 {
     if (!operation.IgnoreStop)
     {
         if (this.operationsQueue.IndexOf(operation) != -1)
         {
             lock (this.syncObject)
             {
                 if (this.operationsQueue.IndexOf(operation) != -1)
                 {
                     this.operationsQueue.Remove(operation);
                     this.RaiseThrottleManagerEvents();
                     return;
                 }
             }
         }
         lock (this.syncObject)
         {
             this.stopOperationQueue.Add(operation);
             operation.IgnoreStop = true;
         }
         operation.StopOperation();
     }
 }
Пример #11
0
 internal List<Job> GetJobsForOperation(IThrottleOperation operation)
 {
     List<Job> list = new List<Job>();
     ExecutionCmdletHelper helper = operation as ExecutionCmdletHelper;
     foreach (Job job in base.ChildJobs)
     {
         PSRemotingChildJob item = job as PSRemotingChildJob;
         if ((job != null) && item.Helper.Equals(helper))
         {
             list.Add(item);
         }
     }
     return list;
 }
Пример #12
0
        }// AddOperation        

        /// <summary>
        /// Stop throttling operations
        /// </summary>
        /// <remarks>Calling this method will also affect other cmdlets which
        /// could have potentially submitComplete operations for processing
        /// </remarks>
        /// <returns>number of objects cleared from queue without being
        /// stopped</returns>
        internal void StopAllOperations()
        {
            // if stopping is already in progress, make it a no op
            bool needToReturn = false;

            lock (_syncObject)
            {
                if (!_stopping)
                {
                    _stopping = true;
                }
                else
                {
                    needToReturn = true;
                }
            } // lock ...

            if (needToReturn)
            {
                RaiseThrottleManagerEvents();
                return;
            }

            IThrottleOperation[] startOperationsInProcessArray;

            lock (_syncObject)
            {
                // no more submissions possible once stopped
                _submitComplete = true;

                // Clear all pending operations in queue so that they are not
                // scheduled when a stop operation completes
                _operationsQueue.Clear();

                // Make a copy of the in process queue so as to stop all
                // operations in progress
                startOperationsInProcessArray =
                        new IThrottleOperation[_startOperationQueue.Count];
                _startOperationQueue.CopyTo(startOperationsInProcessArray);

                // stop all operations in process (using the copy)
                foreach (IThrottleOperation operation in startOperationsInProcessArray)
                {
                    // When iterating through the array of operations in process
                    // it is quite possible that a runspace gets to the open state
                    // before stop is actually called on it. In that case, the 
                    // OperationCompleteHandler will remove it from the 
                    // operationsInProcess queue. Now when the runspace is closed
                    // the same handler will try removing it again and so there will
                    // be an exception. Hence adding it a second time before stop 
                    // will ensure that the operation is available in the queue for
                    // removal. In case the stop succeeds before start succeeds then
                    // both will get removed (it goes without saying that there cannot
                    // be a situation where start succeeds after stop succeeded)
                    _stopOperationQueue.Add(operation);

                    operation.IgnoreStop = true;
                } // foreach...
            } // lock...

            foreach (IThrottleOperation operation in startOperationsInProcessArray)
            {
                operation.StopOperation();
            }

            // Raise event as it can be that at this point, all operations are
            // complete
            RaiseThrottleManagerEvents();
        } // StopAllOperations
        /// <summary>
        /// Stop throttling operations.
        /// </summary>
        /// <remarks>Calling this method will also affect other cmdlets which
        /// could have potentially submitComplete operations for processing
        /// </remarks>
        /// <returns>Number of objects cleared from queue without being
        /// stopped.</returns>
        internal void StopAllOperations()
        {
            // if stopping is already in progress, make it a no op
            bool needToReturn = false;

            lock (_syncObject)
            {
                if (!_stopping)
                {
                    _stopping = true;
                }
                else
                {
                    needToReturn = true;
                }
            }

            if (needToReturn)
            {
                RaiseThrottleManagerEvents();
                return;
            }

            IThrottleOperation[] startOperationsInProcessArray;

            lock (_syncObject)
            {
                // no more submissions possible once stopped
                _submitComplete = true;

                // Clear all pending operations in queue so that they are not
                // scheduled when a stop operation completes
                _operationsQueue.Clear();

                // Make a copy of the in process queue so as to stop all
                // operations in progress
                startOperationsInProcessArray =
                    new IThrottleOperation[_startOperationQueue.Count];
                _startOperationQueue.CopyTo(startOperationsInProcessArray);

                // stop all operations in process (using the copy)
                foreach (IThrottleOperation operation in startOperationsInProcessArray)
                {
                    // When iterating through the array of operations in process
                    // it is quite possible that a runspace gets to the open state
                    // before stop is actually called on it. In that case, the
                    // OperationCompleteHandler will remove it from the
                    // operationsInProcess queue. Now when the runspace is closed
                    // the same handler will try removing it again and so there will
                    // be an exception. Hence adding it a second time before stop
                    // will ensure that the operation is available in the queue for
                    // removal. In case the stop succeeds before start succeeds then
                    // both will get removed (it goes without saying that there cannot
                    // be a situation where start succeeds after stop succeeded)
                    _stopOperationQueue.Add(operation);

                    operation.IgnoreStop = true;
                }
            }

            foreach (IThrottleOperation operation in startOperationsInProcessArray)
            {
                operation.StopOperation();
            }

            // Raise event as it can be that at this point, all operations are
            // complete
            RaiseThrottleManagerEvents();
        }
Пример #14
0
        } // StopAllOperations

        /// <summary>
        /// Stop the specified operation
        /// </summary>
        /// <param name="operation">operation which needs to be stopped</param>
        internal void StopOperation(IThrottleOperation operation)
        {
            // StopOperation is being called a second time
            // or the stop operation has already completed
            // - in either case just return
            if (operation.IgnoreStop)
            {
                return;
            }

            // If the operation has not yet been started, then
            // remove it from the pending queue 
            if (_operationsQueue.IndexOf(operation) != -1)
            {
                lock (_syncObject)
                {
                    if (_operationsQueue.IndexOf(operation) != -1)
                    {
                        _operationsQueue.Remove(operation);
                        RaiseThrottleManagerEvents();
                        return;
                    }
                }
            }

            // The operation has already started, then add it
            // to the inprocess queue and call stop. Refer to
            // comment in StopAllOperations() as to why this is
            // being added a second time
            lock (_syncObject)
            {
                _stopOperationQueue.Add(operation);

                operation.IgnoreStop = true;
            }

            // stop the operation outside of the lock
            operation.StopOperation();
        }
Пример #15
0
 internal void StopAllOperations()
 {
     bool flag = false;
     lock (this.syncObject)
     {
         if (!this.stopping)
         {
             this.stopping = true;
         }
         else
         {
             flag = true;
         }
     }
     if (flag)
     {
         this.RaiseThrottleManagerEvents();
     }
     else
     {
         IThrottleOperation[] operationArray;
         lock (this.syncObject)
         {
             this.submitComplete = true;
             this.operationsQueue.Clear();
             operationArray = new IThrottleOperation[this.startOperationQueue.Count];
             this.startOperationQueue.CopyTo(operationArray);
             foreach (IThrottleOperation operation in operationArray)
             {
                 this.stopOperationQueue.Add(operation);
                 operation.IgnoreStop = true;
             }
         }
         foreach (IThrottleOperation operation2 in operationArray)
         {
             operation2.StopOperation();
         }
         this.RaiseThrottleManagerEvents();
     }
 }
Пример #16
0
        } // SubmitOperations

        /// <summary>
        /// Add a single operation to the queue
        /// </summary>
        /// <param name="operation">Operation to be added</param>
        internal void AddOperation(IThrottleOperation operation)
        {
            // add item to the queue
            lock (_syncObject)
            {
                // operations can be submitted only until submitComplete 
                // is not set to true (happens when EndSubmitOperations is called)
                if (!_submitComplete)
                {
                    Dbg.Assert(operation != null,
                        "Operation submitComplete to throttle manager cannot be null");

                    _operationsQueue.Add(operation);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            // start operations from queue if possible
            StartOperationsFromQueue();
        }// AddOperation        
Пример #17
0
 internal void StopOperation(IThrottleOperation operation)
 {
     if (!operation.IgnoreStop)
     {
         if (this.operationsQueue.IndexOf(operation) != -1)
         {
             lock (this.syncObject)
             {
                 if (this.operationsQueue.IndexOf(operation) != -1)
                 {
                     this.operationsQueue.Remove(operation);
                     this.RaiseThrottleManagerEvents();
                     return;
                 }
             }
         }
         lock (this.syncObject)
         {
             this.stopOperationQueue.Add(operation);
             operation.IgnoreStop = true;
         }
         operation.StopOperation();
     }
 }