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