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) {
|