On 11/29/2013 09:06 PM, Ivan Gerasimov wrote:
Thank you Alan for the reply!
On 29.11.2013 21:03, Alan Bateman wrote:
On 19/11/2013 17:58, Ivan Gerasimov wrote:
Hello all!
Would you please help review a fix for the bug?
https://bugs.openjdk.java.net/browse/JDK-6968459
It was reported that creating new InitialLdapContext() can fail with
"javax.naming.NamingException: LDAP response read timed out, timeout
used:30000ms", even though the specified timeout hadn't been elapsed.
The fix was provided by the filer of the bug some time ago.
Here's the webrev with this fix:
http://cr.openjdk.java.net/~igerasim/6968459/0/webrev/
I haven't seen any replies to this but I've cc'ed Vinnie and Xuelei
as they are more familiar with this area.
If I understand correctly then the issue is that the timeout handling
doesn't take account of wakeups when aren't any BerDecoders to
dequeue. The changes mean it will retry the wait with a decreasing
timeout until a reply is received or the timeout elapses. That seems
reasonable, assuming the time doesn't change :-) You might find the
code is a bit clearer if you have a "remaining" time as that would
allow you get rid of timedOut, timeOut and endTime.
I modified the patch in the way you suggest.
http://cr.openjdk.java.net/~igerasim/6968459/1/webrev/
The timeOut variable now holds the remaining time.
If the system time had changed back, we start counting from the
beginning.
If it had changed forward, we have no way to catch it and the timeout
gets elapsed earlier.
I see the patch doesn't come with a test. Is there any test
infrastructure for testing LDAP without require a complete server?
I didn't find anything like that, that's why I set 'noreg-hard' label.
Sincerely yours,
Ivan
-Alan.
Hi Ivan,
From quick look I notice a danger that Connection.readReply() pauses
(for the timeOut time) in spite of the fact that a reply is ready and
enqueued before waiting.
Imagine a situation where the 1st try of obtaining result returns null:
450 // Get the reply if it is already available.
451 BerDecoder rber = ldr.getReplyBer();
...after that, but before reaching the following lines:
471 synchronized (ldr) {
472 ldr.wait(timeOut);
473 }
The "other" thread enqueues a reply (LdapRequest.addReplyBer()) because
the code in readReply() is executing without holding a lock on "ldr".
When "this" thread (executing readReply()) finally enters synchronized
block and waits, it will wait until wait() times out or another reply is
enqueued which will issue another notify(). This can lead to unnecessary
pauses. Old code does not exhibit this problem, because it re-checks the
readiness of a reply immediately after entering the synchronized block.
Regards, Peter