Пример #1
0
 public int ready() throws IOException {
   if (descriptor.getChannel() instanceof SelectableChannel) {
     int ready_stat = 0;
     java.nio.channels.Selector sel =
         SelectorFactory.openWithRetryFrom(
             null, ((SelectableChannel) descriptor.getChannel()).provider());
     SelectableChannel selchan = (SelectableChannel) descriptor.getChannel();
     synchronized (selchan.blockingLock()) {
       boolean is_block = selchan.isBlocking();
       try {
         selchan.configureBlocking(false);
         selchan.register(sel, java.nio.channels.SelectionKey.OP_READ);
         ready_stat = sel.selectNow();
         sel.close();
       } catch (Throwable ex) {
       } finally {
         if (sel != null) {
           try {
             sel.close();
           } catch (Exception e) {
           }
         }
         selchan.configureBlocking(is_block);
       }
     }
     return ready_stat;
   } else {
     return newInputStream().available();
   }
 }
Пример #2
0
  public static void main(String[] argv) throws Exception {
    Pipe[] pipes = new Pipe[PIPES_COUNT];
    Pipe pipe = Pipe.open();
    Pipe.SinkChannel sink = pipe.sink();
    Pipe.SourceChannel source = pipe.source();
    Selector sel = Selector.open();
    source.configureBlocking(false);
    source.register(sel, SelectionKey.OP_READ);

    for (int i = 0; i < PIPES_COUNT; i++) {
      pipes[i] = Pipe.open();
      Pipe.SourceChannel sc = pipes[i].source();
      sc.configureBlocking(false);
      sc.register(sel, SelectionKey.OP_READ);
      Pipe.SinkChannel sc2 = pipes[i].sink();
      sc2.configureBlocking(false);
      sc2.register(sel, SelectionKey.OP_WRITE);
    }

    for (int i = 0; i < LOOPS; i++) {
      sink.write(ByteBuffer.allocate(BUF_SIZE));
      int x = sel.selectNow();
      sel.selectedKeys().clear();
      source.read(ByteBuffer.allocate(BUF_SIZE));
    }

    for (int i = 0; i < PIPES_COUNT; i++) {
      pipes[i].sink().close();
      pipes[i].source().close();
    }
    pipe.sink().close();
    pipe.source().close();
    sel.close();
  }
 private void driveClientIO() throws IOException, GearmanException {
   for (GearmanJobServerSession sess : sessionsMap.values()) {
     int interestOps = SelectionKey.OP_READ;
     if (sess.sessionHasDataToWrite()) {
       interestOps |= SelectionKey.OP_WRITE;
     }
     try {
       sess.getSelectionKey().interestOps(interestOps);
     } catch (IllegalStateException ise) {
       LOG.warn("Unable to drive IO for session " + sess + "," + " skipping.", ise);
       continue;
     }
   }
   ioAvailable.selectNow();
   Set<SelectionKey> keys = ioAvailable.selectedKeys();
   LOG.trace(
       "Driving IO for client "
           + this
           + ". "
           + keys.size()
           + " session(s) currently available for IO");
   Iterator<SelectionKey> iter = keys.iterator();
   while (iter.hasNext()) {
     SelectionKey key = iter.next();
     GearmanJobServerSession s = sessionsMap.get(key);
     s.driveSessionIO();
   }
 }
