@GuardedBy("lock")
 private void setWriteOps() {
   // Make sure we are registered to get updated when writing is available again
   key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
   // Refresh the selector to make sure it gets the new interestOps
   key.selector().wakeup();
 }
Exemple #2
0
 /** Немедленно выключает интересуемое действие OP_READ */
 protected void disableReadInterest() {
   try {
     _selectionKey.interestOps(_selectionKey.interestOps() & ~SelectionKey.OP_READ);
   } catch (CancelledKeyException e) {
     // ignore
   }
 }
Exemple #3
0
 private void processWritableKey(SelectionKey key) {
   CrawlURL url = (CrawlURL) key.attachment();
   SocketChannel channel = (SocketChannel) key.channel();
   ByteBuffer buffer = (ByteBuffer) url.getHandlerAttr(_REQUEST_BUFFER);
   try {
     // 发送http请求,若发送完成,取消OP_WRITE。
     int writtenBytes = 0;
     for (int i = WRITE_SPIN_COUNT; i > 0; i--) {
       writtenBytes = channel.write(buffer);
       // write success
       if (writtenBytes != 0) {
         url.setHandlerAttr(_LAST_SEND_REQUEST_MILLIS, System.currentTimeMillis());
         url.setHandlerAttr(
             _REQUEST_ALREADY_SEND_SIZE,
             (Integer) url.getHandlerAttr(_REQUEST_ALREADY_SEND_SIZE) + writtenBytes);
         url.setHandlerAttr(
             _REQUEST_SEND_TIMES, (Integer) url.getHandlerAttr(_REQUEST_SEND_TIMES) + 1);
         break;
       }
     }
     boolean reqSendFinished = !buffer.hasRemaining();
     url.setHandlerAttr(_REQUEST_SEND_FINISHED, reqSendFinished);
     url.setHandlerAttr(_REQUEST_SEND_FINISHED_MILLIS, reqSendFinished);
     if (reqSendFinished) {
       url.removeHandlerAttr(_REQUEST_BUFFER);
       key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
     }
   } catch (IOException e) {
     logger.error("error send http request ! URL: " + url);
     cancelAndClose(key);
     url.setFetchStatus(FETCH_FAILED);
     url.getPipeline().resume(DefaultPipeline.EMPTY_MSG);
   }
 }
  @Override
  protected void writeOP(SelectionKey key) throws IOException {
    RapidoidConnection conn = (RapidoidConnection) key.attachment();
    SocketChannel socketChannel = (SocketChannel) key.channel();

    checkOnSameThread();

    try {
      int wrote = conn.output.writeTo(socketChannel);

      conn.output.deleteBefore(wrote);

      boolean complete = conn.output.size() == 0;

      if (conn.closeAfterWrite() && complete) {
        close(conn);
      } else {
        if (complete) {
          key.interestOps(SelectionKey.OP_READ);
        } else {
          key.interestOps(SelectionKey.OP_READ + SelectionKey.OP_WRITE);
        }
        conn.wrote(complete);
      }
    } catch (IOException e) {
      close(conn);
    }
  }
  public static void chooseDispatcher(SocketChannel channel, int op) {

    if (channel.isRegistered()) {
      for (Dispatcher dispatcher : dispatchers) {
        SelectionKey key = channel.keyFor(dispatcher.getSelector());
        if (key != null && key.isValid() && (key.interestOps() == op)) {
          return;
        }
      }

      for (Dispatcher dispatcher : dispatchers) {
        SelectionKey key = channel.keyFor(dispatcher.getSelector());
        if (key != null && key.isValid() && (key.interestOps() == 0)) {
          if (op == SelectionKey.OP_READ) {
            dispatcher.addChannelForRead(channel);
          } else if (op == SelectionKey.OP_WRITE) {
            dispatcher.addChannelForWrite(channel);
          }
          return;
        }
      }
    } else {
      if (op == SelectionKey.OP_READ) {
        nextDispatcher().addChannelForRead(channel);
      } else if (op == SelectionKey.OP_WRITE) {
        nextDispatcher().addChannelForWrite(channel);
      }
    }
  }
