public DatagramChannelImpl(SelectorProvider sp) throws IOException {
   super(sp);
   ResourceManager.beforeUdpCreate();
   try {
     this.family =
         Net.isIPv6Available() ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
     this.fd = Net.socket(family, false);
     this.fdVal = IOUtil.fdVal(fd);
     this.state = ST_UNCONNECTED;
   } catch (IOException ioe) {
     ResourceManager.afterUdpClose();
     throw ioe;
   }
 }
 /** Closes the socket. */
 protected void close() throws IOException {
   synchronized (fdLock) {
     if (fd != null || fd1 != null) {
       if (!stream) {
         ResourceManager.afterUdpClose();
       }
       if (fdUseCount == 0) {
         if (closePending) {
           return;
         }
         closePending = true;
         socketClose();
         fd = null;
         fd1 = null;
         return;
       } else {
         /*
          * If a thread has acquired the fd and a close
          * isn't pending then use a deferred close.
          * Also decrement fdUseCount to signal the last
          * thread that releases the fd to close it.
          */
         if (!closePending) {
           closePending = true;
           fdUseCount--;
           socketClose();
         }
       }
     }
   }
 }
  protected void implCloseSelectableChannel() throws IOException {
    synchronized (stateLock) {
      if (state != ST_KILLED) nd.preClose(fd);
      ResourceManager.afterUdpClose();

      // if member of mulitcast group then invalidate all keys
      if (registry != null) registry.invalidateAll();

      long th;
      if ((th = readerThread) != 0) NativeThread.signal(th);
      if ((th = writerThread) != 0) NativeThread.signal(th);
      if (!isRegistered()) kill();
    }
  }