< prev index next >

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

Print this page

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

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

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







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

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







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

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

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

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

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

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

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