< prev index next >

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

Print this page

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

332         }
333         Net.bind(family, fd, isa.getAddress(), isa.getPort());
334         Net.listen(fd, backlog < 1 ? 50 : backlog);
335         return Net.localAddress(fd);
336     }
337 
338     /**
339      * Marks the beginning of an I/O operation that might block.
340      *
341      * @throws ClosedChannelException if the channel is closed
342      * @throws NotYetBoundException if the channel's socket has not been bound yet
343      */
344     private void begin(boolean blocking) throws ClosedChannelException {
345         if (blocking)
346             begin();  // set blocker to close channel if interrupted
347         synchronized (stateLock) {
348             ensureOpen();
349             if (localAddress == null)
350                 throw new NotYetBoundException();
351             if (blocking)
352                 thread = NativeThread.current();
353         }
354     }
355 
356     /**
357      * Marks the end of an I/O operation that may have blocked.
358      *
359      * @throws AsynchronousCloseException if the channel was closed due to this
360      * thread being interrupted on a blocking I/O operation.
361      */
362     private void end(boolean blocking, boolean completed)
363         throws AsynchronousCloseException
364     {
365         if (blocking) {
366             synchronized (stateLock) {
367                 thread = 0;
368                 if (state == ST_CLOSING) {
369                     tryFinishClose();
370                 }
371             }
372             end(completed);
373         }
374     }
375 
376     @Override
377     public SocketChannel accept() throws IOException {
378         int n = 0;
379         FileDescriptor newfd = new FileDescriptor();
380         SocketAddress[] saa = new SocketAddress[1];
381 
382         acceptLock.lock();
383         try {
384             ensureOpen();
385             boolean blocking = isBlocking();
386             try {
387                 begin(blocking);

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

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

332         }
333         Net.bind(family, fd, isa.getAddress(), isa.getPort());
334         Net.listen(fd, backlog < 1 ? 50 : backlog);
335         return Net.localAddress(fd);
336     }
337 
338     /**
339      * Marks the beginning of an I/O operation that might block.
340      *
341      * @throws ClosedChannelException if the channel is closed
342      * @throws NotYetBoundException if the channel's socket has not been bound yet
343      */
344     private void begin(boolean blocking) throws ClosedChannelException {
345         if (blocking)
346             begin();  // set blocker to close channel if interrupted
347         synchronized (stateLock) {
348             ensureOpen();
349             if (localAddress == null)
350                 throw new NotYetBoundException();
351             if (blocking)
352                 thread = NativeThread.threadToSignal();
353         }
354     }
355 
356     /**
357      * Marks the end of an I/O operation that may have blocked.
358      *
359      * @throws AsynchronousCloseException if the channel was closed due to this
360      * thread being interrupted on a blocking I/O operation.
361      */
362     private void end(boolean blocking, boolean completed)
363         throws AsynchronousCloseException
364     {
365         if (blocking) {
366             synchronized (stateLock) {
367                 thread = null;
368                 if (state == ST_CLOSING) {
369                     tryFinishClose();
370                 }
371             }
372             end(completed);
373         }
374     }
375 
376     @Override
377     public SocketChannel accept() throws IOException {
378         int n = 0;
379         FileDescriptor newfd = new FileDescriptor();
380         SocketAddress[] saa = new SocketAddress[1];
381 
382         acceptLock.lock();
383         try {
384             ensureOpen();
385             boolean blocking = isBlocking();
386             try {
387                 begin(blocking);

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