code: void completed(long bytesAffected) {
          boolean needToFire = true;
          synchronized (this.completedSemaphore) {
              // If it's already completed, do nothing
              if (this.completed || !this.channel.isOpen()) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(tc, "Future completed after already cancelled or socket was closed");
                  }
                  return;
              }
              // mark it completed, release sync lock, then process
              this.completed = true;
  
              // new timeout code - cancel timeout request if active
              if (getTimeoutWorkItem() != null) {
                  getTimeoutWorkItem().state = TimerWorkItem.ENTRY_CANCELLED;
              }
  
              this.byteCount = bytesAffected;
              // Loop over the buffers, updating the positions until
              // we've exhausted the number of bytes affected
              long numbytes = bytesAffected;
              for (ByteBuffer buffer : this.buffers) {
                  int bufspace = buffer.remaining();
                  if (bytesAffected > bufspace) {
                      buffer.position(buffer.limit());
                      numbytes -= bufspace;
                  } else {
                      buffer.position(buffer.position() + (int) numbytes);
                      numbytes = 0;
                      break;
                  }
              } // end for
  
              if (this.firstListener == null) {
                  // Sync Read/Write request.
                  // must do this inside the sync, or else Sync Read/Write could complete
                  // before we get here, and we would be doing this on the next
                  // Read/Write request!
                  needToFire = false;
                  this.completedSemaphore.notifyAll();
              }
          }
  
          if (needToFire) {
              // ASync Read/Write request.
              // need to do this outside the sync, or else we will hold the sync
              // for the user's callback.
              fireCompletionActions();
          }
      }
docs: Marks this result as successfully complete, wakes waiting threads
  and runs the callback. Note that the thread that invokes this
  method runs the code in the callback function, which is arbitrarily
  long (as it is user code).
  
  @param bytesAffected a count of the number of bytes read/written
  by the operation