Exemple #6
0
 /** Немедленно выключает интересуемое действие OP_WRITE */
 protected void disableWriteInterest() {
   try {
     if (_isPengingWrite.compareAndSet(true, false))
       _selectionKey.interestOps(_selectionKey.interestOps() & ~SelectionKey.OP_WRITE);
   } catch (CancelledKeyException e) {
     // ignore
   }
 }
Exemple #7
0
 private void removeInterest(int i) {
   if (selKey.isValid()) {
     selKey.interestOps(selKey.interestOps() & ~i);
     if (log.isDebugEnabled()) {
       log.debug("Interest now {}", selKey.interestOps());
     }
   }
 }
 private boolean resumeIfSuspended(final int ops) {
   final int interestOps = key.interestOps();
   if ((interestOps & ops) == 0) {
     key.interestOps(interestOps | ops).selector().wakeup();
     logger.debug("{} resumed {}", this, ops == SelectionKey.OP_READ ? "read" : "write");
     return true;
   } else {
     return false;
   }
 }
 private boolean suspendIfResumed(final int ops) {
   final int interestOps = key.interestOps();
   if ((interestOps & ops) == ops) {
     key.interestOps(interestOps & ~ops);
     logger.debug("{} suspended {}", this, ops == SelectionKey.OP_READ ? "read" : "write");
     return true;
   } else {
     return false;
   }
 }
  void disableWrites() {
    if (writeChannel == null) return;

    try {
      final SelectionKey selectionKey = writeChannel.keyFor(this.selector);
      selectionKey.interestOps(selectionKey.interestOps() & ~OP_WRITE);
    } catch (Exception e) {
      LOG.error("", e);
    }
  }
