Sho SHIMIZU

Copy FlowOperationsProcessor defensively for thread safety

Change-Id: Ic5c920b0efc40d472d454b0e1a0305f16b39e98c
...@@ -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();
......