Skip to content

Commit

Permalink
CA-379971: Ensure ParallelAction is not waiting on _lock when no …
Browse files Browse the repository at this point in the history
…actions are running

There is a chance that all actions have completed before we hit the `Wait` call, we need to make sure we don't hit a deadlock.

This can happen if for instance there is only one action, and it is a "dummy" action, such as the one used in the EUA check.

Also I have removed the compound assignment for the `volatile _completedActionsCount` since Visual Studio was flagging it as a "suspicious usage of a volatile variable". I personally don't think it's a problem but better safe than sorry.

Contains minor whitespace fixes, too

Signed-off-by: Danilo Del Busso <[email protected]>
  • Loading branch information
danilo-delbusso committed Oct 25, 2023
1 parent 972ebf2 commit da74a6b
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions XenModel/Actions/ParallelAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class ParallelAction : MultipleAction
private readonly int _maxNumberOfParallelActions;
private readonly int _actionsCount;
private readonly object _lock = new object();
private volatile int _completedActionsCount ;
private volatile int _completedActionsCount;

/// <summary>
/// Use this constructor to create a cross connection ParallelAction.
Expand Down Expand Up @@ -124,7 +124,10 @@ protected override void RunSubActions(List<Exception> exceptions)

lock (_lock)
{
Monitor.Wait(_lock);
// CA-379971: There is a chance that all actions have completed before we
// hit the Wait call, we need to make sure we don't hit a deadlock
if (_completedActionsCount != _actionsCount)
Monitor.Wait(_lock);
}
}

Expand Down Expand Up @@ -165,7 +168,7 @@ protected override void RecalculatePercentComplete()

foreach (var connection in _actionsByConnection.Keys)
{
foreach (var action in _actionsByConnection[connection])
foreach (var action in _actionsByConnection[connection])
total += action.PercentComplete;
}

Expand All @@ -180,7 +183,7 @@ private void action_Completed(ActionBase sender)
sender.Completed -= action_Completed;
lock (_lock)
{
_completedActionsCount++;
_completedActionsCount = _completedActionsCount + 1;
if (_completedActionsCount == _actionsCount)
{
Monitor.Pulse(_lock);
Expand Down

0 comments on commit da74a6b

Please sign in to comment.