Exemple #11
0
    // Remove connect interest from connected sockets
    // See:
    // http://stackoverflow.com/questions/204186/java-nio-select-returns-without-selected-keys-why
    private void processKey(SelectionKey key) {
      if ((key.readyOps() & SelectionKey.OP_CONNECT) != 0) {
        int interestOps = key.interestOps();

        interestOps &= ~SelectionKey.OP_CONNECT;
        interestOps |= SelectionKey.OP_WRITE;

        key.interestOps(interestOps);
      }
    }
 private void handleRemaining(int remaining) {
   if (remaining > 0) {
     // chunked channels should not fail
     assert !mChannel.isChunked();
     // register for a write notification if a write fails
     mKey.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
   } else {
     mKey.interestOps(SelectionKey.OP_READ);
   }
 }
  private void dispatch() throws IOException {
    SelectionKey key = null;
    for (SocketChannelOPSChangeRequest request : opsChangeRequstMap.values()) {
      key = request.getChannel().keyFor(selector);
      if (key != null) {
        // 写优先
        if ((request.getOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
          key.interestOps(SelectionKey.OP_WRITE);
          request.clearOps(SelectionKey.OP_WRITE);
        } else if ((request.getOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
          key.interestOps(SelectionKey.OP_READ);
          request.clearOps(SelectionKey.OP_READ);
        }
      }
    }

    isWeakuped.set(false);
    if (selector.select(WaveriderConfig.WAVERIDER_DEFAULT_NETWORK_TIME_OUT) <= 0) {
      return;
    }

    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
    while (iterator.hasNext()) {
      key = (SelectionKey) iterator.next();
      iterator.remove();
      try {
        if (!key.isValid()) {
          continue;
        } else if (key.isAcceptable()) {
          onAccept(key);
        } else if (key.isReadable()) {
          // readerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_READ));
          onRead(key);
        } else if (key.isWritable()) {
          // writerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_WRITE));
          onWrite(key);
        }
      } catch (IOException e) {
        // 客户端连接出问题
        Session session = (Session) key.attachment();
        if (session != null) {
          session.onException();
          // 释放Session
          sessionManager.freeSession(session);
        }
        opsChangeRequstMap.remove((SocketChannel) key.channel());
        key.cancel();
        key.channel().close();
        e.printStackTrace();
        logger.error("OOPS:Exception:", e);
      }
    }
  }
  private void enableWrites() {
    if (writeChannel == null) return;

    try {
      final SelectionKey selectionKey = writeChannel.keyFor(this.selector);
      if (selectionKey != null) selectionKey.interestOps(selectionKey.interestOps() | OP_WRITE);
      // we have just enabled it, so don't have to do this again.
      shouldEnableOpWrite = false;
    } catch (Exception e) {
      LOG.error("", e);
    }
  }
Exemple #15
0
  private void handleWritableChannel(SelectionKey key, SelectableChannel channel) {
    try {
      if (!key.isWritable()) return;

      ByteBuffer buffer = this.outputBuffers.get(channel);
      buffer.flip();
      ((WritableByteChannel) channel).write(buffer);

      // If there aren't any bytes left to write from the buffer, tell the
      // selector that we no longer want to write to the channel (and-not
      // disables only that bit)
      if (0 == buffer.remaining()) key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
      buffer.compact();

      // The code below the catch blocks below is for error-handling only
      return;
    } catch (CancelledKeyException e) {
      // Error-handling code below to avoid code duplication
    } catch (ClosedChannelException e) {
      // Error-handling code below to avoid code duplication
    } catch (EOFException e) {
      // Error-handling code below to avoid code duplication
    } catch (IOException e) {
      reportIOException(e);

      // Continue with the error-handling code below
    }

    this.outputBuffers.remove(channel);

    // Close and remove any routes that point to this channel as an output
    Iterator<Map.Entry<SelectableChannel, SelectableChannel>> i =
        this.outputs.entrySet().iterator();
    while (i.hasNext()) {
      Map.Entry<SelectableChannel, SelectableChannel> entry = i.next();
      if (entry.getValue().equals(channel)) {
        closeChannelAndReportException(entry.getKey());
        i.remove();
      }
    }

    try {
      // No longer interested in handling this channel for write
      // operations
      key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
    } catch (CancelledKeyException e) {
      // Do nothing
    }

    // The channel should already be closed, but just in case
    closeChannelAndReportException(channel);
  }
 public void applyUpdates() {
   if (wasChanged.getAndSet(false)) {
     for (int i = changeOfOpWriteRequired.nextSetBit(0);
         i >= 0;
         i = changeOfOpWriteRequired.nextSetBit(i + 1)) {
       changeOfOpWriteRequired.clear(i);
       final SelectionKey key = selectionKeys[i];
       try {
         key.interestOps(key.interestOps() | op);
       } catch (Exception e) {
         LOG.debug("", e);
       }
     }
   }
 }
  /**
   * Handle OP_WRITE.
   *
   * @param key {@link SelectionKey}
   * @param ctx {@link Context}
   */
  public boolean onWriteInterest(final SelectionKey key, final Context ctx) throws IOException {
    // disable OP_WRITE on key before doing anything else
    key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));

    if (asyncQueueWriter.isReady(key)) {
      invokeAsyncQueueWriter(pollContext(ctx, key, Context.OpType.OP_WRITE));
      return false;
    }
    Object attach = SelectionKeyAttachment.getAttachment(key);
    if (attach instanceof CallbackHandler) {
      NIOContext context = pollContext(ctx, key, Context.OpType.OP_WRITE);
      invokeCallbackHandler((CallbackHandler) attach, context);
      return false;
    }
    return true;
  }
