private void StartChildJobIfPossible()
        {
            StartableJob readyToRunChildJob = null;

            lock (_lockObject)
            {
                do
                {
                    if ((_readyToRunQueryJobs.Count > 0) &&
                        (_extraCapacityForRunningQueryJobs > 0) &&
                        (_extraCapacityForRunningAllJobs > 0))
                    {
                        _extraCapacityForRunningQueryJobs--;
                        _extraCapacityForRunningAllJobs--;
                        readyToRunChildJob = _readyToRunQueryJobs.Dequeue();
                        break;
                    }

                    if ((_readyToRunRegularJobs.Count > 0) &&
                        (_extraCapacityForRunningAllJobs > 0))
                    {
                        _extraCapacityForRunningAllJobs--;
                        readyToRunChildJob = _readyToRunRegularJobs.Dequeue();
                        break;
                    }
                } while (false);
            }

            if (readyToRunChildJob != null)
            {
                readyToRunChildJob.StartJob();
            }
        }
        private void EnqueueReadyToRunChildJob(StartableJob childJob)
        {
            lock (_lockObject)
            {
                bool isQueryJob = _setOfChildJobsThatCanAddMoreChildJobs.Contains(childJob.InstanceId);
                if (isQueryJob &&
                    !_inBoostModeToPreventQueryJobDeadlock &&
                    (_maximumConcurrentChildJobs == 1))
                {
                    _inBoostModeToPreventQueryJobDeadlock = true;
                    _extraCapacityForRunningAllJobs++;
                }

                if (isQueryJob)
                {
                    _readyToRunQueryJobs.Enqueue(childJob);
                }
                else
                {
                    _readyToRunRegularJobs.Enqueue(childJob);
                }
            }

            StartChildJobIfPossible();
        }
Пример #3
0
        internal void AddChildJobWithoutBlocking(StartableJob childJob, ChildJobFlags flags, Action jobEnqueuedAction = null)
        {
            if (childJob == null)
            {
                throw new ArgumentNullException("childJob");
            }
            if (childJob.JobStateInfo.State != JobState.NotStarted)
            {
                throw new ArgumentException(RemotingErrorIdStrings.ThrottlingJobChildAlreadyRunning, "childJob");
            }
            base.AssertNotDisposed();
            JobStateInfo info = null;

            lock (this._lockObject)
            {
                if (this.IsEndOfChildJobs)
                {
                    throw new InvalidOperationException(RemotingErrorIdStrings.ThrottlingJobChildAddedAfterEndOfChildJobs);
                }
                if (this._isStopping)
                {
                    return;
                }
                if (this._countOfAllChildJobs == 0)
                {
                    info = new JobStateInfo(JobState.Running);
                }
                if (ChildJobFlags.CreatesChildJobs == (ChildJobFlags.CreatesChildJobs & flags))
                {
                    this._setOfChildJobsThatCanAddMoreChildJobs.Add(childJob.InstanceId);
                }
                base.ChildJobs.Add(childJob);
                this._childJobLocations.Add(childJob.Location);
                this._countOfAllChildJobs++;
                this.WriteWarningAboutHighUsageOfFlowControlBuffers((long)this.CountOfRunningOrReadyToRunChildJobs);
                if (this.CountOfRunningOrReadyToRunChildJobs > this._maxReadyToRunJobs)
                {
                    this._actionsForUnblockingChildAdditions.Enqueue(jobEnqueuedAction);
                }
                else if (jobEnqueuedAction != null)
                {
                    jobEnqueuedAction();
                }
            }
            if (info != null)
            {
                base.SetJobState(info.State, info.Reason);
            }
            this.ChildJobAdded.SafeInvoke <ThrottlingJobChildAddedEventArgs>(this, new ThrottlingJobChildAddedEventArgs(childJob));
            childJob.SetParentActivityIdGetter(new Func <int>(this.GetProgressActivityId));
            childJob.StateChanged += new EventHandler <JobStateEventArgs>(this.childJob_StateChanged);
            if (this._cmdletMode)
            {
                childJob.Results.DataAdded += new EventHandler <DataAddedEventArgs>(this.childJob_ResultsAdded);
            }
            this.EnqueueReadyToRunChildJob(childJob);
            this.ReportProgress(true);
        }
