From f752afc1cf0b850e930d146cac67aac8943cc82a Mon Sep 17 00:00:00 2001 From: Sho SHIMIZU Date: Wed, 7 Sep 2016 10:06:14 -0700 Subject: [PATCH] Copy FlowOperationsProcessor defensively for thread safety Change-Id: Ic5c920b0efc40d472d454b0e1a0305f16b39e98c --- .../onosproject/net/flow/impl/FlowRuleManager.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) 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 6a52f076b9b..2f65b7b90f0 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 @@ -582,12 +582,20 @@ private class FlowOperationsProcessor implements Runnable { // Mutable private final List> stages; - private final Set pendingDevices = new HashSet<>(); + private final Set 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 @@ -620,7 +628,7 @@ private void process(Set ops) { synchronized void satisfy(DeviceId devId) { pendingDevices.remove(devId); if (pendingDevices.isEmpty()) { - operationsService.execute(this); + operationsService.execute(new FlowOperationsProcessor(this)); } } @@ -628,7 +636,7 @@ synchronized void fail(DeviceId devId, Set failures) { hasFailed = true; pendingDevices.remove(devId); if (pendingDevices.isEmpty()) { - operationsService.execute(this); + operationsService.execute(new FlowOperationsProcessor(this)); } FlowRuleOperations.Builder failedOpsBuilder = FlowRuleOperations.builder();