(teststabilization) RFR: 8231506: Fix some instabilities in a few networking tests
mark sheppard
macanaoire at hotmail.com
Mon Sep 30 11:56:42 UTC 2019
Hi Daniel,
thanks for the reply ..
the client is on loopback with an ephemeral port
so in the following:
try (MulticastSocket s = new MulticastSocket(clientAddress)) {
// no-op; close immediately
s.getLocalPort(); // no-op
}
long fdCount0 = getFdCount();
listProcFD();
// start a server
Server svr = new Server();
Thread thr = new Thread(svr);
thr.start();
MulticastSocket client = new MulticastSocket(clientAddress);
the first uses the InetSocketAddress allocated and then the second uses the same address, without bind exception because of
the SO_REUSEADDR option being set, even if the close had not completed at that time.
The reference to asynchronous close in the try block above is at the OS/kernel level. The assumption is that a synchronous
blocking call but that might not be the case within the OS (?) . This may leave two extant UDP sockets bound to the same
address at the time of the echo from the server, which may leave corresponding delivery to the UDP socket indeterminate.
Again, some extreme conjecture, but failures are intermittent and on heavily loaded system, I think, making concurrent activity
more indeterminate.
WRT server, the point here is that can you guarantee that in the following, the release of the server socket
is not without side effect.
ss.send(p); // send back +1
// do NOT close but 'forget' the socket reference
ss = null;
the ss = null; releases the server socket and it is available for garbage collection, which theoretically could compete before any pending
i/o to the client has occurred in the kernel !!
Thus, this ss = null could have a side effect such that on a heavily loaded system the send is pending (in the kernel) and the
release of the server socket object results in a close, due to garbage collection, before the send has completed.
Such a close could result in the pending send (i/o) being cancelled. Hence the client never receives its
echo response.
you previously used a CoundownLatch to synchronize the client receive with the release of the server socket, to ensure that
the receive has occurred prior to the release of the server socket, thus ensuring the client receive happens before the
server socket is releases to eliminate the possibility of cancellation of pending i/o from the server.
in the server
CountDownLatch clientRxLatch = new CountDownLatch(1);
...
ss.send();
clientRxLatch.await();
ss = null;
in the client thread
DatagramPacket p = new DatagramPacket(msg, msg.length, svr.getHost(), svr.getPort());
client.send(p);
svr.clientRxLatch.countDown();
System.out.printf("ping sent to: %s:%d%n", svr.getHost(), svr.getPort());
perhaps worth considering ?
best regards
Mark
From: Daniel Fuchs <daniel.fuchs at oracle.com>
Sent: Monday 30 September 2019 10:05
To: mark sheppard <macanaoire at hotmail.com>; OpenJDK Network Dev list <net-dev at openjdk.java.net>
Subject: Re: (teststabilization) RFR: 8231506: Fix some instabilities in a few networking tests
Hi Mark,
On 30/09/2019 08:58, mark sheppard wrote:
> So does the second MulticastSocket need to use the same client unicast
> address ?
The clientAddress is an InetSocketAddress with port 0. It is possible
that the second MulticastSocket will get the same port allocated to
it, because the first one has been closed - but it's probably unlikely.
> Can it be assured that there is no asynchrony in the synthesized code for the autoclose in the try with
> resources, both at the java level and within the OS kernel executing the close?
> Would an explicit close of the first MulticastSocket add better determinacy to the test execution?
try-with-resource will close the first socket just as in
try { } finally { } - there is no mystery here. So the answer
to the above is clearly no.
> n the DatagramSocket version, a level of synchronization between the server thread and
> the main thread was added, would that be appropriate here again?
I don't think so all that matters is that the server DatagramSocket
is created before the datagram packet is sent.
best regards,
-- daniel
More information about the net-dev
mailing list