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(); }
internal void AddOperation(IThrottleOperation operation) { lock (this.syncObject) { if (this.submitComplete) { throw new InvalidOperationException(); } this.operationsQueue.Add(operation); } this.StartOperationsFromQueue(); }
internal void AddOperation(IThrottleOperation operation) { lock (this.syncObject) { if (this.submitComplete) { throw new InvalidOperationException(); } this.operationsQueue.Add(operation); } this.StartOperationsFromQueue(); }
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(); } }
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(); }
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(); } }
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; }
}// 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(); }
} // 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(); }
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(); } }
} // 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
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(); } }