Exemple #18
0
  private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    synchronized (this.pendingData) {
      List queue = (List) this.pendingData.get(socketChannel);

      // Write until there's not more data ...
      while (!queue.isEmpty()) {
        ByteBuffer buf = (ByteBuffer) queue.get(0);
        socketChannel.write(buf);
        if (buf.remaining() > 0) {
          // ... or the socket's buffer fills up
          break;
        }
        queue.remove(0);
      }

      if (queue.isEmpty()) {
        // We wrote away all data, so we're no longer interested
        // in writing on this socket. Switch back to waiting for
        // data.
        key.interestOps(SelectionKey.OP_READ);
      }
    }
  }
  /** Handle new OP_CONNECT ops. */
  protected void onConnectOp(Context ctx, ConnectChannelOperation selectionKeyOp)
      throws IOException {
    SocketChannel socketChannel = (SocketChannel) selectionKeyOp.getChannel();
    SocketAddress remoteAddress = selectionKeyOp.getRemoteAddress();
    CallbackHandler callbackHandler = selectionKeyOp.getCallbackHandler();

    CallbackHandlerSelectionKeyAttachment attachment =
        new CallbackHandlerSelectionKeyAttachment(callbackHandler);

    SelectionKey key = socketChannel.register(selector, 0, attachment);
    attachment.associateKey(key);

    boolean isConnected;
    try {
      isConnected = socketChannel.connect(remoteAddress);
    } catch (Exception e) {
      if (logger.isLoggable(Level.FINE)) {
        logger.log(Level.FINE, "Exception occured when tried to connect socket", e);
      }

      // set isConnected to true to let callback handler to know about the problem happened
      isConnected = true;
    }

    // if channel was connected immediately or exception occured
    if (isConnected) {
      onConnectInterest(key, ctx);
    } else {
      key.interestOps(SelectionKey.OP_CONNECT);
    }
  }
Exemple #20
0
  private void queue_data(SelectionKey key, byte[] data) {
    SocketChannel channel = (SocketChannel) key.channel();
    List<byte[]> pendingData = to_send.get(channel);
    key.interestOps(SelectionKey.OP_WRITE);

    pendingData.add(data);
  }
  /**
   * Serves the incoming connections.
   *
   * @throws IOException
   * @throws DirectoryException
   */
  private void serveIncomingConnections() throws IOException, DirectoryException {
    int selectorState = selector.select();

    // We can't rely on return value of select to determine if any keys
    // are ready.
    // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4850373
    for (Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
        iterator.hasNext(); ) {
      SelectionKey key = iterator.next();
      iterator.remove();
      if (key.isAcceptable()) {
        // Accept the new client connection.
        ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
        SocketChannel clientChannel = serverChannel.accept();
        if (clientChannel != null) {
          acceptConnection(clientChannel);
        }
      }

      if (selectorState == 0 && enabled && !shutdownRequested && logger.isTraceEnabled()) {
        // Selected keys was non empty but select() returned 0.
        // Log warning and hope it blocks on the next select() call.
        logger.trace(
            "Selector.select() returned 0. "
                + "Selected Keys: %d, Interest Ops: %d, Ready Ops: %d ",
            selector.selectedKeys().size(), key.interestOps(), key.readyOps());
      }
    }
  }
Exemple #22
0
  /** Writes data pending message into a specific socket defined by the key */
  private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();

    synchronized (pendingWriteData) {
      List<ByteBuffer> queue = pendingWriteData.get(socketChannel);
      if (queue == null) {
        queue = new ArrayList<>();
        pendingWriteData.put(socketChannel, queue);
      }

      // Write until there's no more data ...
      while (!queue.isEmpty()) {
        ByteBuffer buf = queue.get(0);
        socketChannel.write(buf);
        if (buf.remaining() > 0) {
          logger.finest("Write Buffer Full!");
          break;
        }
        queue.remove(0);
      }

      if (queue.isEmpty()) {
        // All data written, change selector interest
        logger.finest("No more Data to write!");
        key.interestOps(SelectionKey.OP_READ);
      }
    }
  }
