internal void DoConcurrentCheckAndAddToRunningPipelines(PipelineBase pipeline, bool syncCall) { lock (this._syncRoot) { if (this._bSessionStateProxyCallInProgress) { throw PSTraceSource.NewInvalidOperationException("RunspaceStrings", "NoPipelineWhenSessionStateProxyInProgress", new object[0]); } pipeline.DoConcurrentCheck(syncCall, this._syncRoot, true); this.AddToRunningPipelineList(pipeline); } }
internal void AddToRunningPipelineList(PipelineBase pipeline) { lock (this._runningPipelines.SyncRoot) { if (!this._bypassRunspaceStateCheck && (this.RunspaceState != System.Management.Automation.Runspaces.RunspaceState.Opened)) { InvalidRunspaceStateException exception = new InvalidRunspaceStateException(StringUtil.Format(RunspaceStrings.RunspaceNotOpenForPipeline, this.RunspaceState.ToString()), this.RunspaceState, System.Management.Automation.Runspaces.RunspaceState.Opened); throw exception; } this._runningPipelines.Add(pipeline); this.currentlyRunningPipeline = pipeline; } }
internal void RemoveFromRunningPipelineList(PipelineBase pipeline) { lock (this._runningPipelines.SyncRoot) { this._runningPipelines.Remove(pipeline); if (this._runningPipelines.Count == 0) { this.currentlyRunningPipeline = null; } else { this.currentlyRunningPipeline = (Pipeline)this._runningPipelines[this._runningPipelines.Count - 1]; } pipeline.PipelineFinishedEvent.Set(); } }
internal void DoConcurrentCheck(bool syncCall, object syncObject, bool isInLock) { PipelineBase currentlyRunningPipeline = (PipelineBase)this.RunspaceBase.GetCurrentlyRunningPipeline(); if (!this.IsNested) { if (currentlyRunningPipeline != null) { if ((currentlyRunningPipeline != this.RunspaceBase.PulsePipeline) && (!currentlyRunningPipeline.IsNested || (this.RunspaceBase.PulsePipeline == null))) { throw PSTraceSource.NewInvalidOperationException("RunspaceStrings", "ConcurrentInvokeNotAllowed", new object[0]); } if (isInLock) { Monitor.Exit(syncObject); } try { this.RunspaceBase.WaitForFinishofPipelines(); } finally { if (isInLock) { Monitor.Enter(syncObject); } } this.DoConcurrentCheck(syncCall, syncObject, isInLock); } } else if (this._performNestedCheck) { if (!syncCall) { throw PSTraceSource.NewInvalidOperationException("RunspaceStrings", "NestedPipelineInvokeAsync", new object[0]); } if (currentlyRunningPipeline == null) { throw PSTraceSource.NewInvalidOperationException("RunspaceStrings", "NestedPipelineNoParentPipeline", new object[0]); } Thread currentThread = Thread.CurrentThread; if (!currentlyRunningPipeline.NestedPipelineExecutionThread.Equals(currentThread)) { throw PSTraceSource.NewInvalidOperationException("RunspaceStrings", "NestedPipelineNoParentPipeline", new object[0]); } } }
protected PipelineBase(PipelineBase pipeline) : this(pipeline.Runspace, (string)null, false, pipeline.IsNested) { using (PipelineBase._trace.TraceConstructor((object)this)) { if (pipeline == null) { throw PipelineBase._trace.NewArgumentNullException(nameof(pipeline)); } this._addToHistory = !pipeline._disposed ? pipeline._addToHistory : throw PipelineBase._trace.NewObjectDisposedException(nameof(pipeline)); this._historyString = pipeline._historyString; foreach (Command command in (Collection <Command>)pipeline.Commands) { this.Commands.Add(command.Clone()); } } }
protected PipelineBase(PipelineBase pipeline) : this(pipeline.Runspace, null, false, pipeline.IsNested) { if (pipeline == null) { throw PSTraceSource.NewArgumentNullException("pipeline"); } if (pipeline._disposed) { throw PSTraceSource.NewObjectDisposedException("pipeline"); } this._addToHistory = pipeline._addToHistory; this._historyString = pipeline._historyString; foreach (Command command in pipeline.Commands) { Command item = command.Clone(); base.Commands.Add(item); } }
internal PowerShellStopper(ExecutionContext context, PowerShell powerShell) { if (context == null) { throw new ArgumentNullException("context"); } if (powerShell == null) { throw new ArgumentNullException("powerShell"); } this.powerShell = powerShell; if (((context.CurrentCommandProcessor != null) && (context.CurrentCommandProcessor.CommandRuntime != null)) && ((context.CurrentCommandProcessor.CommandRuntime.PipelineProcessor != null) && (context.CurrentCommandProcessor.CommandRuntime.PipelineProcessor.LocalPipeline != null))) { this.eventHandler = new EventHandler<PipelineStateEventArgs>(this.LocalPipeline_StateChanged); this.pipeline = context.CurrentCommandProcessor.CommandRuntime.PipelineProcessor.LocalPipeline; this.pipeline.StateChanged += this.eventHandler; } }
internal bool RunActionIfNoRunningPipelinesWithThreadCheck(Action action) { bool flag = false; bool flag2 = false; lock (this._runningPipelines.SyncRoot) { PipelineBase currentlyRunningPipeline = this.currentlyRunningPipeline as PipelineBase; if ((currentlyRunningPipeline == null) || Thread.CurrentThread.Equals(currentlyRunningPipeline.NestedPipelineExecutionThread)) { flag2 = true; } } if (flag2) { action(); flag = true; } return(flag); }
internal void DoConcurrentCheck(bool syncCall) { using (PipelineBase._trace.TraceMethod()) { PipelineBase currentlyRunningPipeline = (PipelineBase)this.RunspaceBase.GetCurrentlyRunningPipeline(); if (!this.IsNested) { if (currentlyRunningPipeline == null) { return; } if (currentlyRunningPipeline != this.RunspaceBase.PulsePipeline) { throw PipelineBase._trace.NewInvalidOperationException("Runspace", "ConcurrentInvokeNotAllowed"); } this.RunspaceBase.WaitForFinishofPipelines(); this.DoConcurrentCheck(syncCall); } else { if (!this._performNestedCheck) { return; } if (!syncCall) { throw PipelineBase._trace.NewInvalidOperationException("Runspace", "NestedPipelineInvokeAsync"); } if (currentlyRunningPipeline == null) { throw PipelineBase._trace.NewInvalidOperationException("Runspace", "NestedPipelineNoParentPipeline"); } Thread currentThread = Thread.CurrentThread; if (!currentlyRunningPipeline.NestedPipelineExecutionThread.Equals((object)currentThread)) { throw PipelineBase._trace.NewInvalidOperationException("Runspace", "NestedPipelineNoParentPipeline"); } } } }
internal void Pulse() { bool flag = false; if (this.GetCurrentlyRunningPipeline() == null) { lock (this.SyncRoot) { if (this.GetCurrentlyRunningPipeline() == null) { try { this.pulsePipeline = (PipelineBase)this.CreatePipeline("0"); this.pulsePipeline.IsPulsePipeline = true; flag = true; } catch (ObjectDisposedException) { } } } } if (flag) { try { this.pulsePipeline.Invoke(); } catch (PSInvalidOperationException) { } catch (InvalidRunspaceStateException) { } catch (ObjectDisposedException) { } } }
/// <summary> /// Copy constructor to support cloning /// </summary> /// <param name="pipeline">The source pipeline</param> /// <remarks> /// The copy constructor's intent is to support the scenario /// where a host needs to run the same set of commands multiple /// times. This is accomplished via creating a master pipeline /// then cloning it and executing the cloned copy. /// </remarks> protected PipelineBase(PipelineBase pipeline) : this(pipeline.Runspace, null, false, pipeline.IsNested) { // NTRAID#Windows Out Of Band Releases-915851-2005/09/13 if (pipeline == null) { throw PSTraceSource.NewArgumentNullException("pipeline"); } if (pipeline._disposed) { throw PSTraceSource.NewObjectDisposedException("pipeline"); } AddToHistory = pipeline.AddToHistory; HistoryString = pipeline.HistoryString; foreach (Command command in pipeline.Commands) { Command clone = command.Clone(); // Attach the cloned Command to this pipeline. Commands.Add(clone); } }
/// <summary> /// Add the pipeline to list of pipelines in execution. /// </summary> /// <param name="pipeline">Pipeline to add to the /// list of pipelines in execution</param> /// /// <exception cref="InvalidRunspaceStateException"> /// Thrown if the runspace is not in the Opened state. /// <see cref="RunspaceState"/>. /// </exception> /// /// <exception cref="ArgumentNullException">Thrown if /// <paramref name="pipeline"/> is null. /// </exception> internal void AddToRunningPipelineList(PipelineBase pipeline) { Dbg.Assert(pipeline != null, "caller should validate the parameter"); lock (_pipelineListLock) { if (ByPassRunspaceStateCheck == false && RunspaceState != RunspaceState.Opened) { InvalidRunspaceStateException e = new InvalidRunspaceStateException ( StringUtil.Format(RunspaceStrings.RunspaceNotOpenForPipeline, RunspaceState.ToString()), RunspaceState, RunspaceState.Opened ); throw e; } //Add the pipeline to list of Executing pipeline. //Note:_runningPipelines is always accessed with the lock so //there is no need to create a synchronized version of list RunningPipelines.Add(pipeline); _currentlyRunningPipeline = pipeline; } }
DoConcurrentCheckAndAddToRunningPipelines(PipelineBase pipeline, bool syncCall) { //Concurrency check should be done under runspace lock lock (SyncRoot) { if (_bSessionStateProxyCallInProgress == true) { throw PSTraceSource.NewInvalidOperationException(RunspaceStrings.NoPipelineWhenSessionStateProxyInProgress); } //Delegate to pipeline to do check if it is fine to invoke if another //pipeline is running. pipeline.DoConcurrentCheck(syncCall, SyncRoot, true); //Finally add to the list of running pipelines. AddToRunningPipelineList(pipeline); } }
internal void RemoveFromRunningPipelineList(PipelineBase pipeline) { lock (this._runningPipelines.SyncRoot) { this._runningPipelines.Remove(pipeline); if (this._runningPipelines.Count == 0) { this.currentlyRunningPipeline = null; } else { this.currentlyRunningPipeline = (Pipeline) this._runningPipelines[this._runningPipelines.Count - 1]; } pipeline.PipelineFinishedEvent.Set(); } }
internal void Pulse() { bool flag = false; if (this.GetCurrentlyRunningPipeline() == null) { lock (this.SyncRoot) { if (this.GetCurrentlyRunningPipeline() == null) { try { this.pulsePipeline = (PipelineBase) this.CreatePipeline("0"); this.pulsePipeline.IsPulsePipeline = true; flag = true; } catch (ObjectDisposedException) { } } } } if (flag) { try { this.pulsePipeline.Invoke(); } catch (PSInvalidOperationException) { } catch (InvalidRunspaceStateException) { } catch (ObjectDisposedException) { } } }
/// <summary> /// Remove the pipeline from list of pipelines in execution. /// </summary> /// <param name="pipeline">Pipeline to remove from the /// list of pipelines in execution</param> /// /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="pipeline"/> is null. /// </exception> internal void RemoveFromRunningPipelineList(PipelineBase pipeline) { Dbg.Assert(pipeline != null, "caller should validate the parameter"); lock (_pipelineListLock) { Dbg.Assert(RunspaceState != RunspaceState.BeforeOpen, "Runspace should not be before open when pipeline is running"); //Remove the pipeline to list of Executing pipeline. //Note:_runningPipelines is always accessed with the lock so //there is no need to create a synchronized version of list RunningPipelines.Remove(pipeline); // Update the running pipeline if (RunningPipelines.Count == 0) { _currentlyRunningPipeline = null; } else { _currentlyRunningPipeline = RunningPipelines[RunningPipelines.Count - 1]; } pipeline.PipelineFinishedEvent.Set(); } }
/// <summary> /// Check if anyother pipeline is executing. /// In case of nested pipeline, checks that it is called /// from currently executing pipeline's thread. /// </summary> /// <param name="syncCall">True if method is called from Invoke, false /// if called from InvokeAsync</param> /// <param name="syncObject">The sync object on which the lock is acquired.</param> /// <param name="isInLock">True if the method is invoked in a critical section.</param> /// <exception cref="InvalidOperationException"> /// 1) A pipeline is already executing. Pipeline cannot execute /// concurrently. /// 2) InvokeAsync is called on nested pipeline. Nested pipeline /// cannot be executed Asynchronously. /// 3) Attempt is made to invoke a nested pipeline directly. Nested /// pipeline must be invoked from a running pipeline. /// </exception> internal void DoConcurrentCheck(bool syncCall, object syncObject, bool isInLock) { PipelineBase currentPipeline = (PipelineBase)RunspaceBase.GetCurrentlyRunningPipeline(); if (IsNested == false) { if (currentPipeline == null) { return; } else { // Detect if we're running a pulse pipeline, or we're running a nested pipeline // in a pulse pipeline if (currentPipeline == RunspaceBase.PulsePipeline || (currentPipeline.IsNested && RunspaceBase.PulsePipeline != null)) { // If so, wait and try again if (isInLock) { // If the method is invoked in the lock statement, release the // lock before wait on the pulse pipeline Monitor.Exit(syncObject); } try { RunspaceBase.WaitForFinishofPipelines(); } finally { if (isInLock) { // If the method is invoked in the lock statement, acquire the // lock before we carry on with the rest operations Monitor.Enter(syncObject); } } DoConcurrentCheck(syncCall, syncObject, isInLock); return; } throw PSTraceSource.NewInvalidOperationException( RunspaceStrings.ConcurrentInvokeNotAllowed); } } else { if (_performNestedCheck) { if (syncCall == false) { throw PSTraceSource.NewInvalidOperationException( RunspaceStrings.NestedPipelineInvokeAsync); } if (currentPipeline == null) { if (this.IsChild) { // OK it's not really a nested pipeline but a call with RunspaceMode=UseCurrentRunspace // This shouldn't fail so we'll clear the IsNested and IsChild flags and then return // That way executions proceeds but everything gets clean up at the end when the pipeline completes this.IsChild = false; _isNested = false; return; } throw PSTraceSource.NewInvalidOperationException( RunspaceStrings.NestedPipelineNoParentPipeline); } Dbg.Assert(currentPipeline.NestedPipelineExecutionThread != null, "Current pipeline should always have NestedPipelineExecutionThread set"); Thread th = Thread.CurrentThread; if (currentPipeline.NestedPipelineExecutionThread.Equals(th) == false) { throw PSTraceSource.NewInvalidOperationException( RunspaceStrings.NestedPipelineNoParentPipeline); } } } }
/// <summary> /// Copy constructor to support cloning /// </summary> /// <param name="pipeline">The source pipeline</param> /// <remarks> /// The copy constructor's intent is to support the scenario /// where a host needs to run the same set of commands multiple /// times. This is accomplished via creating a master pipeline /// then cloning it and executing the cloned copy. /// </remarks> protected PipelineBase(PipelineBase pipeline) : this(pipeline.Runspace, null, false, pipeline.IsNested) { // NTRAID#Windows Out Of Band Releases-915851-2005/09/13 if (null == pipeline) { throw PSTraceSource.NewArgumentNullException("pipeline"); } if (pipeline._disposed) { throw PSTraceSource.NewObjectDisposedException("pipeline"); } AddToHistory = pipeline.AddToHistory; HistoryString = pipeline.HistoryString; foreach (Command command in pipeline.Commands) { Command clone = command.Clone(); // Attach the cloned Command to this pipeline. Commands.Add(clone); } }