Пример #4
0
    /**
     * The background thread that adds sockets to the Poller, checks the poller for triggered events
     * and hands the associated socket off to an appropriate processor as events occur.
     */
    @Override
    public void run() {
      // Loop until destroy() is called
      while (true) {

        boolean hasEvents = false;

        try {
          if (!close) {
            hasEvents = events();
            if (wakeupCounter.getAndSet(-1) > 0) {
              // if we are here, means we have other stuff to do
              // do a non blocking select
              keyCount = selector.selectNow();
            } else {
              keyCount = selector.select(selectorTimeout);
            }
            wakeupCounter.set(0);
          }
          if (close) {
            events();
            timeout(0, false);
            try {
              selector.close();
            } catch (IOException ioe) {
              log.error(sm.getString("endpoint.nio.selectorCloseFail"), ioe);
            }
            break;
          }
        } catch (Throwable x) {
          ExceptionUtils.handleThrowable(x);
          log.error("", x);
          continue;
        }
        // either we timed out or we woke up, process events first
        if (keyCount == 0) hasEvents = (hasEvents | events());

        Iterator<SelectionKey> iterator = keyCount > 0 ? selector.selectedKeys().iterator() : null;
        // Walk through the collection of ready keys and dispatch
        // any active event.
        while (iterator != null && iterator.hasNext()) {
          SelectionKey sk = iterator.next();
          NioSocketWrapper attachment = (NioSocketWrapper) sk.attachment();
          // Attachment may be null if another thread has called
          // cancelledKey()
          if (attachment == null) {
            iterator.remove();
          } else {
            iterator.remove();
            processKey(sk, attachment);
          }
        } // while

        // process timeouts
        timeout(keyCount, hasEvents);
      } // while

      stopLatch.countDown();
    }
Пример #5
0
 /**
  * Execute the Selector.select(...) operations.
  *
  * @param ctx {@link Context}
  * @return {@link Set} of {@link SelectionKey}
  */
 public Set<SelectionKey> select(Context ctx) throws IOException {
   if (postponedTasks.isEmpty()) {
     selector.select(selectTimeout);
   } else {
     selector.selectNow();
   }
   return selector.selectedKeys();
 }
Пример #6
0
 private boolean cleanUpCancelledKeys() throws IOException {
   if (cancelledKeys >= CLEANUP_INTERVAL) {
     cancelledKeys = 0;
     selector.selectNow();
     return true;
   }
   return false;
 }
Пример #7
0
  public boolean processNow() throws IOException {
    int numKeys = selector.selectNow();

    if (selector.keys().isEmpty()) return false;

    if (numKeys > 0) dispatchMessages();

    return true;
  }
Пример #8
0
  /**
   * Release the selection key, working around for bug #6403933.
   *
   * @param selector The associated selector.
   * @param selectionKey The used selection key.
   * @throws IOException
   */
  public static void release(Selector selector, SelectionKey selectionKey) throws IOException {
    if (selectionKey != null) {
      // The key you registered on the temporary selector
      selectionKey.cancel();

      if (selector != null) {
        // Flush the canceled key
        selector.selectNow();
        SelectorFactory.returnSelector(selector);
      }
    }
  }
Пример #9
0
  protected final boolean cleanUpCancelledKeys() {
    try {
      if (cancelledKeys >= CLEANUP_INTERVAL) {
        cancelledKeys = 0;
        nioSelector.selectNow();

        return true;
      }
    } catch (IOException e) {
      // select exception
    }
    return false;
  }
Пример #10
0
 /**
  * Loops through all of the selected network events and determines which ones are ready to be
  * handled, and executes them if so.
  */
 public void sequence() {
   try {
     selector.selectNow();
     Iterator<SelectionKey> $it = selector.selectedKeys().iterator();
     while ($it.hasNext()) {
       ServerSelectionKey key = new ServerSelectionKey($it.next(), selector, channel);
       Optional<ServerSelectionEvent> event = key.determineEvent();
       event.ifPresent(e -> e.execute(key));
       $it.remove();
     }
   } catch (Exception e) {
     logger.log(Level.SEVERE, "An error has occured while selecting network events!", e);
   }
 }
 @Override
 public boolean keepalive() throws RemoteException {
   try {
     boolean result = false;
     for (Iterator<
                 Entry<Member, org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface>>
             i = nioSenders.entrySet().iterator();
         i.hasNext(); ) {
       Map.Entry<Member, org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface> entry =
           i.next();
       org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface sender = entry.getValue();
       if (sender.keepalive()) {
         // nioSenders.remove(entry.getKey());
         i.remove();
         result = true;
       } else {
         try {
           sender.read(null);
         } catch (IOException x) {
           sender.disconnect();
           sender.reset();
           // nioSenders.remove(entry.getKey());
           i.remove();
           result = true;
         } catch (Exception x) {
           log.warn("Error during keepalive test for sender:" + sender, x);
         }
       }
     }
     // clean up any cancelled keys
     if (result)
       try {
         selector.selectNow();
       } catch (Exception e) {
         /* Ignore */
       }
     return result;
   } catch (Exception excp) {
     excp.printStackTrace();
   }
   return true;
 }
