Copy FlowOperationsProcessor defensively for thread safety
Change-Id: Ic5c920b0efc40d472d454b0e1a0305f16b39e98c
Showing
1 changed file
with
11 additions
and
3 deletions
... | @@ -582,12 +582,20 @@ public class FlowRuleManager | ... | @@ -582,12 +582,20 @@ public class FlowRuleManager |
582 | 582 | ||
583 | // Mutable | 583 | // Mutable |
584 | private final List<Set<FlowRuleOperation>> stages; | 584 | private final List<Set<FlowRuleOperation>> stages; |
585 | - private final Set<DeviceId> pendingDevices = new HashSet<>(); | 585 | + private final Set<DeviceId> pendingDevices; |
586 | private boolean hasFailed = false; | 586 | private boolean hasFailed = false; |
587 | 587 | ||
588 | FlowOperationsProcessor(FlowRuleOperations ops) { | 588 | FlowOperationsProcessor(FlowRuleOperations ops) { |
589 | this.stages = Lists.newArrayList(ops.stages()); | 589 | this.stages = Lists.newArrayList(ops.stages()); |
590 | this.fops = ops; | 590 | this.fops = ops; |
591 | + this.pendingDevices = new HashSet<>(); | ||
592 | + } | ||
593 | + | ||
594 | + FlowOperationsProcessor(FlowOperationsProcessor src) { | ||
595 | + this.fops = src.fops; | ||
596 | + this.stages = Lists.newArrayList(src.stages); | ||
597 | + this.pendingDevices = new HashSet<>(src.pendingDevices); | ||
598 | + this.hasFailed = src.hasFailed; | ||
591 | } | 599 | } |
592 | 600 | ||
593 | @Override | 601 | @Override |
... | @@ -620,7 +628,7 @@ public class FlowRuleManager | ... | @@ -620,7 +628,7 @@ public class FlowRuleManager |
620 | synchronized void satisfy(DeviceId devId) { | 628 | synchronized void satisfy(DeviceId devId) { |
621 | pendingDevices.remove(devId); | 629 | pendingDevices.remove(devId); |
622 | if (pendingDevices.isEmpty()) { | 630 | if (pendingDevices.isEmpty()) { |
623 | - operationsService.execute(this); | 631 | + operationsService.execute(new FlowOperationsProcessor(this)); |
624 | } | 632 | } |
625 | } | 633 | } |
626 | 634 | ||
... | @@ -628,7 +636,7 @@ public class FlowRuleManager | ... | @@ -628,7 +636,7 @@ public class FlowRuleManager |
628 | hasFailed = true; | 636 | hasFailed = true; |
629 | pendingDevices.remove(devId); | 637 | pendingDevices.remove(devId); |
630 | if (pendingDevices.isEmpty()) { | 638 | if (pendingDevices.isEmpty()) { |
631 | - operationsService.execute(this); | 639 | + operationsService.execute(new FlowOperationsProcessor(this)); |
632 | } | 640 | } |
633 | 641 | ||
634 | FlowRuleOperations.Builder failedOpsBuilder = FlowRuleOperations.builder(); | 642 | FlowRuleOperations.Builder failedOpsBuilder = FlowRuleOperations.builder(); | ... | ... |
-
Please register or login to post a comment