Ejemplo n.º 1
0
        /// <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);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Invoke the pipeline asynchronously with input.
        /// </summary>
        /// <param name="input">input to provide to pipeline. Input is
        /// used only for synchronous execution</param>
        /// <param name="syncCall">True if this method is called from
        /// synchronous invoke else false</param>
        /// <remarks>
        /// Results are returned through the <see cref="Pipeline.Output"/> reader.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        /// No command is added to pipeline
        /// </exception>
        /// <exception cref="InvalidPipelineStateException">
        /// PipelineState is not NotStarted.
        /// </exception>
        /// <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>
        /// <exception cref="InvalidRunspaceStateException">
        /// RunspaceState is not Open
        /// </exception>
        /// <exception cref="ObjectDisposedException">
        /// Pipeline already disposed
        /// </exception>
        private void CoreInvoke(IEnumerable input, bool syncCall)
        {
            lock (SyncRoot)
            {
                // NTRAID#Windows Out Of Band Releases-915851-2005/09/13
                if (_disposed)
                {
                    throw PSTraceSource.NewObjectDisposedException("pipeline");
                }

                if (Commands == null || Commands.Count == 0)
                {
                    throw PSTraceSource.NewInvalidOperationException(
                              RunspaceStrings.NoCommandInPipeline);
                }

                if (PipelineState != PipelineState.NotStarted)
                {
                    InvalidPipelineStateException e =
                        new InvalidPipelineStateException
                        (
                            StringUtil.Format(RunspaceStrings.PipelineReInvokeNotAllowed),
                            PipelineState,
                            PipelineState.NotStarted
                        );
                    throw e;
                }

                if (syncCall && !(InputStream is PSDataCollectionStream <PSObject> || InputStream is PSDataCollectionStream <object>))
                {
                    // Method is called from synchronous invoke.
                    if (input != null)
                    {
                        // TO-DO-Add a test make sure that ObjectDisposed
                        // exception is thrown
                        // Write input data in to inputStream and close the input
                        // pipe. If Input stream is already closed an
                        // ObjectDisposed exception will be thrown
                        foreach (object temp in input)
                        {
                            InputStream.Write(temp);
                        }
                    }

                    InputStream.Close();
                }

                SyncInvokeCall = syncCall;

                // Create event which will be signalled when pipeline execution
                // is completed/failed/stoped.
                // Note:Runspace.Close waits for all the running pipeline
                // to finish.  This Event must be created before pipeline is
                // added to list of running pipelines. This avoids the race condition
                // where Close is called after pipeline is added to list of
                // running pipeline but before event is created.
                PipelineFinishedEvent = new ManualResetEvent(false);

                // 1) Do the check to ensure that pipeline no other
                // pipeline is running.
                // 2) Runspace object maintains a list of pipelines in
                // execution. Add this pipeline to the list.
                RunspaceBase.DoConcurrentCheckAndAddToRunningPipelines(this, syncCall);

                // Note: Set PipelineState to Running only after adding pipeline to list
                // of pipelines in execution. AddForExecution checks that runspace is in
                // state where pipeline can be run.
                // StartPipelineExecution raises this event. See Windows Bug 1160481 for
                // more details.
                SetPipelineState(PipelineState.Running);
            }

            try
            {
                // Let the derived class start the pipeline execution.
                StartPipelineExecution();
            }
            catch (Exception exception)
            {
                // If we fail in any of the above three steps, set the correct states.
                RunspaceBase.RemoveFromRunningPipelineList(this);
                SetPipelineState(PipelineState.Failed, exception);

                // Note: we are not raising the events in this case. However this is
                // fine as user is getting the exception.
                throw;
            }
        }
Ejemplo n.º 3
0
 internal SessionStateProxy(RunspaceBase runspace)
 {
     this._runspace = runspace;
 }
Ejemplo n.º 4
0
 internal SessionStateProxy(RunspaceBase runspace)
 {
     this._runspace = runspace;
 }
Ejemplo n.º 5
0
 internal SessionStateProxy(RunspaceBase runspace)
 {
     Dbg.Assert(runspace != null, "Caller should validate the parameter");
     _runspace = runspace;
 }