Barrier turn on/off - no Barrier pipeline
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / connection / OutboundQueueEntry.java
1 /*
2  * Copyright (c) 2015 Pantheon Technologies s.r.o. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowjava.protocol.impl.core.connection;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.FutureCallback;
12 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 final class OutboundQueueEntry {
21     private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueEntry.class);
22     private FutureCallback<OfHeader> callback;
23     private OfHeader message;
24     private boolean completed;
25     private boolean barrier;
26     private volatile boolean committed;
27
28     void commit(final OfHeader message, final FutureCallback<OfHeader> callback) {
29         this.message = message;
30         this.callback = callback;
31         this.barrier = message instanceof BarrierInput;
32
33         // Volatile write, needs to be last
34         committed = true;
35     }
36
37     void reset() {
38         barrier = false;
39         callback = null;
40         completed = false;
41         message = null;
42
43         // Volatile write, needs to be last
44         committed = false;
45     }
46
47     boolean isBarrier() {
48         return barrier;
49     }
50
51     boolean isCommitted() {
52         return committed;
53     }
54
55     boolean isCompleted() {
56         return completed;
57     }
58
59     OfHeader takeMessage() {
60         final OfHeader ret = message;
61         if (!barrier) {
62             checkCompletionNeed();
63         }
64         message = null;
65         return ret;
66     }
67
68     private void checkCompletionNeed() {
69         if (callback == null || (message instanceof PacketOutInput)) {
70             completed = true;
71             if (callback != null) {
72                 callback.onSuccess(null);
73                 callback = null;
74             }
75             committed = false;
76         }
77     }
78
79     boolean complete(final OfHeader response) {
80         Preconditions.checkState(!completed, "Attempted to complete a completed message with response %s", response);
81
82         // Multipart requests are special, we have to look at them to see
83         // if there is something outstanding and adjust ourselves accordingly
84         final boolean reallyComplete;
85         if (response instanceof MultipartReplyMessage) {
86             reallyComplete = !((MultipartReplyMessage) response).getFlags().isOFPMPFREQMORE();
87             LOG.debug("Multipart reply {}", response);
88         } else {
89             reallyComplete = true;
90         }
91
92         completed = reallyComplete;
93         if (callback != null) {
94             callback.onSuccess(response);
95             if (reallyComplete) {
96                 // We will not need the callback anymore, make sure it can be GC'd
97                 callback = null;
98             }
99         }
100         LOG.debug("Entry {} completed {} with response {}", this, completed, response);
101         return reallyComplete;
102     }
103
104     void fail(final OutboundQueueException cause) {
105         if (!completed) {
106             completed = true;
107             if (callback != null) {
108                 callback.onFailure(cause);
109                 callback = null;
110             }
111         } else {
112             LOG.warn("Ignoring failure {} for completed message", cause);
113         }
114     }
115 }