protected void implCloseSelectableChannel() throws IOException {
   synchronized (stateLock) {
     if (state != ST_KILLED) nd.preClose(fd);
     long th = thread;
     if (th != 0) NativeThread.signal(th);
     if (!isRegistered()) kill();
   }
 }
 public long read(ByteBuffer[] dsts) throws IOException {
   if (dsts == null) throw new NullPointerException();
   ensureOpen();
   synchronized (lock) {
     long n = 0;
     try {
       begin();
       if (!isOpen()) return 0;
       thread = NativeThread.current();
       do {
         n = IOUtil.read(fd, dsts, nd);
       } while ((n == IOStatus.INTERRUPTED) && isOpen());
       return IOStatus.normalize(n);
     } finally {
       thread = 0;
       end((n > 0) || (n == IOStatus.UNAVAILABLE));
       assert IOStatus.check(n);
     }
   }
 }