< prev index next >

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

Print this page

 75     // Our file descriptor
 76     private final FileDescriptor fd;
 77     private final int fdVal;
 78 
 79     // Lock held by thread currently blocked on this channel
 80     private final ReentrantLock acceptLock = new ReentrantLock();
 81 
 82     // Lock held by any thread that modifies the state fields declared below
 83     // DO NOT invoke a blocking I/O operation while holding this lock!
 84     private final Object stateLock = new Object();
 85 
 86     // -- The following fields are protected by stateLock
 87 
 88     // Channel state, increases monotonically
 89     private static final int ST_INUSE = 0;
 90     private static final int ST_CLOSING = 1;
 91     private static final int ST_CLOSED = 2;
 92     private int state;
 93 
 94     // ID of native thread currently blocked in this channel, for signalling
 95     private long thread;
 96 
 97     // Binding
 98     private SocketAddress localAddress; // null => unbound
 99 
100     // set true when exclusive binding is on and SO_REUSEADDR is emulated
101     private boolean isReuseAddress;
102 
103     // Our socket adaptor, if any
104     private ServerSocket socket;
105 
106     // True if the channel's socket has been forced into non-blocking mode
107     // by a virtual thread. It cannot be reset. When the channel is in
108     // blocking mode and the channel's socket is in non-blocking mode then
109     // operations that don't complete immediately will poll the socket and
110     // preserve the semantics of blocking operations.
111     private volatile boolean forcedNonBlocking;
112 
113     // -- End of fields protected by stateLock
114 
115     ServerSocketChannelImpl(SelectorProvider sp) throws IOException {

349         synchronized (stateLock) {
350             ensureOpen();
351             if (localAddress == null)
352                 throw new NotYetBoundException();
353             if (blocking)
354                 thread = NativeThread.current();
355         }
356     }
357 
358     /**
359      * Marks the end of an I/O operation that may have blocked.
360      *
361      * @throws AsynchronousCloseException if the channel was closed due to this
362      * thread being interrupted on a blocking I/O operation.
363      */
364     private void end(boolean blocking, boolean completed)
365         throws AsynchronousCloseException
366     {
367         if (blocking) {
368             synchronized (stateLock) {
369                 thread = 0;
370                 if (state == ST_CLOSING) {
371                     tryFinishClose();
372                 }
373             }
374             end(completed);
375         }
376     }
377 
378     @Override
379     public SocketChannel accept() throws IOException {
380         int n = 0;
381         FileDescriptor newfd = new FileDescriptor();
382         SocketAddress[] saa = new SocketAddress[1];
383 
384         acceptLock.lock();
385         try {
386             ensureOpen();
387             boolean blocking = isBlocking();
388             try {
389                 begin(blocking);

536     /**
537      * Ensures that the socket is configured non-blocking when on a virtual thread.
538      */
539     private void configureSocketNonBlockingIfVirtualThread() throws IOException {
540         assert acceptLock.isHeldByCurrentThread();
541         if (!forcedNonBlocking && Thread.currentThread().isVirtual()) {
542             synchronized (stateLock) {
543                 ensureOpen();
544                 IOUtil.configureBlocking(fd, false);
545                 forcedNonBlocking = true;
546             }
547         }
548     }
549 
550     /**
551      * Closes the socket if there are no accept in progress and the channel is
552      * not registered with a Selector.
553      */
554     private boolean tryClose() throws IOException {
555         assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
556         if ((thread == 0) && !isRegistered()) {
557             state = ST_CLOSED;
558             nd.close(fd);
559             return true;
560         } else {
561             return false;
562         }
563     }
564 
565     /**
566      * Invokes tryClose to attempt to close the socket.
567      *
568      * This method is used for deferred closing by I/O and Selector operations.
569      */
570     private void tryFinishClose() {
571         try {
572             tryClose();
573         } catch (IOException ignore) { }
574     }
575 
576     /**
577      * Closes this channel when configured in blocking mode.
578      *
579      * If there is an accept in progress then the socket is pre-closed and the
580      * accept thread is signalled, in which case the final close is deferred
581      * until the accept aborts.
582      */
583     private void implCloseBlockingMode() throws IOException {
584         synchronized (stateLock) {
585             assert state < ST_CLOSING;
586             state = ST_CLOSING;
587             if (!tryClose()) {
588                 nd.preClose(fd, thread, 0);
589             }
590         }
591     }
592 
593     /**
594      * Closes this channel when configured in non-blocking mode.
595      *
596      * If the channel is registered with a Selector then the close is deferred
597      * until the channel is flushed from all Selectors.
598      */
599     private void implCloseNonBlockingMode() throws IOException {
600         synchronized (stateLock) {
601             assert state < ST_CLOSING;
602             state = ST_CLOSING;
603         }
604         // wait for any accept to complete before trying to close
605         acceptLock.lock();
606         acceptLock.unlock();
607         synchronized (stateLock) {
608             if (state == ST_CLOSING) {

 75     // Our file descriptor
 76     private final FileDescriptor fd;
 77     private final int fdVal;
 78 
 79     // Lock held by thread currently blocked on this channel
 80     private final ReentrantLock acceptLock = new ReentrantLock();
 81 
 82     // Lock held by any thread that modifies the state fields declared below
 83     // DO NOT invoke a blocking I/O operation while holding this lock!
 84     private final Object stateLock = new Object();
 85 
 86     // -- The following fields are protected by stateLock
 87 
 88     // Channel state, increases monotonically
 89     private static final int ST_INUSE = 0;
 90     private static final int ST_CLOSING = 1;
 91     private static final int ST_CLOSED = 2;
 92     private int state;
 93 
 94     // ID of native thread currently blocked in this channel, for signalling
 95     private NativeThread thread;
 96 
 97     // Binding
 98     private SocketAddress localAddress; // null => unbound
 99 
100     // set true when exclusive binding is on and SO_REUSEADDR is emulated
101     private boolean isReuseAddress;
102 
103     // Our socket adaptor, if any
104     private ServerSocket socket;
105 
106     // True if the channel's socket has been forced into non-blocking mode
107     // by a virtual thread. It cannot be reset. When the channel is in
108     // blocking mode and the channel's socket is in non-blocking mode then
109     // operations that don't complete immediately will poll the socket and
110     // preserve the semantics of blocking operations.
111     private volatile boolean forcedNonBlocking;
112 
113     // -- End of fields protected by stateLock
114 
115     ServerSocketChannelImpl(SelectorProvider sp) throws IOException {

349         synchronized (stateLock) {
350             ensureOpen();
351             if (localAddress == null)
352                 throw new NotYetBoundException();
353             if (blocking)
354                 thread = NativeThread.current();
355         }
356     }
357 
358     /**
359      * Marks the end of an I/O operation that may have blocked.
360      *
361      * @throws AsynchronousCloseException if the channel was closed due to this
362      * thread being interrupted on a blocking I/O operation.
363      */
364     private void end(boolean blocking, boolean completed)
365         throws AsynchronousCloseException
366     {
367         if (blocking) {
368             synchronized (stateLock) {
369                 thread = null;
370                 if (state == ST_CLOSING) {
371                     tryFinishClose();
372                 }
373             }
374             end(completed);
375         }
376     }
377 
378     @Override
379     public SocketChannel accept() throws IOException {
380         int n = 0;
381         FileDescriptor newfd = new FileDescriptor();
382         SocketAddress[] saa = new SocketAddress[1];
383 
384         acceptLock.lock();
385         try {
386             ensureOpen();
387             boolean blocking = isBlocking();
388             try {
389                 begin(blocking);

536     /**
537      * Ensures that the socket is configured non-blocking when on a virtual thread.
538      */
539     private void configureSocketNonBlockingIfVirtualThread() throws IOException {
540         assert acceptLock.isHeldByCurrentThread();
541         if (!forcedNonBlocking && Thread.currentThread().isVirtual()) {
542             synchronized (stateLock) {
543                 ensureOpen();
544                 IOUtil.configureBlocking(fd, false);
545                 forcedNonBlocking = true;
546             }
547         }
548     }
549 
550     /**
551      * Closes the socket if there are no accept in progress and the channel is
552      * not registered with a Selector.
553      */
554     private boolean tryClose() throws IOException {
555         assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
556         if ((thread == null) && !isRegistered()) {
557             state = ST_CLOSED;
558             nd.close(fd);
559             return true;
560         } else {
561             return false;
562         }
563     }
564 
565     /**
566      * Invokes tryClose to attempt to close the socket.
567      *
568      * This method is used for deferred closing by I/O and Selector operations.
569      */
570     private void tryFinishClose() {
571         try {
572             tryClose();
573         } catch (IOException ignore) { }
574     }
575 
576     /**
577      * Closes this channel when configured in blocking mode.
578      *
579      * If there is an accept in progress then the socket is pre-closed and the
580      * accept thread is signalled, in which case the final close is deferred
581      * until the accept aborts.
582      */
583     private void implCloseBlockingMode() throws IOException {
584         synchronized (stateLock) {
585             assert state < ST_CLOSING;
586             state = ST_CLOSING;
587             if (!tryClose()) {
588                 nd.preClose(fd, thread, null);
589             }
590         }
591     }
592 
593     /**
594      * Closes this channel when configured in non-blocking mode.
595      *
596      * If the channel is registered with a Selector then the close is deferred
597      * until the channel is flushed from all Selectors.
598      */
599     private void implCloseNonBlockingMode() throws IOException {
600         synchronized (stateLock) {
601             assert state < ST_CLOSING;
602             state = ST_CLOSING;
603         }
604         // wait for any accept to complete before trying to close
605         acceptLock.lock();
606         acceptLock.unlock();
607         synchronized (stateLock) {
608             if (state == ST_CLOSING) {
< prev index next >