Пример #12
0
  void processConnections() {

    synchronized (this.pendingStateChanges) {
      Iterator<ChangeRequest> changes = this.pendingStateChanges.iterator();

      while (changes.hasNext()) {
        ChangeRequest change = (ChangeRequest) changes.next();
        SelectionKey key = change.getSocket().keyFor(this.selector);
        key.interestOps(change.getOps());
      }
      this.pendingStateChanges.clear();
    }

    try {
      selector.selectNow();
    } catch (IOException e) {
      LOG.severe("Couldn't select channels.");
    }

    processSelectedKeys();

    selector.selectedKeys().clear();
  }
Пример #13
0
  void checkIO() {
    long timeout;

    if (NewConnections.size() > 0) {
      timeout = -1;
    } else if (!Timers.isEmpty()) {
      long now = new Date().getTime();
      long k = Timers.firstKey();
      long diff = k - now;

      if (diff <= 0) timeout = -1; // don't wait, just poll once
      else timeout = diff;
    } else {
      timeout = 0; // wait indefinitely
    }

    try {
      if (timeout == -1) mySelector.selectNow();
      else mySelector.select(timeout);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
Пример #14
0
  public static void checkClients(List<SocketChannel> anonymousClients) {
    try {

      if (selector.selectNow() == 0) {
        return;
      }

      Set<SelectionKey> keys = selector.selectedKeys();
      for (SelectionKey key : keys) {

        if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
          SocketChannel clientSocket = serverSocket.accept();
          if (clientSocket == null) {
            System.err.println("Error: can not accept");
            continue;
          }
          anonymousClients.add(clientSocket);
          clientSocket.configureBlocking(false);
          clientSocket.register(selector, SelectionKey.OP_READ);
        } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
          SocketChannel clientSocket = (SocketChannel) key.channel();
          ByteBuffer bytes = ByteBuffer.allocate(4096);

          if (clientSocket.read(bytes) != -1) {
            byte[] message = bytes.array();
            switch (message[0]) {
              case 1:
                {
                  String nick = MessageUtils.parseMessage(message).first;
                  if (!checkMessage(nick, "", clientSocket)) {
                    continue;
                  }

                  if (clients.containsKey(nick) || nick.length() > 32) {
                    if (nick.length() > 32) {
                      sendMessage(
                          clientSocket, MessageUtils.error("<server>: your nick is too long"));
                    } else {
                      sendMessage(
                          clientSocket,
                          MessageUtils.error("<server>: another user is using this nick"));
                    }
                    sendMessage(clientSocket, MessageUtils.bye());
                    anonymousClients.remove(clientSocket);
                    Utils.tryClose(clientSocket);
                  } else {
                    System.out.println(nick + " enter this chatroom");
                    notifyAllClients(nick + " enter this chatroom");

                    sendMessage(
                        clientSocket,
                        MessageUtils.message("<server>", "Wellcome, your nick is " + nick));
                    anonymousClients.remove(clientSocket);
                    clients.put(nick, clientSocket);
                  }
                  break;
                }

              case 2:
                {
                  String nick = getNickFromSocket(clientSocket);
                  if (nick == null) {
                    Utils.printErrorAndExit("Error: it could not happen");
                  }

                  Utils.Pair<String, String> pair = MessageUtils.parseMessage(message);
                  if (!checkMessage(pair.first, pair.second, clientSocket)) {
                    continue;
                  }

                  if (!pair.first.equals(nick)) {
                    System.out.println("Cheater: " + nick);
                    sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat"));
                  }

                  for (Entry<String, SocketChannel> client : clients.entrySet()) {
                    if (!clientSocket.equals(client.getValue())) {
                      sendMessage(client.getValue(), MessageUtils.message(nick, pair.second));
                    }
                  }
                  break;
                }

              case 3:
                disconnectClient(clientSocket);
                break;

              case 127:
                {
                  String nick = getNickFromSocket(clientSocket);

                  Utils.Pair<String, String> pair = MessageUtils.parseMessage(message);
                  if (!checkMessage(pair.first, pair.second, clientSocket)) {
                    continue;
                  }

                  if (!pair.first.equals(nick)) {
                    System.out.println("Cheater: " + nick);
                    sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat"));
                  }
                  System.out.println(nick + ": " + pair.second);
                  break;
                }

              default:
                System.out.println("Bad message from " + getNickFromSocket(clientSocket));
                sendMessage(clientSocket, MessageUtils.message("<server>", "bad message"));
                break;
            }
          } else {
            disconnectClient(clientSocket);
          }
        }
      }
      keys.clear();
    } catch (Exception expt) {
      expt.printStackTrace();
      Utils.printErrorAndExit(expt.getMessage());
    }
  }
