< prev index next >

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

Print this page

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

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

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







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

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







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

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

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

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

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

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

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

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

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

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

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

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

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