Copy FlowOperationsProcessor defensively for thread safety
Change-Id: Ic5c920b0efc40d472d454b0e1a0305f16b39e98c
diff --git a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
index 50d74fc..b386df4 100644
--- a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
@@ -603,12 +603,20 @@
// Mutable
private final List<Set<FlowRuleOperation>> stages;
- private final Set<DeviceId> pendingDevices = new HashSet<>();
+ private final Set<DeviceId> pendingDevices;
private boolean hasFailed = false;
FlowOperationsProcessor(FlowRuleOperations ops) {
this.stages = Lists.newArrayList(ops.stages());
this.fops = ops;
+ this.pendingDevices = new HashSet<>();
+ }
+
+ FlowOperationsProcessor(FlowOperationsProcessor src) {
+ this.fops = src.fops;
+ this.stages = Lists.newArrayList(src.stages);
+ this.pendingDevices = new HashSet<>(src.pendingDevices);
+ this.hasFailed = src.hasFailed;
}
@Override
@@ -641,7 +649,7 @@
synchronized void satisfy(DeviceId devId) {
pendingDevices.remove(devId);
if (pendingDevices.isEmpty()) {
- operationsService.execute(this);
+ operationsService.execute(new FlowOperationsProcessor(this));
}
}
@@ -649,7 +657,7 @@
hasFailed = true;
pendingDevices.remove(devId);
if (pendingDevices.isEmpty()) {
- operationsService.execute(this);
+ operationsService.execute(new FlowOperationsProcessor(this));
}
FlowRuleOperations.Builder failedOpsBuilder = FlowRuleOperations.builder();