Interrupt thread before closing socket
Test failed when socket.close() ran, and in the other thread
we are trying to initialize an InetSocketAddress. If the socket
was closed, the port got from the socket object becomes -1 hence
the InetSocketAddress cannot be constructed and the
IllegalArgumentException would be thrown.
Interrupt thread before closing socket to prevent from the race.
Test: atest TestDnsServerTest --rerun-until-failure 1000
Fix: 259160848
Change-Id: I219ee1e32144ba9983a28765e7a84621c27c1c09
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt
index c63b38f..e1b771b 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt
@@ -108,8 +108,13 @@
if (status != Status.STARTED) {
throw IllegalStateException("unexpected status: $status")
}
- socket.close()
+ // The thread needs to be interrupted before closing the socket to prevent a data
+ // race where the thread tries to read from the socket while it's being closed.
+ // DatagramSocket is not thread-safe and running both concurrently can end up in
+ // getPort() returning -1 after it's been checked not to, resulting in a crash by
+ // IllegalArgumentException inside the DatagramSocket implementation.
thread.interrupt()
+ socket.close()
thread.join()
status = Status.STOPPED
}
@@ -119,7 +124,6 @@
inner class ReceivingThread : Thread() {
override fun run() {
- Log.i(TAG, "starting addr={${socket.localSocketAddress}}")
while (!interrupted() && !socket.isClosed) {
try {
processPacket()