Пример #15
0
  @Test
  public void testSelector() throws Exception {
    ServerSocket acceptor = new ServerSocket(0);

    Selector selector = Selector.open();

    // Create client server socket pair
    SocketChannel client = SocketChannel.open(acceptor.getLocalSocketAddress());
    Socket server = acceptor.accept();
    server.setTcpNoDelay(true);

    // Make the client non blocking and register it with selector for reads
    client.configureBlocking(false);
    SelectionKey key = client.register(selector, SelectionKey.OP_READ);

    // assert it is not selected
    assertTrue(key.isValid());
    assertFalse(key.isReadable());
    assertEquals(0, key.readyOps());

    // try selecting and assert nothing selected
    int selected = selector.selectNow();
    assertEquals(0, selected);
    assertEquals(0, selector.selectedKeys().size());
    assertTrue(key.isValid());
    assertFalse(key.isReadable());
    assertEquals(0, key.readyOps());

    // Write a byte from server to client
    server.getOutputStream().write(42);
    server.getOutputStream().flush();

    // select again and assert selection found for read
    selected = selector.select(1000);
    assertEquals(1, selected);
    assertEquals(1, selector.selectedKeys().size());
    assertTrue(key.isValid());
    assertTrue(key.isReadable());
    assertEquals(1, key.readyOps());

    // select again and see that it is not reselect, but stays selected
    selected = selector.select(100);
    assertEquals(0, selected);
    assertEquals(1, selector.selectedKeys().size());
    assertTrue(key.isValid());
    assertTrue(key.isReadable());
    assertEquals(1, key.readyOps());

    // read the byte
    ByteBuffer buf = ByteBuffer.allocate(1024);
    int len = client.read(buf);
    assertEquals(1, len);
    buf.flip();
    assertEquals(42, buf.get());
    buf.clear();

    // But this does not change the key
    assertTrue(key.isValid());
    assertTrue(key.isReadable());
    assertEquals(1, key.readyOps());

    // Even if we select again ?
    selected = selector.select(100);
    assertEquals(0, selected);
    assertEquals(1, selector.selectedKeys().size());
    assertTrue(key.isValid());
    assertTrue(key.isReadable());
    assertEquals(1, key.readyOps());

    // Unless we remove the key from the select set
    // and then it is still flagged as isReadable()
    selector.selectedKeys().clear();
    assertEquals(0, selector.selectedKeys().size());
    assertTrue(key.isValid());
    assertTrue(key.isReadable());
    assertEquals(1, key.readyOps());

    // Now if we select again - it is still flagged as readable!!!
    selected = selector.select(100);
    assertEquals(0, selected);
    assertEquals(0, selector.selectedKeys().size());
    assertTrue(key.isValid());
    assertTrue(key.isReadable());
    assertEquals(1, key.readyOps());

    // Only when it is selected for something else does that state change.
    key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    selected = selector.select(1000);
    assertEquals(1, selected);
    assertEquals(1, selector.selectedKeys().size());
    assertTrue(key.isValid());
    assertTrue(key.isWritable());
    assertFalse(key.isReadable());
    assertEquals(SelectionKey.OP_WRITE, key.readyOps());
  }
