Activate code generation
[bgpcep.git] / framework / src / main / java / org / opendaylight / protocol / framework / SSLSelectionKey.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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.protocol.framework;
9
10 import java.io.IOException;
11 import java.nio.channels.CancelledKeyException;
12 import java.nio.channels.SelectableChannel;
13 import java.nio.channels.SelectionKey;
14 import java.nio.channels.Selector;
15 import java.nio.channels.spi.AbstractSelectionKey;
16
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 class SSLSelectionKey extends AbstractSelectionKey {
21         private static final Logger logger = LoggerFactory.getLogger(SSLSelectionKey.class);
22         private final SelectableChannel channel;
23         private final Selector selector;
24         private final SelectionKey key;
25         private int ops = 0, readyOps = 0;
26
27         SSLSelectionKey(final Selector selector, final SelectionKey key, final SelectableChannel channel) {
28                 this.selector = selector;
29                 this.channel = channel;
30                 this.key = key;
31         }
32
33         @Override
34         public SelectableChannel channel() {
35                 return channel;
36         }
37
38         @Override
39         public int interestOps() {
40                 return ops;
41         }
42
43         @Override
44         public SelectionKey interestOps(final int ops) {
45                 this.ops = ops;
46                 return this;
47         }
48
49         @Override
50         public int readyOps() {
51                 return readyOps;
52         }
53
54         @Override
55         public Selector selector() {
56                 return selector;
57         }
58
59         void cancelSlave() {
60                 key.cancel();
61         }
62
63         void updateInterestOps() {
64                 int newOps = ops;
65
66                 if (channel instanceof SSLSocketChannel) {
67                         newOps = ((SSLSocketChannel)channel).computeInterestOps(ops);
68                 } else if (channel instanceof SSLServerSocketChannel) {
69                         newOps = ((SSLServerSocketChannel)channel).computeInterestOps(ops);
70                 }
71
72                 logger.trace("Updating interestOps to {} (before SSL={})", newOps, ops);
73
74                 // FIXME: is this check sufficient?
75                 if (key.isValid())
76                         key.interestOps(newOps);
77         }
78
79         boolean preselectReady() {
80                 final int newReadyOps;
81
82                 // FIXME: abstract out interface
83                 if (channel instanceof SSLSocketChannel) {
84                         final SSLSocketChannel sc = (SSLSocketChannel)channel;
85                         newReadyOps = sc.computeReadyOps();
86
87                         if (sc.hasParent()) {
88                                 logger.trace("Child key, ready {}", newReadyOps);
89                                 if ((newReadyOps & SelectionKey.OP_CONNECT) != 0) {
90                                         try {
91                                                 if (sc.finishConnect()) {
92                                                         this.cancel();
93                                                         return true;
94                                                 } else
95                                                         logger.trace("finishConnect indicated non-connect after poll. Possible leak.");
96                                         } catch (IOException e) {
97                                                 logger.trace("Failed to establish child socket", e);
98                                                 this.cancel();
99                                         }
100                                 }
101                                 return false;
102                         }
103                 } else if (channel instanceof SSLServerSocketChannel) {
104                         newReadyOps = ((SSLServerSocketChannel)channel).computeReadyOps();
105                 } else
106                         newReadyOps = 0;
107
108                 logger.trace("Preselect: ready {} interest {} (A: {} R: {} W: {})",
109                                 newReadyOps, ops, SelectionKey.OP_CONNECT, SelectionKey.OP_READ, SelectionKey.OP_WRITE);
110                 return (newReadyOps & ops) != 0;
111         }
112
113         boolean updateReadyOps() {
114                 int newReadyOps = 0;
115                 if (channel instanceof SSLServerSocketChannel) {
116                         newReadyOps = ((SSLServerSocketChannel)channel).computeReadyOps();
117                 } else if (channel instanceof SSLSocketChannel) {
118                         final SSLSocketChannel sc = (SSLSocketChannel)channel;
119
120                         // Do not report events for internal channels
121                         if (!sc.hasParent())
122                                 newReadyOps = sc.computeReadyOps();
123                 } else {
124                         try {
125                                 newReadyOps = key.readyOps();
126                         } catch (CancelledKeyException e) {
127                                 logger.trace("Encountered cancelled key, ignoring", e);
128                         }
129                 }
130
131                 if (readyOps == newReadyOps)
132                         return false;
133
134                 logger.trace("Updating readyOps from {} to {}", readyOps, newReadyOps);
135                 readyOps = newReadyOps;
136                 return true;
137         }
138 }
139