< prev index next >

src/share/classes/com/sun/jndi/ldap/Connection.java

Print this page
rev 13664 : 8139965: Hang seen when using com.sun.jndi.ldap.search.replyQueueSize
Reviewed-by: dfuchs


 436         if (debug) {
 437             System.err.println("Writing request to: " + outStream);
 438         }
 439 
 440         try {
 441             synchronized (this) {
 442                 outStream.write(ber.getBuf(), 0, ber.getDataLen());
 443                 outStream.flush();
 444             }
 445         } catch (IOException e) {
 446             cleanup(null, true);
 447             throw (closureReason = e); // rethrow
 448         }
 449 
 450         return req;
 451     }
 452 
 453     /**
 454      * Reads a reply; waits until one is ready.
 455      */
 456     BerDecoder readReply(LdapRequest ldr)
 457             throws IOException, NamingException {
 458         BerDecoder rber;
 459 
 460         // Track down elapsed time to workaround spurious wakeups
 461         long elapsedMilli = 0;
 462         long elapsedNano = 0;
 463 
 464         while (((rber = ldr.getReplyBer()) == null) &&
 465                 (readTimeout <= 0 || elapsedMilli < readTimeout))
 466         {
 467             try {
 468                 // If socket closed, don't even try
 469                 synchronized (this) {
 470                     if (sock == null) {
 471                         throw new ServiceUnavailableException(host + ":" + port +
 472                             "; socket closed");
 473                     }
 474                 }
 475                 synchronized (ldr) {
 476                     // check if condition has changed since our last check
 477                     rber = ldr.getReplyBer();
 478                     if (rber == null) {
 479                         if (readTimeout > 0) {  // Socket read timeout is specified
 480                             long beginNano = System.nanoTime();
 481 
 482                             // will be woken up before readTimeout if reply is
 483                             // available
 484                             ldr.wait(readTimeout - elapsedMilli);
 485                             elapsedNano += (System.nanoTime() - beginNano);
 486                             elapsedMilli += elapsedNano / 1000_000;
 487                             elapsedNano %= 1000_000;
 488 
 489                         } else {
 490                             // no timeout is set so we wait infinitely until
 491                             // a response is received
 492                             // https://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-ldap.html#PROP
 493                             ldr.wait();
 494                         }
 495                     } else {
 496                         break;
 497                     }
 498                 }
 499             } catch (InterruptedException ex) {
 500                 throw new InterruptedNamingException(
 501                     "Interrupted during LDAP operation");
 502             }
 503         }
 504 
 505         if ((rber == null) && (elapsedMilli >= readTimeout)) {
 506             abandonRequest(ldr, null);
 507             throw new NamingException("LDAP response read timed out, timeout used:"

 508                             + readTimeout + "ms." );
 509 
 510         }
 511         return rber;
 512     }
 513 
 514 
 515     ////////////////////////////////////////////////////////////////////////////
 516     //
 517     // Methods to add, find, delete, and abandon requests made to server
 518     //
 519     ////////////////////////////////////////////////////////////////////////////
 520 
 521     private synchronized void addRequest(LdapRequest ldapRequest) {
 522 
 523         LdapRequest ldr = pendingRequests;
 524         if (ldr == null) {
 525             pendingRequests = ldapRequest;
 526             ldapRequest.next = null;
 527         } else {
 528             ldapRequest.next = pendingRequests;
 529             pendingRequests = ldapRequest;
 530         }
 531     }
 532 
 533     synchronized LdapRequest findRequest(int msgId) {
 534 


 688                         sock.close();
 689                         unpauseReader();
 690                     } catch (IOException ie) {
 691                         if (debug)
 692                             System.err.println("Connection: problem closing socket: " + ie);
 693                     }
 694                     if (!notifyParent) {
 695                         LdapRequest ldr = pendingRequests;
 696                         while (ldr != null) {
 697                             ldr.cancel();
 698                             ldr = ldr.next;
 699                         }
 700                     }
 701                     sock = null;
 702                 }
 703                 nparent = notifyParent;
 704             }
 705             if (nparent) {
 706                 LdapRequest ldr = pendingRequests;
 707                 while (ldr != null) {
 708 
 709                     synchronized (ldr) {
 710                         ldr.notify();
 711                         ldr = ldr.next;
 712                     }
 713                 }
 714             }
 715         }
 716         if (nparent) {
 717             parent.processConnectionClosure();
 718         }
 719     }
 720 
 721 
 722     // Assume everything is "quiet"
 723     // "synchronize" might lead to deadlock so don't synchronize method
 724     // Use streamLock instead for synchronizing update to stream
 725 
 726     synchronized public void replaceStreams(InputStream newIn, OutputStream newOut) {
 727         if (debug) {
 728             System.err.println("Replacing " + inStream + " with: " + newIn);
 729             System.err.println("Replacing " + outStream + " with: " + newOut);
 730         }
 731 
 732         inStream = newIn;
 733 
 734         // Cleanup old stream
 735         try {


 783      * plain ones and then closes the SSL socket.
 784      * If the reader thread attempts to read, or was reading, from
 785      * the SSL socket (that is, it got to the read BEFORE replaceStreams()),
 786      * the SSL socket close will cause the reader thread to
 787      * get an EOF/exception and reexamine the input stream.
 788      * If the reader thread sees a new stream, it reattempts the read.
 789      * If the underlying socket is still alive, then the new read will succeed.
 790      * If the underlying socket has been closed also, then the new read will
 791      * fail and the reader thread exits.
 792      * If the reader thread attempts to read, or was reading, from the plain
 793      * socket (that is, it got to the read AFTER replaceStreams()), the
 794      * SSL socket close will have no effect on the reader thread.
 795      *
 796      * The check for new stream is made only
 797      * in the first attempt at reading a BER buffer; the reader should
 798      * never be in midst of reading a buffer when a nonfatal close occurs.
 799      * If this occurs, then the connection is in an inconsistent state and
 800      * the safest thing to do is to shut it down.
 801      */
 802 
 803     private Object pauseLock = new Object();  // lock for reader to wait on while paused
 804     private boolean paused = false;           // paused state of reader
 805 
 806     /*
 807      * Unpauses reader thread if it was paused
 808      */
 809     private void unpauseReader() throws IOException {
 810         synchronized (pauseLock) {
 811             if (paused) {
 812                 if (debug) {
 813                     System.err.println("Unpausing reader; read from: " +
 814                                         inStream);
 815                 }
 816                 paused = false;
 817                 pauseLock.notify();
 818             }
 819         }
 820     }
 821 
 822      /*
 823      * Pauses reader so that it stops reading from the input stream.




 436         if (debug) {
 437             System.err.println("Writing request to: " + outStream);
 438         }
 439 
 440         try {
 441             synchronized (this) {
 442                 outStream.write(ber.getBuf(), 0, ber.getDataLen());
 443                 outStream.flush();
 444             }
 445         } catch (IOException e) {
 446             cleanup(null, true);
 447             throw (closureReason = e); // rethrow
 448         }
 449 
 450         return req;
 451     }
 452 
 453     /**
 454      * Reads a reply; waits until one is ready.
 455      */
 456     BerDecoder readReply(LdapRequest ldr) throws IOException, NamingException {

 457         BerDecoder rber;
 458 







 459         try {
 460             // if no timeout is set so we wait infinitely until






















 461             // a response is received
 462             // http://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-ldap.html#PROP
 463             rber = ldr.getReplyBer(readTimeout);





 464         } catch (InterruptedException ex) {
 465             throw new InterruptedNamingException(
 466                 "Interrupted during LDAP operation");
 467         }

 468 
 469         if (rber == null) {
 470             abandonRequest(ldr, null);
 471             throw new NamingException(
 472                     "LDAP response read timed out, timeout used:"
 473                             + readTimeout + "ms." );
 474 
 475         }
 476         return rber;
 477     }
 478 

 479     ////////////////////////////////////////////////////////////////////////////
 480     //
 481     // Methods to add, find, delete, and abandon requests made to server
 482     //
 483     ////////////////////////////////////////////////////////////////////////////
 484 
 485     private synchronized void addRequest(LdapRequest ldapRequest) {
 486 
 487         LdapRequest ldr = pendingRequests;
 488         if (ldr == null) {
 489             pendingRequests = ldapRequest;
 490             ldapRequest.next = null;
 491         } else {
 492             ldapRequest.next = pendingRequests;
 493             pendingRequests = ldapRequest;
 494         }
 495     }
 496 
 497     synchronized LdapRequest findRequest(int msgId) {
 498 


 652                         sock.close();
 653                         unpauseReader();
 654                     } catch (IOException ie) {
 655                         if (debug)
 656                             System.err.println("Connection: problem closing socket: " + ie);
 657                     }
 658                     if (!notifyParent) {
 659                         LdapRequest ldr = pendingRequests;
 660                         while (ldr != null) {
 661                             ldr.cancel();
 662                             ldr = ldr.next;
 663                         }
 664                     }
 665                     sock = null;
 666                 }
 667                 nparent = notifyParent;
 668             }
 669             if (nparent) {
 670                 LdapRequest ldr = pendingRequests;
 671                 while (ldr != null) {
 672                     ldr.close();


 673                         ldr = ldr.next;
 674                     }
 675                 }
 676             }

 677         if (nparent) {
 678             parent.processConnectionClosure();
 679         }
 680     }
 681 
 682 
 683     // Assume everything is "quiet"
 684     // "synchronize" might lead to deadlock so don't synchronize method
 685     // Use streamLock instead for synchronizing update to stream
 686 
 687     synchronized public void replaceStreams(InputStream newIn, OutputStream newOut) {
 688         if (debug) {
 689             System.err.println("Replacing " + inStream + " with: " + newIn);
 690             System.err.println("Replacing " + outStream + " with: " + newOut);
 691         }
 692 
 693         inStream = newIn;
 694 
 695         // Cleanup old stream
 696         try {


 744      * plain ones and then closes the SSL socket.
 745      * If the reader thread attempts to read, or was reading, from
 746      * the SSL socket (that is, it got to the read BEFORE replaceStreams()),
 747      * the SSL socket close will cause the reader thread to
 748      * get an EOF/exception and reexamine the input stream.
 749      * If the reader thread sees a new stream, it reattempts the read.
 750      * If the underlying socket is still alive, then the new read will succeed.
 751      * If the underlying socket has been closed also, then the new read will
 752      * fail and the reader thread exits.
 753      * If the reader thread attempts to read, or was reading, from the plain
 754      * socket (that is, it got to the read AFTER replaceStreams()), the
 755      * SSL socket close will have no effect on the reader thread.
 756      *
 757      * The check for new stream is made only
 758      * in the first attempt at reading a BER buffer; the reader should
 759      * never be in midst of reading a buffer when a nonfatal close occurs.
 760      * If this occurs, then the connection is in an inconsistent state and
 761      * the safest thing to do is to shut it down.
 762      */
 763 
 764     private final Object pauseLock = new Object();  // lock for reader to wait on while paused
 765     private boolean paused = false;           // paused state of reader
 766 
 767     /*
 768      * Unpauses reader thread if it was paused
 769      */
 770     private void unpauseReader() throws IOException {
 771         synchronized (pauseLock) {
 772             if (paused) {
 773                 if (debug) {
 774                     System.err.println("Unpausing reader; read from: " +
 775                                         inStream);
 776                 }
 777                 paused = false;
 778                 pauseLock.notify();
 779             }
 780         }
 781     }
 782 
 783      /*
 784      * Pauses reader so that it stops reading from the input stream.


< prev index next >