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

 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         SocketException ex = null;
 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         } catch (InterruptedIOException e) {
 312             throw e;
 313         } catch (ConnectionResetException e) {
 314             connectionReset = true;
 315             throw new SocketException("Connection reset");
 316         } catch (IOException ioe) {
 317             // translate to SocketException to maintain compatibility
 318             ex = asSocketException(ioe);

 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.current();
 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 = 0;
 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         SocketException ex = null;
 422         FileDescriptor fd = beginWrite();
 423         try {







 424             configureNonBlockingIfNeeded(fd, false);
 425             n = tryWrite(fd, b, off, len);
 426             while (IOStatus.okayToRetry(n) && isOpen()) {
 427                 park(fd, Net.POLLOUT);
 428                 n = tryWrite(fd, b, off, len);
 429             }
 430         } catch (InterruptedIOException e) {
 431             throw e;
 432         } catch (IOException ioe) {
 433             // translate to SocketException to maintain compatibility
 434             ex = asSocketException(ioe);
 435         } finally {
 436             endWrite(n > 0);
 437         }
 438         if (ex != null) {
 439             throw ex;
 440         }
 441         return n;
 442     }
 443 

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

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

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

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

 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         SocketException ex = null;
 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         } catch (InterruptedIOException e) {
 319             throw e;
 320         } catch (ConnectionResetException e) {
 321             connectionReset = true;
 322             throw new SocketException("Connection reset");
 323         } catch (IOException ioe) {
 324             // translate to SocketException to maintain compatibility
 325             ex = asSocketException(ioe);

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

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

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

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

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