예제 #1
0
 @Override
 public void run() {
   if (interestOps == OP_REGISTER) {
     try {
       socket
           .getIOChannel()
           .register(socket.getPoller().getSelector(), SelectionKey.OP_READ, socketWrapper);
     } catch (Exception x) {
       log.error(sm.getString("endpoint.nio.registerFail"), x);
     }
   } else {
     final SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
     try {
       if (key == null) {
         // The key was cancelled (e.g. due to socket closure)
         // and removed from the selector while it was being
         // processed. Count down the connections at this point
         // since it won't have been counted down when the socket
         // closed.
         socket.socketWrapper.getEndpoint().countDownConnection();
       } else {
         final NioSocketWrapper socketWrapper = (NioSocketWrapper) key.attachment();
         if (socketWrapper != null) {
           // we are registering the key to start with, reset the fairness counter.
           int ops = key.interestOps() | interestOps;
           socketWrapper.interestOps(ops);
           key.interestOps(ops);
         } else {
           socket.getPoller().cancelledKey(key);
         }
       }
     } catch (CancelledKeyException ckx) {
       try {
         socket.getPoller().cancelledKey(key);
       } catch (Exception ignore) {
       }
     }
   }
 }
예제 #2
0
    public SendfileState processSendfile(
        SelectionKey sk, NioSocketWrapper socketWrapper, boolean calledByProcessor) {
      NioChannel sc = null;
      try {
        unreg(sk, socketWrapper, sk.readyOps());
        SendfileData sd = socketWrapper.getSendfileData();

        if (log.isTraceEnabled()) {
          log.trace("Processing send file for: " + sd.fileName);
        }

        if (sd.fchannel == null) {
          // Setup the file channel
          File f = new File(sd.fileName);
          if (!f.exists()) {
            cancelledKey(sk);
            return SendfileState.ERROR;
          }
          @SuppressWarnings("resource") // Closed when channel is closed
          FileInputStream fis = new FileInputStream(f);
          sd.fchannel = fis.getChannel();
        }

        // Configure output channel
        sc = socketWrapper.getSocket();
        // TLS/SSL channel is slightly different
        WritableByteChannel wc = ((sc instanceof SecureNioChannel) ? sc : sc.getIOChannel());

        // We still have data in the buffer
        if (sc.getOutboundRemaining() > 0) {
          if (sc.flushOutbound()) {
            socketWrapper.updateLastWrite();
          }
        } else {
          long written = sd.fchannel.transferTo(sd.pos, sd.length, wc);
          if (written > 0) {
            sd.pos += written;
            sd.length -= written;
            socketWrapper.updateLastWrite();
          } else {
            // Unusual not to be able to transfer any bytes
            // Check the length was set correctly
            if (sd.fchannel.size() <= sd.pos) {
              throw new IOException(
                  "Sendfile configured to " + "send more data than was available");
            }
          }
        }
        if (sd.length <= 0 && sc.getOutboundRemaining() <= 0) {
          if (log.isDebugEnabled()) {
            log.debug("Send file complete for: " + sd.fileName);
          }
          socketWrapper.setSendfileData(null);
          try {
            sd.fchannel.close();
          } catch (Exception ignore) {
          }
          // For calls from outside the Poller, the caller is
          // responsible for registering the socket for the
          // appropriate event(s) if sendfile completes.
          if (!calledByProcessor) {
            if (sd.keepAlive) {
              if (log.isDebugEnabled()) {
                log.debug("Connection is keep alive, registering back for OP_READ");
              }
              reg(sk, socketWrapper, SelectionKey.OP_READ);
            } else {
              if (log.isDebugEnabled()) {
                log.debug("Send file connection is being closed");
              }
              close(sc, sk);
            }
          }
          return SendfileState.DONE;
        } else {
          if (log.isDebugEnabled()) {
            log.debug("OP_WRITE for sendfile: " + sd.fileName);
          }
          if (calledByProcessor) {
            add(socketWrapper.getSocket(), SelectionKey.OP_WRITE);
          } else {
            reg(sk, socketWrapper, SelectionKey.OP_WRITE);
          }
          return SendfileState.PENDING;
        }
      } catch (IOException x) {
        if (log.isDebugEnabled()) log.debug("Unable to complete sendfile request:", x);
        if (!calledByProcessor && sc != null) {
          close(sc, sk);
        } else {
          cancelledKey(sk);
        }
        return SendfileState.ERROR;
      } catch (Throwable t) {
        log.error("", t);
        if (!calledByProcessor && sc != null) {
          close(sc, sk);
        } else {
          cancelledKey(sk);
        }
        return SendfileState.ERROR;
      }
    }
예제 #3
0
    @Override
    protected void doRun() {
      NioChannel socket = socketWrapper.getSocket();
      SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());

      try {
        int handshake = -1;

        try {
          if (key != null) {
            // For STOP there is no point trying to handshake as the
            // Poller has been stopped.
            if (socket.isHandshakeComplete() || event == SocketEvent.STOP) {
              handshake = 0;
            } else {
              handshake = socket.handshake(key.isReadable(), key.isWritable());
              // The handshake process reads/writes from/to the
              // socket. status may therefore be OPEN_WRITE once
              // the handshake completes. However, the handshake
              // happens when the socket is opened so the status
              // must always be OPEN_READ after it completes. It
              // is OK to always set this as it is only used if
              // the handshake completes.
              event = SocketEvent.OPEN_READ;
            }
          }
        } catch (IOException x) {
          handshake = -1;
          if (log.isDebugEnabled()) log.debug("Error during SSL handshake", x);
        } catch (CancelledKeyException ckx) {
          handshake = -1;
        }
        if (handshake == 0) {
          SocketState state = SocketState.OPEN;
          // Process the request from this socket
          if (event == null) {
            state = getHandler().process(socketWrapper, SocketEvent.OPEN_READ);
          } else {
            state = getHandler().process(socketWrapper, event);
          }
          if (state == SocketState.CLOSED) {
            close(socket, key);
          }
        } else if (handshake == -1) {
          close(socket, key);
        } else if (handshake == SelectionKey.OP_READ) {
          socketWrapper.registerReadInterest();
        } else if (handshake == SelectionKey.OP_WRITE) {
          socketWrapper.registerWriteInterest();
        }
      } catch (CancelledKeyException cx) {
        socket.getPoller().cancelledKey(key);
      } catch (VirtualMachineError vme) {
        ExceptionUtils.handleThrowable(vme);
      } catch (Throwable t) {
        log.error("", t);
        socket.getPoller().cancelledKey(key);
      } finally {
        socketWrapper = null;
        event = null;
        // return to cache
        if (running && !paused) {
          processorCache.push(this);
        }
      }
    }