Пример #16
0
  /** Check for incoming messages */
  private void readIncomingMessages() {

    Client client = null;
    try {
      // non-blocking select, returns immediately regardless of
      // how many keys are ready
      readSelector.selectNow();

      // fetch the keys
      Set<SelectionKey> readyKeys = readSelector.selectedKeys();

      // run through the keys and process each one
      while (!readyKeys.isEmpty()) {
        SelectionKey key = readyKeys.iterator().next();
        readyKeys.remove(key);
        SocketChannel channel = (SocketChannel) key.channel();
        client = (Client) key.attachment();
        if (client.isHalfDead()) {
          continue;
        }
        readBuffer.clear();

        client.setTimeOfLastReceive(System.currentTimeMillis());

        // read from the channel into our buffer
        long nBytes = channel.read(readBuffer);
        client.addReceived(nBytes);

        // basic anti-flood protection
        FloodProtectionService floodProtection =
            getContext().getService(FloodProtectionService.class);
        if ((floodProtection != null) && floodProtection.isFlooding(client)) {
          continue;
        }

        // check for end-of-stream
        if (nBytes == -1) {
          LOG.debug("Socket disconnected - killing client");
          channel.close();
          // this will also close the socket channel
          getContext().getClients().killClient(client);
        } else {
          // use a CharsetDecoder to turn those bytes into a string
          // and append it to the client's StringBuilder
          readBuffer.flip();
          String str = getContext().getServer().getAsciiDecoder().decode(readBuffer).toString();
          readBuffer.clear();
          client.appendToRecvBuf(str);

          // TODO move this to Client#appendToRecvBuf(String)
          // check for a full line
          String line = client.readLine();
          while (line != null) {
            executeCommandWrapper(line, client);

            if (!client.isAlive()) {
              // in case the client was killed within the
              // executeCommand() method
              break;
            }
            line = client.readLine();
          }
        }
      }
    } catch (IOException ioex) {
      LOG.info(
          "exception during select(): possibly due to force disconnect. Killing the client ...");
      if (client != null) {
        getContext().getClients().killClient(client, "Quit: connection lost");
      }
      LOG.debug("... the exception was:", ioex);
    }
  }
  private boolean sendPacket(Packet packet, InetSocketAddress address, SelectionKey selectedKey) {

    boolean result = false;

    try {
      lock.lock();

      if (selectedKey == unicastKey) {
        LifxNetworkThrottler.lock(macAsHex);
      } else {
        LifxNetworkThrottler.lock();
      }

      boolean sent = false;

      while (!sent && selector.isOpen()) {
        try {
          selector.selectNow();
        } catch (IOException e) {
          logger.error("An exception occurred while selecting: {}", e.getMessage());
        }

        Set<SelectionKey> selectedKeys = selector.selectedKeys();
        Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

        while (keyIterator.hasNext()) {
          SelectionKey key = keyIterator.next();

          if (key.isValid() && key.isWritable() && key.equals(selectedKey)) {
            SelectableChannel channel = key.channel();
            try {
              if (channel instanceof DatagramChannel) {
                logger.trace(
                    "{} : Sending packet type '{}' from '{}' to '{}' for '{}' with sequence '{}' and source '{}'",
                    new Object[] {
                      macAsHex,
                      packet.getClass().getSimpleName(),
                      ((InetSocketAddress) ((DatagramChannel) channel).getLocalAddress())
                          .toString(),
                      address.toString(),
                      packet.getTarget().getHex(),
                      packet.getSequence(),
                      Long.toString(packet.getSource(), 16)
                    });
                ((DatagramChannel) channel).send(packet.bytes(), address);
                sent = true;
                result = true;
              } else if (channel instanceof SocketChannel) {
                ((SocketChannel) channel).write(packet.bytes());
              }
            } catch (Exception e) {
              logger.error("An exception occurred while writing data : '{}'", e.getMessage());
              break;
            }
          }
        }
      }
    } catch (Exception e) {
      logger.error(
          "An exception occurred while sending a packet to the bulb : '{}'", e.getMessage());
    } finally {

      if (selectedKey == unicastKey) {
        LifxNetworkThrottler.unlock(macAsHex);
      } else {
        LifxNetworkThrottler.unlock();
      }

      lock.unlock();
    }

    return result;
  }
        @Override
        public void run() {
          try {
            lock.lock();

            if (selector != null) {
              try {
                selector.selectNow();
              } catch (IOException e) {
                logger.error("An exception occurred while selecting: {}", e.getMessage());
              }

              Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();

              while (keyIterator.hasNext()) {

                SelectionKey key;

                try {
                  key = keyIterator.next();
                } catch (ConcurrentModificationException e) {
                  // when a StateServiceResponse packet is handled a new unicastChannel may be
                  // registered
                  // in the selector which causes this exception, recover from it by restarting the
                  // iteration
                  logger.debug(
                      "{} : Restarting iteration after ConcurrentModificationException", macAsHex);
                  keyIterator = selector.selectedKeys().iterator();
                  continue;
                }

                if (key.isValid() && key.isAcceptable()) {
                  // a connection was accepted by a ServerSocketChannel.
                  // block of code only for completeness purposes

                } else if (key.isValid() && key.isConnectable()) {
                  // a connection was established with a remote server.
                  // block of code only for completeness purposes

                } else if (key.isValid() && key.isReadable()) {
                  // a channel is ready for reading
                  SelectableChannel channel = key.channel();
                  InetSocketAddress address = null;
                  int messageLength = 0;

                  ByteBuffer readBuffer = ByteBuffer.allocate(bufferSize);
                  try {
                    if (channel instanceof DatagramChannel) {
                      address = (InetSocketAddress) ((DatagramChannel) channel).receive(readBuffer);
                    } else if (channel instanceof SocketChannel) {
                      address = (InetSocketAddress) ((SocketChannel) channel).getRemoteAddress();
                      ((SocketChannel) channel).read(readBuffer);
                    }
                    messageLength = readBuffer.position();
                  } catch (Exception e) {
                    logger.warn("An exception occurred while reading data : '{}'", e.getMessage());
                  }
                  if (address != null) {
                    if (!interfaceAddresses.contains(address.getAddress())) {

                      readBuffer.rewind();

                      ByteBuffer packetSize = readBuffer.slice();
                      packetSize.position(0);
                      packetSize.limit(2);
                      int size = Packet.FIELD_SIZE.value(packetSize);

                      if (messageLength == size) {

                        ByteBuffer packetType = readBuffer.slice();
                        packetType.position(32);
                        packetType.limit(34);
                        int type = Packet.FIELD_PACKET_TYPE.value(packetType);

                        PacketHandler<?> handler = PacketFactory.createHandler(type);

                        if (handler == null) {
                          logger.trace(
                              "Unknown packet type: {} (source: {})",
                              String.format("0x%02X", type),
                              address.toString());
                          continue;
                        }

                        Packet packet = handler.handle(readBuffer);
                        if (packet == null) {
                          logger.warn(
                              "Handler {} was unable to handle packet",
                              handler.getClass().getName());
                        } else {
                          handlePacket(packet, address);
                        }
                      }
                    }
                  }
                } else if (key.isValid() && key.isWritable()) {
                  // a channel is ready for writing
                  // block of code only for completeness purposes
                }
              }
            }
          } catch (Exception e) {
            logger.error(
                "An exception occurred while receiving a packet from the bulb : '{}'",
                e.getMessage());
          } finally {
            lock.unlock();
          }
        }
