Sho SHIMIZU
Committed by Gerrit Code Review

Copy FlowOperationsProcessor defensively for thread safety

Change-Id: Ic5c920b0efc40d472d454b0e1a0305f16b39e98c
...@@ -603,12 +603,20 @@ public class FlowRuleManager ...@@ -603,12 +603,20 @@ public class FlowRuleManager
603 603
604 // Mutable 604 // Mutable
605 private final List<Set<FlowRuleOperation>> stages; 605 private final List<Set<FlowRuleOperation>> stages;
606 - private final Set<DeviceId> pendingDevices = new HashSet<>(); 606 + private final Set<DeviceId> pendingDevices;
607 private boolean hasFailed = false; 607 private boolean hasFailed = false;
608 608
609 FlowOperationsProcessor(FlowRuleOperations ops) { 609 FlowOperationsProcessor(FlowRuleOperations ops) {
610 this.stages = Lists.newArrayList(ops.stages()); 610 this.stages = Lists.newArrayList(ops.stages());
611 this.fops = ops; 611 this.fops = ops;
612 + this.pendingDevices = new HashSet<>();
613 + }
614 +
615 + FlowOperationsProcessor(FlowOperationsProcessor src) {
616 + this.fops = src.fops;
617 + this.stages = Lists.newArrayList(src.stages);
618 + this.pendingDevices = new HashSet<>(src.pendingDevices);
619 + this.hasFailed = src.hasFailed;
612 } 620 }
613 621
614 @Override 622 @Override
...@@ -641,7 +649,7 @@ public class FlowRuleManager ...@@ -641,7 +649,7 @@ public class FlowRuleManager
641 synchronized void satisfy(DeviceId devId) { 649 synchronized void satisfy(DeviceId devId) {
642 pendingDevices.remove(devId); 650 pendingDevices.remove(devId);
643 if (pendingDevices.isEmpty()) { 651 if (pendingDevices.isEmpty()) {
644 - operationsService.execute(this); 652 + operationsService.execute(new FlowOperationsProcessor(this));
645 } 653 }
646 } 654 }
647 655
...@@ -649,7 +657,7 @@ public class FlowRuleManager ...@@ -649,7 +657,7 @@ public class FlowRuleManager
649 hasFailed = true; 657 hasFailed = true;
650 pendingDevices.remove(devId); 658 pendingDevices.remove(devId);
651 if (pendingDevices.isEmpty()) { 659 if (pendingDevices.isEmpty()) {
652 - operationsService.execute(this); 660 + operationsService.execute(new FlowOperationsProcessor(this));
653 } 661 }
654 662
655 FlowRuleOperations.Builder failedOpsBuilder = FlowRuleOperations.builder(); 663 FlowRuleOperations.Builder failedOpsBuilder = FlowRuleOperations.builder();
......