< prev index next >

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

Print this page

  91 
  92     // Lock held when writing
  93     private final ReentrantLock writeLock = new ReentrantLock();
  94 
  95     // The stateLock for read/changing state
  96     private final Object stateLock = new Object();
  97     private static final int ST_NEW = 0;
  98     private static final int ST_UNCONNECTED = 1;
  99     private static final int ST_CONNECTING = 2;
 100     private static final int ST_CONNECTED = 3;
 101     private static final int ST_CLOSING = 4;
 102     private static final int ST_CLOSED = 5;
 103     private volatile int state;  // need stateLock to change
 104 
 105     private Cleanable cleaner;
 106 
 107     // set to true when the socket is in non-blocking mode
 108     private volatile boolean nonBlocking;
 109 
 110     // used by connect/read/write/accept, protected by stateLock
 111     private long readerThread;
 112     private long writerThread;
 113 
 114     // used when SO_REUSEADDR is emulated, protected by stateLock
 115     private boolean isReuseAddress;
 116 
 117     // read or accept timeout in millis
 118     private volatile int timeout;
 119 
 120     // flags to indicate if the connection is shutdown for input and output
 121     private volatile boolean isInputClosed;
 122     private volatile boolean isOutputClosed;
 123 
 124     // used by read to emulate legacy behavior, protected by readLock
 125     private boolean readEOF;
 126     private boolean connectionReset;
 127 
 128     /**
 129      * Creates an instance of this SocketImpl.
 130      * @param server true if this is a SocketImpl for a ServerSocket
 131      */
 132     public NioSocketImpl(boolean server) {

 206      * @throws IOException if there is an I/O error changing the blocking mode
 207      */
 208     private void configureNonBlockingIfNeeded(FileDescriptor fd, boolean timed)
 209         throws IOException
 210     {
 211         if (!nonBlocking
 212             && (timed || Thread.currentThread().isVirtual())) {
 213             assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread();
 214             IOUtil.configureBlocking(fd, false);
 215             nonBlocking = true;
 216         }
 217     }
 218 
 219     /**
 220      * Marks the beginning of a read operation that might block.
 221      * @throws SocketException if the socket is closed or not connected
 222      */
 223     private FileDescriptor beginRead() throws SocketException {
 224         synchronized (stateLock) {
 225             ensureOpenAndConnected();
 226             readerThread = NativeThread.current();
 227             return fd;
 228         }
 229     }
 230 
 231     /**
 232      * Marks the end of a read operation that may have blocked.
 233      * @throws SocketException is the socket is closed
 234      */
 235     private void endRead(boolean completed) throws SocketException {
 236         synchronized (stateLock) {
 237             readerThread = 0;
 238             int state = this.state;
 239             if (state == ST_CLOSING)
 240                 tryFinishClose();
 241             if (!completed && state >= ST_CLOSING)
 242                 throw new SocketException("Socket closed");
 243         }
 244     }
 245 
 246     /**
 247      * Attempts to read bytes from the socket into the given byte array.
 248      */
 249     private int tryRead(FileDescriptor fd, byte[] b, int off, int len)
 250         throws IOException
 251     {
 252         ByteBuffer dst = Util.getTemporaryDirectBuffer(len);
 253         assert dst.position() == 0;
 254         try {
 255             int n = nd.read(fd, ((DirectBuffer)dst).address(), len);
 256             if (n > 0) {
 257                 dst.get(b, off, n);

 279             park(fd, Net.POLLIN, remainingNanos);
 280             n = tryRead(fd, b, off, len);
 281         }
 282         return n;
 283     }
 284 
 285     /**
 286      * Reads bytes from the socket into the given byte array.
 287      * @return the number of bytes read or -1 at EOF
 288      * @throws SocketException if the socket is closed or a socket I/O error occurs
 289      * @throws SocketTimeoutException if the read timeout elapses
 290      */
 291     private int implRead(byte[] b, int off, int len, long remainingNanos) throws IOException {
 292         int n = 0;
 293         FileDescriptor fd = beginRead();
 294         try {
 295             if (connectionReset)
 296                 throw new SocketException("Connection reset");
 297             if (isInputClosed)
 298                 return -1;







 299             configureNonBlockingIfNeeded(fd, remainingNanos > 0);
 300             if (remainingNanos > 0) {
 301                 // read with timeout
 302                 n = timedRead(fd, b, off, len, remainingNanos);
 303             } else {
 304                 // read, no timeout
 305                 n = tryRead(fd, b, off, len);
 306                 while (IOStatus.okayToRetry(n) && isOpen()) {
 307                     park(fd, Net.POLLIN);
 308                     n = tryRead(fd, b, off, len);
 309                 }
 310             }
 311             return n;
 312         } catch (InterruptedIOException e) {
 313             throw e;
 314         } catch (ConnectionResetException e) {
 315             connectionReset = true;
 316             throw new SocketException("Connection reset");
 317         } catch (IOException ioe) {
 318             // throw SocketException to maintain compatibility

 351                     return -1;
 352                 // read up to MAX_BUFFER_SIZE bytes
 353                 int size = Math.min(len, MAX_BUFFER_SIZE);
 354                 int n = implRead(b, off, size, remainingNanos);
 355                 if (n == -1)
 356                     readEOF = true;
 357                 return n;
 358             } finally {
 359                 readLock.unlock();
 360             }
 361         }
 362     }
 363 
 364     /**
 365      * Marks the beginning of a write operation that might block.
 366      * @throws SocketException if the socket is closed or not connected
 367      */
 368     private FileDescriptor beginWrite() throws SocketException {
 369         synchronized (stateLock) {
 370             ensureOpenAndConnected();
 371             writerThread = NativeThread.current();
 372             return fd;
 373         }
 374     }
 375 
 376     /**
 377      * Marks the end of a write operation that may have blocked.
 378      * @throws SocketException is the socket is closed
 379      */
 380     private void endWrite(boolean completed) throws SocketException {
 381         synchronized (stateLock) {
 382             writerThread = 0;
 383             int state = this.state;
 384             if (state == ST_CLOSING)
 385                 tryFinishClose();
 386             if (!completed && state >= ST_CLOSING)
 387                 throw new SocketException("Socket closed");
 388         }
 389     }
 390 
 391     /**
 392      * Attempts to write a sequence of bytes to the socket from the given
 393      * byte array.
 394      */
 395     private int tryWrite(FileDescriptor fd, byte[] b, int off, int len)
 396         throws IOException
 397     {
 398         ByteBuffer src = Util.getTemporaryDirectBuffer(len);
 399         assert src.position() == 0;
 400         try {
 401             src.put(b, off, len);
 402             return nd.write(fd, ((DirectBuffer)src).address(), len);
 403         } finally {
 404             Util.offerFirstTemporaryDirectBuffer(src);
 405         }
 406     }
 407 
 408     /**
 409      * Writes a sequence of bytes to the socket from the given byte array.
 410      * @return the number of bytes written
 411      * @throws SocketException if the socket is closed or a socket I/O error occurs
 412      */
 413     private int implWrite(byte[] b, int off, int len) throws IOException {
 414         int n = 0;
 415         FileDescriptor fd = beginWrite();
 416         try {







 417             configureNonBlockingIfNeeded(fd, false);
 418             n = tryWrite(fd, b, off, len);
 419             while (IOStatus.okayToRetry(n) && isOpen()) {
 420                 park(fd, Net.POLLOUT);
 421                 n = tryWrite(fd, b, off, len);
 422             }
 423             return n;
 424         } catch (InterruptedIOException e) {
 425             throw e;
 426         } catch (IOException ioe) {
 427             // throw SocketException to maintain compatibility
 428             throw asSocketException(ioe);
 429         } finally {
 430             endWrite(n > 0);
 431         }
 432     }
 433 
 434     /**
 435      * Writes a sequence of bytes to the socket from the given byte array.
 436      * @throws SocketException if the socket is closed or a socket I/O error occurs

 493                     throw new SocketException("Not created");
 494                 if (state == ST_CONNECTING)
 495                     throw new SocketException("Connection in progress");
 496                 if (state == ST_CONNECTED)
 497                     throw new SocketException("Already connected");
 498                 if (state >= ST_CLOSING)
 499                     throw new SocketException("Socket closed");
 500                 assert false;
 501             }
 502             this.state = ST_CONNECTING;
 503 
 504             // invoke beforeTcpConnect hook if not already bound
 505             if (localport == 0) {
 506                 NetHooks.beforeTcpConnect(fd, address, port);
 507             }
 508 
 509             // save the remote address/port
 510             this.address = address;
 511             this.port = port;
 512 
 513             readerThread = NativeThread.current();
 514             return fd;
 515         }
 516     }
 517 
 518     /**
 519      * Marks the end of a connect operation that may have blocked.
 520      * @throws SocketException is the socket is closed
 521      */
 522     private void endConnect(FileDescriptor fd, boolean completed) throws IOException {
 523         synchronized (stateLock) {
 524             readerThread = 0;
 525             int state = this.state;
 526             if (state == ST_CLOSING)
 527                 tryFinishClose();
 528             if (completed && state == ST_CONNECTING) {
 529                 this.state = ST_CONNECTED;
 530                 localport = Net.localAddress(fd).getPort();
 531             } else if (!completed && state >= ST_CLOSING) {
 532                 throw new SocketException("Socket closed");
 533             }
 534         }
 535     }
 536 
 537     /**
 538      * Waits for a connection attempt to finish with a timeout
 539      * @throws SocketTimeoutException if the connect timeout elapses
 540      */
 541     private boolean timedFinishConnect(FileDescriptor fd, long nanos) throws IOException {
 542         long startNanos = System.nanoTime();
 543         boolean polled = Net.pollConnectNow(fd);
 544         while (!polled && isOpen()) {

 649 
 650     @Override
 651     protected void listen(int backlog) throws IOException {
 652         synchronized (stateLock) {
 653             ensureOpen();
 654             if (localport == 0)
 655                 throw new SocketException("Not bound");
 656             Net.listen(fd, backlog < 1 ? 50 : backlog);
 657         }
 658     }
 659 
 660     /**
 661      * Marks the beginning of an accept operation that might block.
 662      * @throws SocketException if the socket is closed
 663      */
 664     private FileDescriptor beginAccept() throws SocketException {
 665         synchronized (stateLock) {
 666             ensureOpen();
 667             if (localport == 0)
 668                 throw new SocketException("Not bound");
 669             readerThread = NativeThread.current();
 670             return fd;
 671         }
 672     }
 673 
 674     /**
 675      * Marks the end of an accept operation that may have blocked.
 676      * @throws SocketException is the socket is closed
 677      */
 678     private void endAccept(boolean completed) throws SocketException {
 679         synchronized (stateLock) {
 680             int state = this.state;
 681             readerThread = 0;
 682             if (state == ST_CLOSING)
 683                 tryFinishClose();
 684             if (!completed && state >= ST_CLOSING)
 685                 throw new SocketException("Socket closed");
 686         }
 687     }
 688 
 689     /**
 690      * Accepts a new connection with a timeout.
 691      * @throws SocketTimeoutException if the accept timeout elapses
 692      */
 693     private int timedAccept(FileDescriptor fd,
 694                             FileDescriptor newfd,
 695                             InetSocketAddress[] isaa,
 696                             long nanos)
 697         throws IOException
 698     {
 699         long startNanos = System.nanoTime();
 700         int n = Net.accept(fd, newfd, isaa);
 701         while (n == IOStatus.UNAVAILABLE && isOpen()) {

 827         };
 828     }
 829 
 830     @Override
 831     protected int available() throws IOException {
 832         synchronized (stateLock) {
 833             ensureOpenAndConnected();
 834             if (isInputClosed) {
 835                 return 0;
 836             } else {
 837                 return Net.available(fd);
 838             }
 839         }
 840     }
 841 
 842     /**
 843      * Closes the socket if there are no I/O operations in progress.
 844      */
 845     private boolean tryClose() throws IOException {
 846         assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
 847         if (readerThread == 0 && writerThread == 0) {
 848             try {
 849                 cleaner.clean();
 850             } catch (UncheckedIOException ioe) {
 851                 throw ioe.getCause();
 852             } finally {
 853                 state = ST_CLOSED;
 854             }
 855             return true;
 856         } else {
 857             return false;
 858         }
 859     }
 860 
 861     /**
 862      * Invokes tryClose to attempt to close the socket.
 863      *
 864      * This method is used for deferred closing by I/O operations.
 865      */
 866     private void tryFinishClose() {
 867         try {

1126                     if (!Net.isReusePortAvailable())
1127                         throw new SocketException("SO_REUSEPORT not supported");
1128                     return Net.getSocketOption(fd, StandardSocketOptions.SO_REUSEPORT);
1129                 default:
1130                     throw new SocketException("Unknown option " + opt);
1131                 }
1132             } catch (SocketException e) {
1133                 throw e;
1134             } catch (IllegalArgumentException | IOException e) {
1135                 throw asSocketException(e);
1136             }
1137         }
1138     }
1139 
1140     @Override
1141     protected void shutdownInput() throws IOException {
1142         synchronized (stateLock) {
1143             ensureOpenAndConnected();
1144             if (!isInputClosed) {
1145                 Net.shutdown(fd, Net.SHUT_RD);
1146                 if (NativeThread.isVirtualThread(readerThread)) {
1147                     Poller.stopPoll(fdVal(fd), Net.POLLIN);
1148                 }
1149                 isInputClosed = true;
1150             }
1151         }
1152     }
1153 
1154     @Override
1155     protected void shutdownOutput() throws IOException {
1156         synchronized (stateLock) {
1157             ensureOpenAndConnected();
1158             if (!isOutputClosed) {
1159                 Net.shutdown(fd, Net.SHUT_WR);
1160                 if (NativeThread.isVirtualThread(writerThread)) {
1161                     Poller.stopPoll(fdVal(fd), Net.POLLOUT);
1162                 }
1163                 isOutputClosed = true;
1164             }
1165         }
1166     }
1167 
1168     @Override
1169     protected boolean supportsUrgentData() {
1170         return true;
1171     }
1172 
1173     @Override
1174     protected void sendUrgentData(int data) throws IOException {
1175         writeLock.lock();
1176         try {
1177             int n = 0;
1178             FileDescriptor fd = beginWrite();
1179             try {
1180                 configureNonBlockingIfNeeded(fd, false);
1181                 do {

  91 
  92     // Lock held when writing
  93     private final ReentrantLock writeLock = new ReentrantLock();
  94 
  95     // The stateLock for read/changing state
  96     private final Object stateLock = new Object();
  97     private static final int ST_NEW = 0;
  98     private static final int ST_UNCONNECTED = 1;
  99     private static final int ST_CONNECTING = 2;
 100     private static final int ST_CONNECTED = 3;
 101     private static final int ST_CLOSING = 4;
 102     private static final int ST_CLOSED = 5;
 103     private volatile int state;  // need stateLock to change
 104 
 105     private Cleanable cleaner;
 106 
 107     // set to true when the socket is in non-blocking mode
 108     private volatile boolean nonBlocking;
 109 
 110     // used by connect/read/write/accept, protected by stateLock
 111     private Thread readerThread;
 112     private Thread writerThread;
 113 
 114     // used when SO_REUSEADDR is emulated, protected by stateLock
 115     private boolean isReuseAddress;
 116 
 117     // read or accept timeout in millis
 118     private volatile int timeout;
 119 
 120     // flags to indicate if the connection is shutdown for input and output
 121     private volatile boolean isInputClosed;
 122     private volatile boolean isOutputClosed;
 123 
 124     // used by read to emulate legacy behavior, protected by readLock
 125     private boolean readEOF;
 126     private boolean connectionReset;
 127 
 128     /**
 129      * Creates an instance of this SocketImpl.
 130      * @param server true if this is a SocketImpl for a ServerSocket
 131      */
 132     public NioSocketImpl(boolean server) {

 206      * @throws IOException if there is an I/O error changing the blocking mode
 207      */
 208     private void configureNonBlockingIfNeeded(FileDescriptor fd, boolean timed)
 209         throws IOException
 210     {
 211         if (!nonBlocking
 212             && (timed || Thread.currentThread().isVirtual())) {
 213             assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread();
 214             IOUtil.configureBlocking(fd, false);
 215             nonBlocking = true;
 216         }
 217     }
 218 
 219     /**
 220      * Marks the beginning of a read operation that might block.
 221      * @throws SocketException if the socket is closed or not connected
 222      */
 223     private FileDescriptor beginRead() throws SocketException {
 224         synchronized (stateLock) {
 225             ensureOpenAndConnected();
 226             readerThread = NativeThread.threadToSignal();
 227             return fd;
 228         }
 229     }
 230 
 231     /**
 232      * Marks the end of a read operation that may have blocked.
 233      * @throws SocketException is the socket is closed
 234      */
 235     private void endRead(boolean completed) throws SocketException {
 236         synchronized (stateLock) {
 237             readerThread = null;
 238             int state = this.state;
 239             if (state == ST_CLOSING)
 240                 tryFinishClose();
 241             if (!completed && state >= ST_CLOSING)
 242                 throw new SocketException("Socket closed");
 243         }
 244     }
 245 
 246     /**
 247      * Attempts to read bytes from the socket into the given byte array.
 248      */
 249     private int tryRead(FileDescriptor fd, byte[] b, int off, int len)
 250         throws IOException
 251     {
 252         ByteBuffer dst = Util.getTemporaryDirectBuffer(len);
 253         assert dst.position() == 0;
 254         try {
 255             int n = nd.read(fd, ((DirectBuffer)dst).address(), len);
 256             if (n > 0) {
 257                 dst.get(b, off, n);

 279             park(fd, Net.POLLIN, remainingNanos);
 280             n = tryRead(fd, b, off, len);
 281         }
 282         return n;
 283     }
 284 
 285     /**
 286      * Reads bytes from the socket into the given byte array.
 287      * @return the number of bytes read or -1 at EOF
 288      * @throws SocketException if the socket is closed or a socket I/O error occurs
 289      * @throws SocketTimeoutException if the read timeout elapses
 290      */
 291     private int implRead(byte[] b, int off, int len, long remainingNanos) throws IOException {
 292         int n = 0;
 293         FileDescriptor fd = beginRead();
 294         try {
 295             if (connectionReset)
 296                 throw new SocketException("Connection reset");
 297             if (isInputClosed)
 298                 return -1;
 299 
 300             // experimental
 301             if (Poller.supportReadOps() && Thread.currentThread().isVirtual()) {
 302                 n = Poller.read(fdVal(fd), b, off, len, remainingNanos, this::isOpen);
 303                 if (n != IOStatus.UNAVAILABLE) return n;
 304             }
 305 
 306             configureNonBlockingIfNeeded(fd, remainingNanos > 0);
 307             if (remainingNanos > 0) {
 308                 // read with timeout
 309                 n = timedRead(fd, b, off, len, remainingNanos);
 310             } else {
 311                 // read, no timeout
 312                 n = tryRead(fd, b, off, len);
 313                 while (IOStatus.okayToRetry(n) && isOpen()) {
 314                     park(fd, Net.POLLIN);
 315                     n = tryRead(fd, b, off, len);
 316                 }
 317             }
 318             return n;
 319         } catch (InterruptedIOException e) {
 320             throw e;
 321         } catch (ConnectionResetException e) {
 322             connectionReset = true;
 323             throw new SocketException("Connection reset");
 324         } catch (IOException ioe) {
 325             // throw SocketException to maintain compatibility

 358                     return -1;
 359                 // read up to MAX_BUFFER_SIZE bytes
 360                 int size = Math.min(len, MAX_BUFFER_SIZE);
 361                 int n = implRead(b, off, size, remainingNanos);
 362                 if (n == -1)
 363                     readEOF = true;
 364                 return n;
 365             } finally {
 366                 readLock.unlock();
 367             }
 368         }
 369     }
 370 
 371     /**
 372      * Marks the beginning of a write operation that might block.
 373      * @throws SocketException if the socket is closed or not connected
 374      */
 375     private FileDescriptor beginWrite() throws SocketException {
 376         synchronized (stateLock) {
 377             ensureOpenAndConnected();
 378             writerThread = NativeThread.threadToSignal();
 379             return fd;
 380         }
 381     }
 382 
 383     /**
 384      * Marks the end of a write operation that may have blocked.
 385      * @throws SocketException is the socket is closed
 386      */
 387     private void endWrite(boolean completed) throws SocketException {
 388         synchronized (stateLock) {
 389             writerThread = null;
 390             int state = this.state;
 391             if (state == ST_CLOSING)
 392                 tryFinishClose();
 393             if (!completed && state >= ST_CLOSING)
 394                 throw new SocketException("Socket closed");
 395         }
 396     }
 397 
 398     /**
 399      * Attempts to write a sequence of bytes to the socket from the given
 400      * byte array.
 401      */
 402     private int tryWrite(FileDescriptor fd, byte[] b, int off, int len)
 403         throws IOException
 404     {
 405         ByteBuffer src = Util.getTemporaryDirectBuffer(len);
 406         assert src.position() == 0;
 407         try {
 408             src.put(b, off, len);
 409             return nd.write(fd, ((DirectBuffer)src).address(), len);
 410         } finally {
 411             Util.offerFirstTemporaryDirectBuffer(src);
 412         }
 413     }
 414 
 415     /**
 416      * Writes a sequence of bytes to the socket from the given byte array.
 417      * @return the number of bytes written
 418      * @throws SocketException if the socket is closed or a socket I/O error occurs
 419      */
 420     private int implWrite(byte[] b, int off, int len) throws IOException {
 421         int n = 0;
 422         FileDescriptor fd = beginWrite();
 423         try {
 424 
 425             // experimental
 426             if (Poller.supportWriteOps() && Thread.currentThread().isVirtual()) {
 427                 n = Poller.write(fdVal(fd), b, off, len, this::isOpen);
 428                 if (n != IOStatus.UNAVAILABLE) return n;
 429             }
 430 
 431             configureNonBlockingIfNeeded(fd, false);
 432             n = tryWrite(fd, b, off, len);
 433             while (IOStatus.okayToRetry(n) && isOpen()) {
 434                 park(fd, Net.POLLOUT);
 435                 n = tryWrite(fd, b, off, len);
 436             }
 437             return n;
 438         } catch (InterruptedIOException e) {
 439             throw e;
 440         } catch (IOException ioe) {
 441             // throw SocketException to maintain compatibility
 442             throw asSocketException(ioe);
 443         } finally {
 444             endWrite(n > 0);
 445         }
 446     }
 447 
 448     /**
 449      * Writes a sequence of bytes to the socket from the given byte array.
 450      * @throws SocketException if the socket is closed or a socket I/O error occurs

 507                     throw new SocketException("Not created");
 508                 if (state == ST_CONNECTING)
 509                     throw new SocketException("Connection in progress");
 510                 if (state == ST_CONNECTED)
 511                     throw new SocketException("Already connected");
 512                 if (state >= ST_CLOSING)
 513                     throw new SocketException("Socket closed");
 514                 assert false;
 515             }
 516             this.state = ST_CONNECTING;
 517 
 518             // invoke beforeTcpConnect hook if not already bound
 519             if (localport == 0) {
 520                 NetHooks.beforeTcpConnect(fd, address, port);
 521             }
 522 
 523             // save the remote address/port
 524             this.address = address;
 525             this.port = port;
 526 
 527             readerThread = NativeThread.threadToSignal();
 528             return fd;
 529         }
 530     }
 531 
 532     /**
 533      * Marks the end of a connect operation that may have blocked.
 534      * @throws SocketException is the socket is closed
 535      */
 536     private void endConnect(FileDescriptor fd, boolean completed) throws IOException {
 537         synchronized (stateLock) {
 538             readerThread = null;
 539             int state = this.state;
 540             if (state == ST_CLOSING)
 541                 tryFinishClose();
 542             if (completed && state == ST_CONNECTING) {
 543                 this.state = ST_CONNECTED;
 544                 localport = Net.localAddress(fd).getPort();
 545             } else if (!completed && state >= ST_CLOSING) {
 546                 throw new SocketException("Socket closed");
 547             }
 548         }
 549     }
 550 
 551     /**
 552      * Waits for a connection attempt to finish with a timeout
 553      * @throws SocketTimeoutException if the connect timeout elapses
 554      */
 555     private boolean timedFinishConnect(FileDescriptor fd, long nanos) throws IOException {
 556         long startNanos = System.nanoTime();
 557         boolean polled = Net.pollConnectNow(fd);
 558         while (!polled && isOpen()) {

 663 
 664     @Override
 665     protected void listen(int backlog) throws IOException {
 666         synchronized (stateLock) {
 667             ensureOpen();
 668             if (localport == 0)
 669                 throw new SocketException("Not bound");
 670             Net.listen(fd, backlog < 1 ? 50 : backlog);
 671         }
 672     }
 673 
 674     /**
 675      * Marks the beginning of an accept operation that might block.
 676      * @throws SocketException if the socket is closed
 677      */
 678     private FileDescriptor beginAccept() throws SocketException {
 679         synchronized (stateLock) {
 680             ensureOpen();
 681             if (localport == 0)
 682                 throw new SocketException("Not bound");
 683             readerThread = NativeThread.threadToSignal();
 684             return fd;
 685         }
 686     }
 687 
 688     /**
 689      * Marks the end of an accept operation that may have blocked.
 690      * @throws SocketException is the socket is closed
 691      */
 692     private void endAccept(boolean completed) throws SocketException {
 693         synchronized (stateLock) {
 694             int state = this.state;
 695             readerThread = null;
 696             if (state == ST_CLOSING)
 697                 tryFinishClose();
 698             if (!completed && state >= ST_CLOSING)
 699                 throw new SocketException("Socket closed");
 700         }
 701     }
 702 
 703     /**
 704      * Accepts a new connection with a timeout.
 705      * @throws SocketTimeoutException if the accept timeout elapses
 706      */
 707     private int timedAccept(FileDescriptor fd,
 708                             FileDescriptor newfd,
 709                             InetSocketAddress[] isaa,
 710                             long nanos)
 711         throws IOException
 712     {
 713         long startNanos = System.nanoTime();
 714         int n = Net.accept(fd, newfd, isaa);
 715         while (n == IOStatus.UNAVAILABLE && isOpen()) {

 841         };
 842     }
 843 
 844     @Override
 845     protected int available() throws IOException {
 846         synchronized (stateLock) {
 847             ensureOpenAndConnected();
 848             if (isInputClosed) {
 849                 return 0;
 850             } else {
 851                 return Net.available(fd);
 852             }
 853         }
 854     }
 855 
 856     /**
 857      * Closes the socket if there are no I/O operations in progress.
 858      */
 859     private boolean tryClose() throws IOException {
 860         assert Thread.holdsLock(stateLock) && state == ST_CLOSING;
 861         if (readerThread == null && writerThread == null) {
 862             try {
 863                 cleaner.clean();
 864             } catch (UncheckedIOException ioe) {
 865                 throw ioe.getCause();
 866             } finally {
 867                 state = ST_CLOSED;
 868             }
 869             return true;
 870         } else {
 871             return false;
 872         }
 873     }
 874 
 875     /**
 876      * Invokes tryClose to attempt to close the socket.
 877      *
 878      * This method is used for deferred closing by I/O operations.
 879      */
 880     private void tryFinishClose() {
 881         try {

1140                     if (!Net.isReusePortAvailable())
1141                         throw new SocketException("SO_REUSEPORT not supported");
1142                     return Net.getSocketOption(fd, StandardSocketOptions.SO_REUSEPORT);
1143                 default:
1144                     throw new SocketException("Unknown option " + opt);
1145                 }
1146             } catch (SocketException e) {
1147                 throw e;
1148             } catch (IllegalArgumentException | IOException e) {
1149                 throw asSocketException(e);
1150             }
1151         }
1152     }
1153 
1154     @Override
1155     protected void shutdownInput() throws IOException {
1156         synchronized (stateLock) {
1157             ensureOpenAndConnected();
1158             if (!isInputClosed) {
1159                 Net.shutdown(fd, Net.SHUT_RD);
1160                 if (readerThread != null && readerThread.isVirtual()) {
1161                     Poller.stopPoll(readerThread);
1162                 }
1163                 isInputClosed = true;
1164             }
1165         }
1166     }
1167 
1168     @Override
1169     protected void shutdownOutput() throws IOException {
1170         synchronized (stateLock) {
1171             ensureOpenAndConnected();
1172             if (!isOutputClosed) {
1173                 Net.shutdown(fd, Net.SHUT_WR);
1174                 if (writerThread != null && writerThread.isVirtual()) {
1175                     Poller.stopPoll(writerThread);
1176                 }
1177                 isOutputClosed = true;
1178             }
1179         }
1180     }
1181 
1182     @Override
1183     protected boolean supportsUrgentData() {
1184         return true;
1185     }
1186 
1187     @Override
1188     protected void sendUrgentData(int data) throws IOException {
1189         writeLock.lock();
1190         try {
1191             int n = 0;
1192             FileDescriptor fd = beginWrite();
1193             try {
1194                 configureNonBlockingIfNeeded(fd, false);
1195                 do {
< prev index next >