/**
  * Cancels the outstanding I/O operation on the directory associated with the given key and
  * releases the associated resources.
  */
 private void releaseResources(WindowsWatchKey key) {
   try {
     CancelIo(key.handle());
     GetOverlappedResult(key.handle(), key.overlappedAddress());
   } catch (WindowsException expected) {
     // expected as I/O operation has been cancelled
   }
   CloseHandle(key.handle());
   closeAttachedEvent(key.overlappedAddress());
   key.buffer().cleaner().clean();
 }
    /** Poller main loop */
    @Override
    public void run() {
      for (; ; ) {
        CompletionStatus info;
        try {
          info = GetQueuedCompletionStatus(port);
        } catch (WindowsException x) {
          // this should not happen
          x.printStackTrace();
          return;
        }

        // wakeup
        if (info.completionKey() == WAKEUP_COMPLETION_KEY) {
          boolean shutdown = processRequests();
          if (shutdown) {
            return;
          }
          continue;
        }

        // map completionKey to get WatchKey
        WindowsWatchKey key = ck2key.get((int) info.completionKey());
        if (key == null) {
          // We get here when a registration is changed. In that case
          // the directory is closed which causes an event with the
          // old completion key.
          continue;
        }

        boolean criticalError = false;
        int errorCode = info.error();
        int messageSize = info.bytesTransferred();
        if (errorCode == ERROR_NOTIFY_ENUM_DIR) {
          // buffer overflow
          key.signalEvent(StandardWatchEventKinds.OVERFLOW, null);
        } else if (errorCode != 0 && errorCode != ERROR_MORE_DATA) {
          // ReadDirectoryChangesW failed
          criticalError = true;
        } else {
          // ERROR_MORE_DATA is a warning about incomplete
          // data transfer over TCP/UDP stack. For the case
          // [messageSize] is zero in the most of cases.

          if (messageSize > 0) {
            // process non-empty events.
            processEvents(key, messageSize);
          } else if (errorCode == 0) {
            // insufficient buffer size
            // not described, but can happen.
            key.signalEvent(StandardWatchEventKinds.OVERFLOW, null);
          }

          // start read for next batch of changes
          try {
            ReadDirectoryChangesW(
                key.handle(),
                key.buffer().address(),
                CHANGES_BUFFER_SIZE,
                key.watchSubtree(),
                ALL_FILE_NOTIFY_EVENTS,
                key.countAddress(),
                key.overlappedAddress());
          } catch (WindowsException x) {
            // no choice but to cancel key
            criticalError = true;
          }
        }
        if (criticalError) {
          implCancelKey(key);
          key.signal();
        }
      }
    }