Пример #19
0
 static void releaseTemporarySelector(Selector sel) throws IOException {
   // Selector should be empty
   sel.selectNow(); // Flush cancelled keys
   assert sel.keys().isEmpty() : "Temporary selector not empty";
   localSelectorWrapper.set(null);
 }
Пример #20
0
  /** Performs a server cycle. */
  private void cycle() {
    int loggedIn = 0;
    Benchmark b = Benchmarks.getBenchmark("loginQueue");
    b.start();
    while (!loginQueue.isEmpty() && loggedIn++ < 50) {
      Player player = loginQueue.poll();
      try {
        player.finishLogin();
        player.setLoginStage(LoginStages.LOGGED_IN);
      } catch (Exception ex) {
        // ex.printStackTrace();
        System.out.println("Error, infinite DC loop for this player");
        player.disconnect();
      }
    }
    b.stop();

    b = Benchmarks.getBenchmark("handleNetworkPackets");
    b.start();
    // Handle all network events.
    try {
      selector.selectNow();
      for (SelectionKey selectionKey : selector.selectedKeys()) {
        if (selectionKey.isValid()) {
          if (selectionKey.isReadable()) {
            // Tell the client to handle the packet.
            PacketManager.handleIncomingData((Player) selectionKey.attachment());
          }
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    b.stop();

    // Next, perform game processing.
    try {
      PluginManager.tick();
      World.process();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    b = Benchmarks.getBenchmark("disconnectingPlayers");
    b.start();
    synchronized (disconnectedPlayers) {
      for (Iterator<Player> players = disconnectedPlayers.iterator(); players.hasNext(); ) {
        Player player = players.next();
        if (player.logoutDisabled()) continue;
        player.logout();
        players.remove();
      }
    }
    b.stop();
    if (infoDisplayCounter == 0) {
      System.out.println(
          "[ENGINE]: Server load: " + cycle + "% with " + World.playerAmount() + " players");
      infoDisplayCounter = 300;
    } else {
      infoDisplayCounter--;
    }
  }
Пример #21
0
 final void selectNow() throws IOException {
   final Selector selector = this.selector;
   if (selector != null) {
     selector.selectNow();
   }
 }
Пример #22
0
  public boolean select(Channel channel, RubyIO io, int ops, long timeout) {
    if (channel instanceof SelectableChannel) {
      SelectableChannel selectable = (SelectableChannel) channel;

      synchronized (selectable.blockingLock()) {
        boolean oldBlocking = selectable.isBlocking();

        SelectionKey key = null;
        try {
          selectable.configureBlocking(false);

          if (io != null) io.addBlockingThread(this);
          currentSelector = getRuntime().getSelectorPool().get(selectable.provider());

          key = selectable.register(currentSelector, ops);

          beforeBlockingCall();
          int result;
          if (timeout < 0) {
            result = currentSelector.select();
          } else if (timeout == 0) {
            result = currentSelector.selectNow();
          } else {
            result = currentSelector.select(timeout);
          }

          // check for thread events, in case we've been woken up to die
          pollThreadEvents();

          if (result == 1) {
            Set<SelectionKey> keySet = currentSelector.selectedKeys();

            if (keySet.iterator().next() == key) {
              return true;
            }
          }

          return false;
        } catch (IOException ioe) {
          throw getRuntime().newIOErrorFromException(ioe);
        } finally {
          // Note: I don't like ignoring these exceptions, but it's
          // unclear how likely they are to happen or what damage we
          // might do by ignoring them. Note that the pieces are separate
          // so that we can ensure one failing does not affect the others
          // running.

          // clean up the key in the selector
          try {
            if (key != null) key.cancel();
            if (currentSelector != null) currentSelector.selectNow();
          } catch (Exception e) {
            // ignore
          }

          // shut down and null out the selector
          try {
            if (currentSelector != null) {
              getRuntime().getSelectorPool().put(currentSelector);
            }
          } catch (Exception e) {
            // ignore
          } finally {
            currentSelector = null;
          }

          // remove this thread as a blocker against the given IO
          if (io != null) io.removeBlockingThread(this);

          // go back to previous blocking state on the selectable
          try {
            selectable.configureBlocking(oldBlocking);
          } catch (Exception e) {
            // ignore
          }

          // clear thread state from blocking call
          afterBlockingCall();
        }
      }
    } else {
      // can't select, just have to do a blocking call
      return true;
    }
  }