2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.framework;
10 import java.io.IOException;
11 import java.nio.channels.ClosedChannelException;
12 import java.nio.channels.ClosedSelectorException;
13 import java.nio.channels.SelectionKey;
14 import java.nio.channels.Selector;
15 import java.nio.channels.spi.AbstractSelectableChannel;
16 import java.nio.channels.spi.AbstractSelector;
17 import java.util.Collections;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
23 import org.opendaylight.protocol.util.RemoveOnlySet;
24 import com.google.common.collect.Sets;
26 class SSLSelector extends AbstractSelector {
27 private static final Logger logger = LoggerFactory.getLogger(SSLSelector.class);
28 private final Set<SelectionKey> selectedKeys = Sets.newHashSet();
29 private final Set<SelectionKey> keys = Sets.newCopyOnWriteArraySet();
31 private final Set<SelectionKey> guardedSelectedKeys = RemoveOnlySet.wrap(selectedKeys);
32 private final Set<SelectionKey> guardedKeys = Collections.unmodifiableSet(keys);
33 private final Selector selector;
34 private boolean closed = false;
36 SSLSelector(final Selector selector) throws IOException {
37 super(selector.provider());
38 this.selector = selector;
42 protected void implCloseSelector() throws IOException {
43 // Make sure selection won't block
49 for (SelectionKey k : keys)
59 protected synchronized SelectionKey register(final AbstractSelectableChannel ch, final int ops, final Object att) {
62 final AbstractSelectableChannel slave;
63 if (ch instanceof SSLServerSocketChannel)
64 slave = ((SSLServerSocketChannel)ch).channel;
65 else if (ch instanceof SSLSocketChannel)
66 slave = ((SSLSocketChannel)ch).channel;
70 logger.trace("Register channel {} slave {} with ops {}", ch, slave, ops);
72 final SelectionKey key;
74 key = new SSLSelectionKey(this, slave.register(selector, 0, null), ch);
75 } catch (ClosedChannelException e) {
76 throw new IllegalStateException("Slave selector found the channel closed", e);
85 public synchronized Set<SelectionKey> keys() {
90 private void ensureOpen() {
92 throw new ClosedSelectorException();
95 private int afterSelect() {
96 logger.trace("Running afterSelect");
99 final Set<SelectionKey> ck = cancelledKeys();
101 selectedKeys.removeAll(ck);
103 for (final SelectionKey k : keys) {
104 final boolean updated = ((SSLSelectionKey)k).updateReadyOps();
105 if ((k.readyOps() & k.interestOps()) != 0) {
110 selectedKeys.remove(k);
117 private boolean beforeSelect() {
118 logger.trace("Running beforeSelect");
120 final Set<SelectionKey> ck = cancelledKeys();
122 for (final SelectionKey k : ck)
123 ((SSLSelectionKey)k).cancelSlave();
124 selectedKeys.removeAll(ck);
128 for (final SelectionKey k : keys) {
129 final SSLSelectionKey sk = (SSLSelectionKey)k;
130 if (sk.preselectReady()) {
131 logger.trace("Key {} ready in preselect", k);
134 sk.updateInterestOps();
142 public synchronized int select() throws IOException {
147 public synchronized int select(final long timeout) throws IOException {
150 if (!beforeSelect()) {
153 selector.select(timeout);
158 return afterSelect();
162 public synchronized int selectNow() throws IOException {
166 selector.selectNow();
167 return afterSelect();
171 public synchronized Set<SelectionKey> selectedKeys() {
173 return guardedSelectedKeys;
177 public Selector wakeup() {
178 logger.trace("Running wakeup");