void terminate() throws IOException {
   int state = this.state;
   if (anyAreClear(state, WRITE_SHUTDOWN | READ_SHUTDOWN)) {
     this.state = state | WRITE_SHUTDOWN | READ_SHUTDOWN;
   }
   if (Native.SAFE_GC)
     try {
       Native.testAndThrow(Native.dup2(Native.DEAD_FD, fd));
     } finally {
       new FdRef<>(this, fd);
     }
   else {
     // hope for the best
     Native.testAndThrow(Native.close(fd));
   }
   if (Native.EXTRA_TRACE) log.tracef("Close(%d)", fd);
 }
 public void terminateWrites() throws IOException {
   if (connection.writeClosed())
     try {
       int state = this.state;
       if (allAreClear(state, WRITE_SHUTDOWN)) {
         this.state = state & ~(WRITE_READY | WRITE_WAKEUP | WRITE_RESUMED) | WRITE_SHUTDOWN;
         if (allAreSet(state, READ_SHUTDOWN)) {
           terminate();
         } else {
           thread.doResume(this, allAreSet(state, READ_RESUMED), false, true);
           Native.testAndThrow(Native.shutdown(fd, false, true));
           if (Native.EXTRA_TRACE) log.tracef("Shutdown writes(%d)", fd);
         }
       }
     } finally {
       writeTerminated();
     }
 }
 public void awaitWritable(final long time, final TimeUnit timeUnit) throws IOException {
   if (Native.EXTRA_TRACE) log.tracef("Await writable on %s (%d %s)", this, time, timeUnit.name());
   Native.testAndThrow(Native.await3(fd, true, timeUnit.toMillis(time)));
 }
 public void awaitWritable() throws IOException {
   if (Native.EXTRA_TRACE) log.tracef("Await writable on %s", this);
   Native.testAndThrow(Native.await2(fd, true));
 }
 public void awaitReadable() throws IOException {
   if (Native.EXTRA_TRACE) log.tracef("Await readable on %s", this);
   Native.testAndThrow(Native.await2(fd, false));
 }