Exemple #23
0
    private void doAsyncWrite(SelectionKey key) throws IOException {
      Call call = (Call) key.attachment();
      if (call == null) {
        return;
      }
      if (key.channel() != call.connection.channel) {
        throw new IOException("doAsyncWrite: bad channel");
      }

      synchronized (call.connection.responseQueue) {
        if (processResponse(call.connection.responseQueue, false)) {
          try {
            key.interestOps(0);
          } catch (CancelledKeyException e) {
            /*
             * The Listener/reader might have closed the socket.
             * We don't explicitly cancel the key, so not sure if this will
             * ever fire.
             * This warning could be removed.
             */
            LOG.warn("Exception while changing ops : " + e);
          }
        }
      }
    }
Exemple #24
0
 @Override
 public void write(Multiplexer multiplexer, SelectionKey key) throws Exception {
   try {
     _socket.write(_command);
     if (_command.position() == _command.limit()) {
       if (_state == ReceiverState.SEND_BYE) {
         close(multiplexer, key, true); // TODO: Check true
       } else {
         key.interestOps(SelectionKey.OP_READ);
       }
     }
   } catch (ClosedChannelException e) {
     /* From GridFTP v2 spec: "...the sender may choose not
      * to wait for 'BYE' acknowledgement. The sender is
      * allowed to close data channels immediately after
      * sending EOD, and the receiver may get a socket
      * error trying to send 'BYE' message back to the
      * sender".
      */
     if (_state == ReceiverState.SEND_BYE) {
       close(multiplexer, key, true); // TODO: Check true
     } else {
       throw e;
     }
   }
 }
Exemple #25
0
  private void write(SelectionKey key) throws IOException {
    SocketChannel ch = (SocketChannel) key.channel();
    int count = 0;

    synchronized (pendingData) {
      List queue = (List) pendingData.get(ch);
      /**
       * Null exception alert: This can happen once a connection was established. Check send() for
       * more information.
       */
      if (queue == null) return;

      while (!queue.isEmpty()) {
        ByteBuffer buf = (ByteBuffer) queue.get(0);
        ch.write(buf);

        count += buf.capacity() - buf.remaining();
        if (buf.remaining() > 0) break;
        queue.remove(0);
      }

      if (queue.isEmpty()) key.interestOps(SelectionKey.OP_READ);
    }

    if (!listener.handleWrite(ch, count)) close(ch);
  }