Пример #4
0
 internal void AddChildJobAndPotentiallyBlock(Cmdlet cmdlet, StartableJob childJob, ChildJobFlags flags)
 {
     using (CancellationTokenSource source = new CancellationTokenSource())
     {
         if (childJob == null)
         {
             throw new ArgumentNullException("childJob");
         }
         this.AddChildJobWithoutBlocking(childJob, flags, new Action(source.Cancel));
         this.ForwardAllResultsToCmdlet(cmdlet, new CancellationToken?(source.Token));
     }
 }
Пример #5
0
 internal void AddChildJobAndPotentiallyBlock(StartableJob childJob, ChildJobFlags flags)
 {
     using (ManualResetEventSlim slim = new ManualResetEventSlim(false))
     {
         if (childJob == null)
         {
             throw new ArgumentNullException("childJob");
         }
         this.AddChildJobWithoutBlocking(childJob, flags, new Action(slim.Set));
         slim.Wait();
     }
 }
Пример #6
0
 internal void AddChildJobAndPotentiallyBlock(Cmdlet cmdlet, StartableJob childJob, ChildJobFlags flags)
 {
     using (CancellationTokenSource source = new CancellationTokenSource())
     {
         if (childJob == null)
         {
             throw new ArgumentNullException("childJob");
         }
         this.AddChildJobWithoutBlocking(childJob, flags, new Action(source.Cancel));
         this.ForwardAllResultsToCmdlet(cmdlet, new CancellationToken?(source.Token));
     }
 }
Пример #7
0
 internal void AddChildJobAndPotentiallyBlock(StartableJob childJob, ChildJobFlags flags)
 {
     using (ManualResetEventSlim slim = new ManualResetEventSlim(false))
     {
         if (childJob == null)
         {
             throw new ArgumentNullException("childJob");
         }
         this.AddChildJobWithoutBlocking(childJob, flags, new Action(slim.Set));
         slim.Wait();
     }
 }
        internal void AddChildJobAndPotentiallyBlock(
            StartableJob childJob,
            ChildJobFlags flags)
        {
            using (var jobGotEnqueued = new ManualResetEventSlim(initialState: false))
            {
                if (childJob == null)
                {
                    throw new ArgumentNullException(nameof(childJob));
                }

                this.AddChildJobWithoutBlocking(childJob, flags, jobGotEnqueued.Set);
                jobGotEnqueued.Wait();
            }
        }
        internal void AddChildJobAndPotentiallyBlock(
            Cmdlet cmdlet,
            StartableJob childJob,
            ChildJobFlags flags)
        {
            using (var forwardingCancellation = new CancellationTokenSource())
            {
                if (childJob == null)
                {
                    throw new ArgumentNullException(nameof(childJob));
                }

                this.AddChildJobWithoutBlocking(childJob, flags, forwardingCancellation.Cancel);
                this.ForwardAllResultsToCmdlet(cmdlet, forwardingCancellation.Token);
            }
        }
Пример #10
0
 private void EnqueueReadyToRunChildJob(StartableJob childJob)
 {
     lock (this._lockObject)
     {
         bool flag = this._setOfChildJobsThatCanAddMoreChildJobs.Contains(childJob.InstanceId);
         if ((flag && !this._inBoostModeToPreventQueryJobDeadlock) && (this._maximumConcurrentChildJobs == 1))
         {
             this._inBoostModeToPreventQueryJobDeadlock = true;
             this._extraCapacityForRunningAllJobs++;
         }
         if (flag)
         {
             this._readyToRunQueryJobs.Enqueue(childJob);
         }
         else
         {
             this._readyToRunRegularJobs.Enqueue(childJob);
         }
     }
     this.StartChildJobIfPossible();
 }
