< prev index next >

src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java

Print this page

        

@@ -46,10 +46,11 @@
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.locks.ReentrantLock;
 
+import jdk.internal.misc.Strands;
 import sun.net.NetHooks;
 import sun.net.ext.ExtendedSocketOptions;
 
 /**
  * An implementation of ServerSocketChannels

@@ -91,10 +92,13 @@
     private boolean isReuseAddress;
 
     // Our socket adaptor, if any
     private ServerSocket socket;
 
+    // lazily set to true when the socket is configured non-blocking
+    private volatile boolean nonBlocking;
+
     // -- End of fields protected by stateLock
 
 
     ServerSocketChannelImpl(SelectorProvider sp) {
         super(sp);

@@ -271,10 +275,11 @@
         acceptLock.lock();
         try {
             boolean blocking = isBlocking();
             try {
                 begin(blocking);
+                lockedConfigureNonBlockingIfFiber();
                 n = Net.accept(this.fd, newfd, isaa);
                 if (blocking) {
                     while (IOStatus.okayToRetry(n) && isOpen()) {
                         park(Net.POLLIN);
                         n = Net.accept(this.fd, newfd, isaa);

@@ -380,11 +385,29 @@
      */
     private void lockedConfigureBlocking(boolean block) throws IOException {
         assert acceptLock.isHeldByCurrentThread();
         synchronized (stateLock) {
             ensureOpen();
-            IOUtil.configureBlocking(fd, block);
+            // do nothing if fiber has forced the socket to be non-blocking
+            if (!nonBlocking) {
+                IOUtil.configureBlocking(fd, block);
+            }
+        }
+    }
+
+    /**
+     * Ensures that the socket is configured non-blocking when the current
+     * strand is a fiber.
+     */
+    private void lockedConfigureNonBlockingIfFiber() throws IOException {
+        assert acceptLock.isHeldByCurrentThread();
+        if (!nonBlocking && (Strands.currentStrand() instanceof Fiber)) {
+            synchronized (stateLock) {
+                ensureOpen();
+                IOUtil.configureBlocking(fd, false);
+                nonBlocking = true;
+            }
         }
     }
 
     /**
      * Closes the socket if there are no accept in progress and the channel is

@@ -424,12 +447,15 @@
             assert state < ST_CLOSING;
             state = ST_CLOSING;
             if (!tryClose()) {
                 long th = thread;
                 if (th != 0) {
+                    if (NativeThread.isFiber(th))
+                        Poller.stopPoll(fdVal);
                     nd.preClose(fd);
-                    NativeThread.signal(th);
+                    if (NativeThread.isKernelThread(th))
+                        NativeThread.signal(th);
                 }
             }
         }
     }
 
< prev index next >