Exemple #26
0
  public void run() {
    while (true) {
      try {
        synchronized (changeRequests) {
          Iterator changes = changeRequests.iterator();
          while (changes.hasNext()) {
            ChangeRequest change = (ChangeRequest) changes.next();
            switch (change.type) {
              case ChangeRequest.CHANGEOPS:
                SelectionKey key = change.socket.keyFor(selector);
                key.interestOps(change.ops);
            }
          }
          changeRequests.clear();
        }
        selector.select();

        Iterator selectedKeys = selector.selectedKeys().iterator();
        while (selectedKeys.hasNext()) {
          SelectionKey key = (SelectionKey) selectedKeys.next();
          selectedKeys.remove();

          if (!key.isValid()) continue;

          if (key.isAcceptable()) accept(key);
          else if (key.isReadable()) read(key);
          else if (key.isWritable()) write(key);
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  @Override
  protected void write(SelectionKey selectionKey) throws IOException {
    if (!checkTimeout()) return;

    if (outputStream.getBuffer().hasRemaining()) {
      // If we have data, write what we can now...
      int count = socketChannel.write(outputStream.getBuffer());

      if (logger.isTraceEnabled())
        logger.trace(
            "Wrote "
                + count
                + " bytes, remaining: "
                + outputStream.getBuffer().remaining()
                + " for "
                + socketChannel.socket());
    } else {
      if (logger.isTraceEnabled()) logger.trace("Wrote no bytes for " + socketChannel.socket());
    }

    // If there's more to write but we didn't write it, we'll take that to
    // mean that we're done here. We don't clear or reset anything. We leave
    // our buffer state where it is and try our luck next time.
    if (outputStream.getBuffer().hasRemaining()) return;

    resetStreams();

    // If we're not streaming writes, signal the Selector that we're
    // ready to read the next request.
    selectionKey.interestOps(SelectionKey.OP_READ);
  }
Exemple #28
0
  protected void writeBuffer(SocketChannel channel) throws IOException {
    synchronized (this.writeQueue) {
      ByteBuffer buffer = this.writeQueue.peek();
      while (buffer != null) {
        writeSize += channel.write(buffer);
        if (buffer.hasRemaining()) {
          this.selectionKey.interestOps(selectionKey.interestOps() | SelectionKey.OP_WRITE);
          this.selectionKey.selector().wakeup();
          break;
        } else {
          this.writeQueue.remove();
          buffer = this.writeQueue.peek();
        }
      }
      this.writeQueue.notifyAll();
    }

    if (System.currentTimeMillis() - this.lastWriteTime > 1000) {
      writeSpeed = this.writeSize * 1.0 / (System.currentTimeMillis() - this.lastWriteTime);
      this.writeSize = 0;
      this.lastWriteTime = System.currentTimeMillis();

      if (log.isDebugEnabled()) {
        log.debug(
            String.format(
                "Write speed %1.3f Kb/s on %s.", this.writeSpeed, this.listener.toString()));
        if (this.writeQueue.size() > 0) {
          log.warn(
              String.format(
                  "Write buffer queue size:%s, on %s",
                  this.writeQueue.size(), this.listener.toString()));
        }
      }
    }
  }
Exemple #29
0
  public void write(ByteBuffer src, boolean sync) {
    if (this.selectionKey == null || !this.selectionKey.isValid()) return;
    // log.debug("wirte to DVR Video channel:" + src.remaining());
    if (this.writeBusy()) {
      this.close();
      // 写出错,设置网络超时错误。关闭连接。
      try {
        this.listener.timeout(this);
      } catch (IOException e) {
        log.error(e.toString(), e);
      }
    } else if (this.writeQueue.offer(src)) {
      // 如果当前Socket没有注册写操作.
      if (this.writeQueue.size() == 1
          && (this.selectionKey.interestOps() & SelectionKey.OP_WRITE) != SelectionKey.OP_WRITE) {
        this.selectionKey.interestOps(selectionKey.interestOps() | SelectionKey.OP_WRITE);
        this.selectionKey.selector().wakeup();
      }
    } else {
      log.warn("Write buffer queue full, client:" + this.toString());
    }

    while (sync && src.remaining() > 0) {
      synchronized (writeQueue) {
        try {
          writeQueue.wait();
        } catch (InterruptedException e) {
        }
      }
    }
  }
  /**
   * @throws IOException due to {@link SocketChannel#write(ByteBuffer)} call
   * @throws CancelledKeyException
   * @see
   *     com.niffy.AndEngineLockStepEngine.threads.nio.BaseSelectorThread#write(java.nio.channels.SelectionKey)
   */
  @Override
  protected void write(SelectionKey pKey) throws IOException, CancelledKeyException {
    DatagramChannel socketChannel;
    String connectionIP;
    socketChannel = (DatagramChannel) pKey.channel();
    InetSocketAddress address = (InetSocketAddress) socketChannel.socket().getRemoteSocketAddress();
    connectionIP = address.getAddress().getHostAddress();
    InetSocketAddress target = (InetSocketAddress) pKey.attachment();

    synchronized (this.mPendingData) {
      ArrayList<ByteBuffer> queue = this.mPendingData.get(target.getAddress());

      // Write until there's not more data ...
      while (!queue.isEmpty()) {
        ByteBuffer buf = (ByteBuffer) queue.get(0);
        socketChannel.send(buf, target);
        if (buf.remaining() > 0) {
          // ... or the socket's buffer fills up
          break;
        }
        queue.remove(0);
      }

      if (queue.isEmpty()) {
        // We wrote away all data, so we're no longer interested
        // in writing on this socket. Switch back to waiting for
        // data.
        pKey.interestOps(SelectionKey.OP_READ);
      }
    }
  }