Пример #11
0
        private void StartChildJobIfPossible()
        {
            StartableJob job = null;

            lock (this._lockObject)
            {
                if (((this._readyToRunQueryJobs.Count > 0) && (this._extraCapacityForRunningQueryJobs > 0)) && (this._extraCapacityForRunningAllJobs > 0))
                {
                    this._extraCapacityForRunningQueryJobs--;
                    this._extraCapacityForRunningAllJobs--;
                    job = this._readyToRunQueryJobs.Dequeue();
                }
                else if ((this._readyToRunRegularJobs.Count > 0) && (this._extraCapacityForRunningAllJobs > 0))
                {
                    this._extraCapacityForRunningAllJobs--;
                    job = this._readyToRunRegularJobs.Dequeue();
                }
            }
            if (job != null)
            {
                job.StartJob();
            }
        }
        /// <summary>
        /// Adds and starts a child job.
        /// </summary>
        /// <param name="childJob">Child job to add.</param>
        /// <param name="flags">Flags of the child job.</param>
        /// <param name="jobEnqueuedAction">Action to run after enqueuing the job.</param>
        /// <exception cref="ArgumentException">
        /// Thrown when the child job is not in the <see cref="JobState.NotStarted"/> state.
        /// (because this can lead to race conditions - the child job can finish before the parent job has a chance to register for child job events)
        /// </exception>
        internal void AddChildJobWithoutBlocking(StartableJob childJob, ChildJobFlags flags, Action jobEnqueuedAction = null)
        {
            if (childJob == null)
            {
                throw new ArgumentNullException(nameof(childJob));
            }
            if (childJob.JobStateInfo.State != JobState.NotStarted)
            {
                throw new ArgumentException(RemotingErrorIdStrings.ThrottlingJobChildAlreadyRunning, nameof(childJob));
            }
            this.AssertNotDisposed();

            JobStateInfo newJobStateInfo = null;

            lock (_lockObject)
            {
                if (this.IsEndOfChildJobs)
                {
                    throw new InvalidOperationException(RemotingErrorIdStrings.ThrottlingJobChildAddedAfterEndOfChildJobs);
                }
                if (_isStopping)
                {
                    return;
                }

                if (_countOfAllChildJobs == 0)
                {
                    newJobStateInfo = new JobStateInfo(JobState.Running);
                }

                if ((ChildJobFlags.CreatesChildJobs & flags) == ChildJobFlags.CreatesChildJobs)
                {
                    _setOfChildJobsThatCanAddMoreChildJobs.Add(childJob.InstanceId);
                }

                this.ChildJobs.Add(childJob);
                _childJobLocations.Add(childJob.Location);
                _countOfAllChildJobs++;

                this.WriteWarningAboutHighUsageOfFlowControlBuffers(this.CountOfRunningOrReadyToRunChildJobs);
                if (this.CountOfRunningOrReadyToRunChildJobs > _maxReadyToRunJobs)
                {
                    _actionsForUnblockingChildAdditions.Enqueue(jobEnqueuedAction);
                }
                else
                {
                    jobEnqueuedAction?.Invoke();
                }
            }

            if (newJobStateInfo != null)
            {
                this.SetJobState(newJobStateInfo.State, newJobStateInfo.Reason);
            }

            this.ChildJobAdded.SafeInvoke(this, new ThrottlingJobChildAddedEventArgs(childJob));

            childJob.SetParentActivityIdGetter(this.GetProgressActivityId);
            childJob.StateChanged += this.childJob_StateChanged;
            if (_cmdletMode)
            {
                childJob.Results.DataAdded += childJob_ResultsAdded;
            }

            this.EnqueueReadyToRunChildJob(childJob);

            this.ReportProgress(minimizeFrequentUpdates: true);
        }
