예제 #1
0
 public SocketChannel detachChannel(long sig) {
   EventableSocketChannel ec = (EventableSocketChannel) Connections.get(sig);
   if (ec != null) {
     UnboundConnections.add(sig);
     return ec.getChannel();
   } else {
     return null;
   }
 }
예제 #2
0
  void isConnectable(SelectionKey k) {
    EventableSocketChannel ec = (EventableSocketChannel) k.attachment();
    long b = ec.getBinding();

    try {
      if (ec.finishConnecting()) eventCallback(b, EM_CONNECTION_COMPLETED, null);
      else UnboundConnections.add(b);
    } catch (IOException e) {
      UnboundConnections.add(b);
    }
  }
예제 #3
0
  public long attachChannel(SocketChannel sc, boolean watch_mode) {
    long b = createBinding();

    EventableSocketChannel ec = new EventableSocketChannel(sc, b, mySelector);

    ec.setAttached();
    if (watch_mode) ec.setWatchOnly();

    Connections.put(b, ec);
    NewConnections.add(b);

    return b;
  }
예제 #4
0
  void close() {
    try {
      if (mySelector != null) mySelector.close();
    } catch (IOException e) {
    }
    mySelector = null;

    // run down open connections and sockets.
    Iterator<ServerSocketChannel> i = Acceptors.values().iterator();
    while (i.hasNext()) {
      try {
        i.next().close();
      } catch (IOException e) {
      }
    }

    // 29Sep09: We create an ArrayList of the existing connections, then iterate over
    // that to call unbind on them. This is because an unbind can trigger a reconnect,
    // which will add to the Connections HashMap, causing a ConcurrentModificationException.
    // XXX: The correct behavior here would be to latch the various reactor methods to return
    // immediately if the reactor is shutting down.
    ArrayList<EventableChannel> conns = new ArrayList<EventableChannel>();
    Iterator<EventableChannel> i2 = Connections.values().iterator();
    while (i2.hasNext()) {
      EventableChannel ec = i2.next();
      if (ec != null) {
        conns.add(ec);
      }
    }
    Connections.clear();

    ListIterator<EventableChannel> i3 = conns.listIterator(0);
    while (i3.hasNext()) {
      EventableChannel ec = i3.next();
      eventCallback(ec.getBinding(), EM_CONNECTION_UNBOUND, null);
      ec.close();

      EventableSocketChannel sc = (EventableSocketChannel) ec;
      if (sc != null && sc.isAttached()) DetachedConnections.add(sc);
    }

    ListIterator<EventableSocketChannel> i4 = DetachedConnections.listIterator(0);
    while (i4.hasNext()) {
      EventableSocketChannel ec = i4.next();
      ec.cleanup();
    }
    DetachedConnections.clear();
  }
예제 #5
0
  void removeUnboundConnections() {
    ListIterator<Long> iter = UnboundConnections.listIterator(0);
    while (iter.hasNext()) {
      long b = iter.next();

      EventableChannel ec = Connections.remove(b);
      if (ec != null) {
        eventCallback(b, EM_CONNECTION_UNBOUND, null);
        ec.close();

        EventableSocketChannel sc = (EventableSocketChannel) ec;
        if (sc != null && sc.isAttached()) DetachedConnections.add(sc);
      }
    }
    UnboundConnections.clear();
  }
예제 #6
0
  void removeUnboundConnections() {
    if (UnboundConnections.size() == 0) {
      return;
    }
    ArrayList<Long> currentUnboundConnections = UnboundConnections;
    // fix concurrent modification exception
    UnboundConnections = new ArrayList<Long>();
    for (long b : currentUnboundConnections) {
      EventableChannel ec = Connections.remove(b);
      if (ec != null) {
        if (ProxyConnections != null) {
          ProxyConnections.remove(b);
        }
        eventCallback(b, EM_CONNECTION_UNBOUND, null);
        ec.close();

        EventableSocketChannel sc = (EventableSocketChannel) ec;
        if (sc != null && sc.isAttached()) DetachedConnections.add(sc);
      }
    }
  }
예제 #7
0
  void addNewConnections() {
    ListIterator<EventableSocketChannel> iter = DetachedConnections.listIterator(0);
    while (iter.hasNext()) {
      EventableSocketChannel ec = iter.next();
      ec.cleanup();
    }
    DetachedConnections.clear();

    ListIterator<Long> iter2 = NewConnections.listIterator(0);
    while (iter2.hasNext()) {
      long b = iter2.next();

      EventableChannel ec = Connections.get(b);
      if (ec != null) {
        try {
          ec.register();
        } catch (ClosedChannelException e) {
          UnboundConnections.add(ec.getBinding());
        }
      }
    }
    NewConnections.clear();
  }
예제 #8
0
  public long connectTcpServer(String bindAddr, int bindPort, String address, int port) {
    long b = createBinding();

    try {
      SocketChannel sc = SocketChannel.open();
      sc.configureBlocking(false);
      if (bindAddr != null) sc.socket().bind(new InetSocketAddress(bindAddr, bindPort));

      EventableSocketChannel ec = new EventableSocketChannel(sc, b, mySelector);

      if (sc.connect(new InetSocketAddress(address, port))) {
        // Connection returned immediately. Can happen with localhost connections.
        // WARNING, this code is untested due to lack of available test conditions.
        // Ought to be be able to come here from a localhost connection, but that
        // doesn't happen on Linux. (Maybe on FreeBSD?)
        // The reason for not handling this until we can test it is that we
        // really need to return from this function WITHOUT triggering any EM events.
        // That's because until the user code has seen the signature we generated here,
        // it won't be able to properly dispatch them. The C++ EM deals with this
        // by setting pending mode as a flag in ALL eventable descriptors and making
        // the descriptor select for writable. Then, it can send UNBOUND and
        // CONNECTION_COMPLETED on the next pass through the loop, because writable will
        // fire.
        throw new RuntimeException("immediate-connect unimplemented");
      } else {
        ec.setConnectPending();
        Connections.put(b, ec);
        NewConnections.add(b);
      }
    } catch (IOException e) {
      // Can theoretically come here if a connect failure can be determined immediately.
      // I don't know how to make that happen for testing purposes.
      throw new RuntimeException("immediate-connect unimplemented: " + e.toString());
    }
    return b;
  }