Closed
Description
Problem
TSAN(go/tsan) reports error:
WARNING: ThreadSanitizer: data race (pid=2317)
Read of size 1 at 0x0000cfabb9bc by thread T56 (mutexes: write M0, write M1, write M2):
#0 java.net.Socket.close()V Socket.java:1512
#1 io.grpc.okhttp.OkHttpServerTransportTest$PipeSocket.close()V OkHttpServerTransportTest.java:1384
#2 io.grpc.internal.GrpcUtil.closeQuietly(Ljava/io/Closeable;)V GrpcUtil.java:812
#3 io.grpc.okhttp.OkHttpServerTransport.shutdown(Ljava/lang/Long;)V OkHttpServerTransport.java:271
#4 io.grpc.okhttp.OkHttpServerTransport.shutdown()V OkHttpServerTransport.java:259
#5 io.grpc.okhttp.OkHttpServerTransportTest.shutdownDuringHandshake()V OkHttpServerTransportTest.java:262
#6 (Generated Stub) <null>
#7 jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; NativeMethodAccessorImpl.java:62
#8 jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; DelegatingMethodAccessorImpl.java:43
#9 java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; Method.java:566
#10 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall()Ljava/lang/Object; FrameworkMethod.java:59
#11 org.junit.internal.runners.model.ReflectiveCallable.run()Ljava/lang/Object; ReflectiveCallable.java:12
#12 org.junit.runners.model.FrameworkMethod.invokeExplosively(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; FrameworkMethod.java:61
#13 org.junit.internal.runners.statements.InvokeMethod.evaluate()V InvokeMethod.java:17
#14 org.junit.internal.runners.statements.RunBefores.evaluate()V RunBefores.java:26
#15 org.junit.internal.runners.statements.RunAfters.evaluate()V RunAfters.java:27
#16 org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call()Ljava/lang/Throwable; FailOnTimeout.java:299
#17 org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call()Ljava/lang/Object; FailOnTimeout.java:293
#18 java.util.concurrent.FutureTask.run()V FutureTask.java:264
#19 java.lang.Thread.run()V Thread.java:830
#20 (Generated Stub) <null>
Previous write of size 1 at 0x0000cfabb9bc by thread T57:
#0 java.net.Socket.createImpl(Z)V Socket.java:478
#1 java.net.Socket.getImpl()Ljava/net/SocketImpl; Socket.java:540
#2 java.net.Socket.setTcpNoDelay(Z)V Socket.java:998
#3 io.grpc.okhttp.OkHttpServerTransport.startIo(Lio/grpc/internal/SerializingExecutor;)V OkHttpServerTransport.java:164
#4 io.grpc.okhttp.OkHttpServerTransport.lambda$start$0(Lio/grpc/internal/SerializingExecutor;)V OkHttpServerTransport.java:159
#5 io.grpc.okhttp.OkHttpServerTransport$$Lambda$56.run()V ??
#6 io.grpc.internal.SerializingExecutor.run()V SerializingExecutor.java:133
#7 java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V ThreadPoolExecutor.java:1130
#8 java.util.concurrent.ThreadPoolExecutor$Worker.run()V ThreadPoolExecutor.java:630
#9 java.lang.Thread.run()V Thread.java:830
#10 (Generated Stub) <null>
The tls wrapper socket is synchronizing on bareSocket, however, okhttpserver is using bareSocket APIs directly that is not threadsafe.
Solution
To fix, we will want to use the wrapper socket consistently cross the implementation and tests.
Acceptance Criteria
Reproduction and verification run in google3 passed (blaze flag --config=tsan
)
cc. @ejona86