Пример #13
0
 internal void AddChildJobWithoutBlocking(StartableJob childJob, ChildJobFlags flags, Action jobEnqueuedAction = null)
 {
     if (childJob == null)
     {
         throw new ArgumentNullException("childJob");
     }
     if (childJob.JobStateInfo.State != JobState.NotStarted)
     {
         throw new ArgumentException(RemotingErrorIdStrings.ThrottlingJobChildAlreadyRunning, "childJob");
     }
     base.AssertNotDisposed();
     JobStateInfo info = null;
     lock (this._lockObject)
     {
         if (this.IsEndOfChildJobs)
         {
             throw new InvalidOperationException(RemotingErrorIdStrings.ThrottlingJobChildAddedAfterEndOfChildJobs);
         }
         if (this._isStopping)
         {
             return;
         }
         if (this._countOfAllChildJobs == 0)
         {
             info = new JobStateInfo(JobState.Running);
         }
         if (ChildJobFlags.CreatesChildJobs == (ChildJobFlags.CreatesChildJobs & flags))
         {
             this._setOfChildJobsThatCanAddMoreChildJobs.Add(childJob.InstanceId);
         }
         base.ChildJobs.Add(childJob);
         this._childJobLocations.Add(childJob.Location);
         this._countOfAllChildJobs++;
         this.WriteWarningAboutHighUsageOfFlowControlBuffers((long) this.CountOfRunningOrReadyToRunChildJobs);
         if (this.CountOfRunningOrReadyToRunChildJobs > this._maxReadyToRunJobs)
         {
             this._actionsForUnblockingChildAdditions.Enqueue(jobEnqueuedAction);
         }
         else if (jobEnqueuedAction != null)
         {
             jobEnqueuedAction();
         }
     }
     if (info != null)
     {
         base.SetJobState(info.State, info.Reason);
     }
     this.ChildJobAdded.SafeInvoke<ThrottlingJobChildAddedEventArgs>(this, new ThrottlingJobChildAddedEventArgs(childJob));
     childJob.SetParentActivityIdGetter(new Func<int>(this.GetProgressActivityId));
     childJob.StateChanged += new EventHandler<JobStateEventArgs>(this.childJob_StateChanged);
     if (this._cmdletMode)
     {
         childJob.Results.DataAdded += new EventHandler<DataAddedEventArgs>(this.childJob_ResultsAdded);
     }
     this.EnqueueReadyToRunChildJob(childJob);
     this.ReportProgress(true);
 }
Пример #14
0
 private void EnqueueReadyToRunChildJob(StartableJob childJob)
 {
     lock (this._lockObject)
     {
         bool flag = this._setOfChildJobsThatCanAddMoreChildJobs.Contains(childJob.InstanceId);
         if ((flag && !this._inBoostModeToPreventQueryJobDeadlock) && (this._maximumConcurrentChildJobs == 1))
         {
             this._inBoostModeToPreventQueryJobDeadlock = true;
             this._extraCapacityForRunningAllJobs++;
         }
         if (flag)
         {
             this._readyToRunQueryJobs.Enqueue(childJob);
         }
         else
         {
             this._readyToRunRegularJobs.Enqueue(childJob);
         }
     }
     this.StartChildJobIfPossible();
 }
Пример #15
0
        private void EnqueueReadyToRunChildJob(StartableJob childJob)
        {
            lock (_lockObject)
            {
                bool isQueryJob = _setOfChildJobsThatCanAddMoreChildJobs.Contains(childJob.InstanceId);
                if (isQueryJob &&
                    !_inBoostModeToPreventQueryJobDeadlock &&
                    (_maximumConcurrentChildJobs == 1))
                {
                    _inBoostModeToPreventQueryJobDeadlock = true;
                    _extraCapacityForRunningAllJobs++;
                }

                if (isQueryJob)
                {
                    _readyToRunQueryJobs.Enqueue(childJob);
                }
                else
                {
                    _readyToRunRegularJobs.Enqueue(childJob);
                }
            }

            StartChildJobIfPossible();
        }
Пример #16
0
        internal void AddChildJobAndPotentiallyBlock(
            StartableJob childJob,
            ChildJobFlags flags)
        {
            using (var jobGotEnqueued = new ManualResetEventSlim(initialState: false))
            {
                if (childJob == null) throw new ArgumentNullException("childJob");

                this.AddChildJobWithoutBlocking(childJob, flags, jobGotEnqueued.Set);
                jobGotEnqueued.Wait();
            }
        }