< prev index next >

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

Print this page




 387      *
 388      * @throws AsynchronousCloseException if the channel was closed asynchronously
 389      */
 390     private void endRead(boolean blocking, boolean completed)
 391         throws AsynchronousCloseException
 392     {
 393         if (blocking) {
 394             synchronized (stateLock) {
 395                 readerThread = 0;
 396                 if (state == ST_CLOSING) {
 397                     tryFinishClose();
 398                 }
 399             }
 400             // remove hook for Thread.interrupt
 401             end(completed);
 402         }
 403     }
 404 
 405     private SocketAddress sender;       // Set by receive0 (## ugh)
 406 


 407     @Override
 408     public SocketAddress receive(ByteBuffer dst) throws IOException {
 409         if (dst.isReadOnly())
 410             throw new IllegalArgumentException("Read-only buffer");
 411 
 412         readLock.lock();
 413         try {
 414             boolean blocking = isBlocking();
 415             int n = 0;
 416             ByteBuffer bb = null;
 417             try {
 418                 SocketAddress remote = beginRead(blocking, false);
 419                 boolean connected = (remote != null);
 420                 SecurityManager sm = System.getSecurityManager();
 421                 if (connected || (sm == null)) {
 422                     // connected or no security manager
 423                     n = receive(fd, dst, connected);
 424                     if (blocking) {
 425                         while (IOStatus.okayToRetry(n) && isOpen()) {
 426                             park(Net.POLLIN);
 427                             n = receive(fd, dst, connected);
 428                         }
 429                     } else if (n == IOStatus.UNAVAILABLE) {
 430                         return null;
 431                     }
 432                 } else {
 433                     // Cannot receive into user's buffer when running with a
 434                     // security manager and not connected
 435                     bb = Util.getTemporaryDirectBuffer(dst.remaining());
 436                     for (;;) {
 437                         n = receive(fd, bb, connected);
 438                         if (blocking) {
 439                             while (IOStatus.okayToRetry(n) && isOpen()) {
 440                                 park(Net.POLLIN);
 441                                 n = receive(fd, bb, connected);
 442                             }
 443                         } else if (n == IOStatus.UNAVAILABLE) {
 444                             return null;
 445                         }
 446                         InetSocketAddress isa = (InetSocketAddress)sender;
 447                         try {
 448                             sm.checkAccept(isa.getAddress().getHostAddress(),
 449                                            isa.getPort());
 450                         } catch (SecurityException se) {
 451                             // Ignore packet
 452                             bb.clear();
 453                             n = 0;
 454                             continue;
 455                         }
 456                         bb.flip();
 457                         dst.put(bb);
 458                         break;
 459                     }
 460                 }
 461                 assert sender != null;
 462                 return sender;
 463             } finally {
 464                 if (bb != null)
 465                     Util.releaseTemporaryDirectBuffer(bb);
 466                 endRead(blocking, n > 0);
 467                 assert IOStatus.check(n);
 468             }
 469         } finally {
 470             readLock.unlock();
 471         }
 472     }
 473 
 474     private int receive(FileDescriptor fd, ByteBuffer dst, boolean connected)
 475         throws IOException
 476     {
 477         int pos = dst.position();
 478         int lim = dst.limit();
 479         assert (pos <= lim);
 480         int rem = (pos <= lim ? lim - pos : 0);
 481         if (dst instanceof DirectBuffer && rem > 0)
 482             return receiveIntoNativeBuffer(fd, dst, rem, pos, connected);
 483 
 484         // Substitute a native buffer. If the supplied buffer is empty
 485         // we must instead use a nonempty buffer, otherwise the call
 486         // will not block waiting for a datagram on some platforms.




 387      *
 388      * @throws AsynchronousCloseException if the channel was closed asynchronously
 389      */
 390     private void endRead(boolean blocking, boolean completed)
 391         throws AsynchronousCloseException
 392     {
 393         if (blocking) {
 394             synchronized (stateLock) {
 395                 readerThread = 0;
 396                 if (state == ST_CLOSING) {
 397                     tryFinishClose();
 398                 }
 399             }
 400             // remove hook for Thread.interrupt
 401             end(completed);
 402         }
 403     }
 404 
 405     private SocketAddress sender;       // Set by receive0 (## ugh)
 406 
 407     private static final int INITIAL = -100;  // some unambiguous negative value
 408 
 409     @Override
 410     public SocketAddress receive(ByteBuffer dst) throws IOException {
 411         if (dst.isReadOnly())
 412             throw new IllegalArgumentException("Read-only buffer");
 413 
 414         readLock.lock();
 415         try {
 416             boolean blocking = isBlocking();
 417             int n = INITIAL;
 418             ByteBuffer bb = null;
 419             try {
 420                 SocketAddress remote = beginRead(blocking, false);
 421                 boolean connected = (remote != null);
 422                 SecurityManager sm = System.getSecurityManager();
 423                 if (connected || (sm == null)) {
 424                     // connected or no security manager
 425                     n = receive(fd, dst, connected);
 426                     if (blocking) {
 427                         while (IOStatus.okayToRetry(n) && isOpen()) {
 428                             park(Net.POLLIN);
 429                             n = receive(fd, dst, connected);
 430                         }
 431                     } else if (n == IOStatus.UNAVAILABLE) {
 432                         return null;
 433                     }
 434                 } else {
 435                     // Cannot receive into user's buffer when running with a
 436                     // security manager and not connected
 437                     bb = Util.getTemporaryDirectBuffer(dst.remaining());
 438                     for (;;) {
 439                         n = receive(fd, bb, connected);
 440                         if (blocking) {
 441                             while (IOStatus.okayToRetry(n) && isOpen()) {
 442                                 park(Net.POLLIN);
 443                                 n = receive(fd, bb, connected);
 444                             }
 445                         } else if (n == IOStatus.UNAVAILABLE) {
 446                             return null;
 447                         }
 448                         InetSocketAddress isa = (InetSocketAddress)sender;
 449                         try {
 450                             sm.checkAccept(isa.getAddress().getHostAddress(),
 451                                            isa.getPort());
 452                         } catch (SecurityException se) {
 453                             // Ignore packet
 454                             bb.clear();
 455                             n = INITIAL;
 456                             continue;
 457                         }
 458                         bb.flip();
 459                         dst.put(bb);
 460                         break;
 461                     }
 462                 }
 463                 assert sender != null;
 464                 return sender;
 465             } finally {
 466                 if (bb != null)
 467                     Util.releaseTemporaryDirectBuffer(bb);
 468                 endRead(blocking, n >= 0);
 469                 assert IOStatus.check(n);
 470             }
 471         } finally {
 472             readLock.unlock();
 473         }
 474     }
 475 
 476     private int receive(FileDescriptor fd, ByteBuffer dst, boolean connected)
 477         throws IOException
 478     {
 479         int pos = dst.position();
 480         int lim = dst.limit();
 481         assert (pos <= lim);
 482         int rem = (pos <= lim ? lim - pos : 0);
 483         if (dst instanceof DirectBuffer && rem > 0)
 484             return receiveIntoNativeBuffer(fd, dst, rem, pos, connected);
 485 
 486         // Substitute a native buffer. If the supplied buffer is empty
 487         // we must instead use a nonempty buffer, otherwise the call
 488         // will not block waiting for a datagram on some platforms.


< prev index next >