Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nio] TSan data race reported in "GRPCTests.ClientConnectionBackoffTests testClientEventuallyConnects" #622

Closed
weissi opened this issue Nov 8, 2019 · 0 comments

Comments

@weissi
Copy link
Contributor

weissi commented Nov 8, 2019

swift-nio: bc661cbb771328e09faa65432628e9ff6fd333d5
swift-nio-http2: 994c319e038e013817a21d4679fa2d73b838a703
grpc-swift: 2cd9ea7

command:

swift test --sanitize=thread --disable-index-store

OS: macOS Catalina

Test Case '-[GRPCTests.ClientConnectionBackoffTests testClientEventuallyConnects]' started.
==================
WARNING: ThreadSanitizer: data race (pid=50737)
  Read of size 8 at 0x7b1c0000dc20 by thread T18 (mutexes: write M2633):
    #0 ConnectivityStateMonitor.delegate.getter <compiler-generated> (GRPCPackageTests:x86_64+0x381754)
    #1 ConnectivityStateMonitor.setNewState(to:) ConnectivityState.swift:103 (GRPCPackageTests:x86_64+0x382f7e)
    #2 closure #1 in ConnectivityStateMonitor.state.setter ConnectivityState.swift:82 (GRPCPackageTests:x86_64+0x382897)
    #3 partial apply for closure #1 in ConnectivityStateMonitor.state.setter <compiler-generated> (GRPCPackageTests:x86_64+0x3828eb)
    #4 thunk for @callee_guaranteed () -> (@error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x4b300f)
    #5 partial apply for thunk for @callee_guaranteed () -> (@error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x808197)
    #6 Lock.withLock<A>(_:) lock.swift:79 (GRPCPackageTests:x86_64+0x807ecf)
    #7 Lock.withLockVoid(_:) lock.swift:85 (GRPCPackageTests:x86_64+0x8080be)
    #8 ConnectivityStateMonitor.state.setter ConnectivityState.swift:81 (GRPCPackageTests:x86_64+0x3827c1)
    #9 closure #3 in ClientConnection.willSetChannel(to:) ClientConnection.swift:229 (GRPCPackageTests:x86_64+0x35b00f)
    #10 partial apply for closure #3 in ClientConnection.willSetChannel(to:) <compiler-generated> (GRPCPackageTests:x86_64+0x367f2f)
    #11 thunk for @escaping @callee_guaranteed (@guaranteed Result<(), Error>) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x35bd17)
    #12 partial apply for thunk for @escaping @callee_guaranteed (@guaranteed Result<(), Error>) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x367fd0)
    #13 closure #1 in EventLoopFuture.whenComplete(_:) EventLoopFuture.swift:757 (GRPCPackageTests:x86_64+0x7001f5)
    #14 partial apply for closure #1 in EventLoopFuture.whenComplete(_:) <compiler-generated> (GRPCPackageTests:x86_64+0x7043ef)
    #15 CallbackList._run() EventLoopFuture.swift:83 (GRPCPackageTests:x86_64+0x6f3560)
    #16 EventLoopPromise._resolve(value:) EventLoopFuture.swift:230 (GRPCPackageTests:x86_64+0x6f52b5)
    #17 EventLoopPromise.succeed(_:) EventLoopFuture.swift:175 (GRPCPackageTests:x86_64+0x6f50a4)
    #18 closure #4 in BaseSocketChannel.close0(error:mode:promise:) BaseSocketChannel.swift:771 (GRPCPackageTests:x86_64+0x5fc0f2)
    #19 partial apply for closure #4 in BaseSocketChannel.close0(error:mode:promise:) <compiler-generated> (GRPCPackageTests:x86_64+0x609a6d)
    #20 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (GRPCPackageTests:x86_64+0x6df7f7)
    #21 partial apply for thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (GRPCPackageTests:x86_64+0x6f059d)
    #22 thunk for @escaping @callee_guaranteed () -> (@out ()) <compiler-generated> (GRPCPackageTests:x86_64+0x6df847)
    #23 partial apply for thunk for @escaping @callee_guaranteed () -> (@out ()) <compiler-generated> (GRPCPackageTests:x86_64+0x6eb4cb)
    #24 closure #3 in SelectableEventLoop.run() EventLoop.swift:943 (GRPCPackageTests:x86_64+0x6df8c4)
    #25 partial apply for closure #3 in SelectableEventLoop.run() <compiler-generated> (GRPCPackageTests:x86_64+0x6eb3bb)
    #26 thunk for @callee_guaranteed () -> (@error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x4b300f)
    #27 thunk for @callee_guaranteed () -> (@error @owned Error)partial apply <compiler-generated> (GRPCPackageTests:x86_64+0x6eb427)
    #28 closure #1 in withAutoReleasePool<A>(_:) EventLoop.swift:640 (GRPCPackageTests:x86_64+0x6d87a8)
    #29 partial apply for closure #1 in withAutoReleasePool<A>(_:) <compiler-generated> (GRPCPackageTests:x86_64+0x6f061a)
    #30 autoreleasepool<A>(invoking:) <null>:3201376 (libswiftObjectiveC.dylib:x86_64+0x2f0d)
    #31 SelectableEventLoop.run() EventLoop.swift:942 (GRPCPackageTests:x86_64+0x6ddbd4)
    #32 closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:initializer:) EventLoop.swift:1114 (GRPCPackageTests:x86_64+0x6e317a)
    #33 partial apply for closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:initializer:) <compiler-generated> (GRPCPackageTests:x86_64+0x6f0049)
    #34 thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x6e3b4b)
    #35 partial apply for thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x7ee468)
    #36 closure #1 in static NIOThread.spawnAndRun(name:detachThread:body:) Thread.swift:110 (GRPCPackageTests:x86_64+0x7ee957)
    #37 @objc closure #1 in static NIOThread.spawnAndRun(name:detachThread:body:) <compiler-generated> (GRPCPackageTests:x86_64+0x7eea10)

  Previous write of size 8 at 0x7b1c0000dc20 by main thread:
    #0 ConnectivityStateMonitor.delegate.setter <compiler-generated> (GRPCPackageTests:x86_64+0x381839)
    #1 ClientConnectionBackoffTests.tearDown() ClientConnectionBackoffTests.swift:101 (GRPCPackageTests:x86_64+0x4cb1b3)
    #2 @objc ClientConnectionBackoffTests.tearDown() <compiler-generated> (GRPCPackageTests:x86_64+0x4cc7b4)
    #3 -[XCTestCase(Failures) performFailableBlock:testCaseRun:shouldInterruptTest:] <null>:3201376 (XCTest:x86_64+0xa1faf)

  Location is heap block of size 98 at 0x7b1c0000dc10 allocated by main thread:
    #0 malloc <null>:3201408 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x4e6ba)
    #1 swift_slowAlloc <null>:3201408 (libswiftCore.dylib:x86_64+0x2cb698)
    #2 ClientConnection.init(configuration:) ClientConnection.swift:97 (GRPCPackageTests:x86_64+0x3546f0)
    #3 ClientConnection.__allocating_init(configuration:) ClientConnection.swift (GRPCPackageTests:x86_64+0x3543e1)
    #4 ClientConnectionBackoffTests.testClientEventuallyConnects() ClientConnectionBackoffTests.swift:155 (GRPCPackageTests:x86_64+0x4ce7c4)
    #5 @objc ClientConnectionBackoffTests.testClientEventuallyConnects() <compiler-generated> (GRPCPackageTests:x86_64+0x4cfb17)
    #6 __invoking___ <null>:3201408 (CoreFoundation:x86_64h+0x4a1cb)

  Mutex M2633 (0x7b100001e3c0) created at:
    #0 pthread_mutex_init <null>:3201264 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2ba03)
    #1 Lock.init() lock.swift:35 (GRPCPackageTests:x86_64+0x806d70)
    #2 Lock.__allocating_init() lock.swift (GRPCPackageTests:x86_64+0x806b34)
    #3 ConnectivityStateMonitor.init(delegate:) ConnectivityState.swift:62 (GRPCPackageTests:x86_64+0x381fb9)
    #4 ConnectivityStateMonitor.__allocating_init(delegate:) ConnectivityState.swift (GRPCPackageTests:x86_64+0x381d97)
    #5 ClientConnection.init(configuration:) ClientConnection.swift:97 (GRPCPackageTests:x86_64+0x3546f0)
    #6 ClientConnection.__allocating_init(configuration:) ClientConnection.swift (GRPCPackageTests:x86_64+0x3543e1)
    #7 ClientConnectionBackoffTests.testClientEventuallyConnects() ClientConnectionBackoffTests.swift:155 (GRPCPackageTests:x86_64+0x4ce7c4)
    #8 @objc ClientConnectionBackoffTests.testClientEventuallyConnects() <compiler-generated> (GRPCPackageTests:x86_64+0x4cfb17)
    #9 __invoking___ <null>:3201264 (CoreFoundation:x86_64h+0x4a1cb)

  Thread T18 (tid=10032874, running) created by main thread at:
    #0 pthread_create <null>:3201456 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2aa2d)
    #1 static NIOThread.spawnAndRun(name:detachThread:body:) Thread.swift:96 (GRPCPackageTests:x86_64+0x7ed8d8)
    #2 static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:initializer:) EventLoop.swift:1100 (GRPCPackageTests:x86_64+0x6e2ae7)
    #3 closure #1 in MultiThreadedEventLoopGroup.init(threadInitializers:) EventLoop.swift:1146 (GRPCPackageTests:x86_64+0x6e43e1)
    #4 partial apply for closure #1 in MultiThreadedEventLoopGroup.init(threadInitializers:) <compiler-generated> (GRPCPackageTests:x86_64+0x6ebd98)
    #5 thunk for @callee_guaranteed (@guaranteed @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()) -> (@owned SelectableEventLoop, @error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x6e4570)
    #6 partial apply for thunk for @callee_guaranteed (@guaranteed @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()) -> (@owned SelectableEventLoop, @error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x6ebe12)
    #7 Collection.map<A>(_:) <null>:3201456 (libswiftCore.dylib:x86_64+0xfc8e)
    #8 MultiThreadedEventLoopGroup.__allocating_init(threadInitializers:) EventLoop.swift (GRPCPackageTests:x86_64+0x6e3bcf)
    #9 MultiThreadedEventLoopGroup.__allocating_init(numberOfThreads:) EventLoop.swift:1134 (GRPCPackageTests:x86_64+0x6e3a7f)
    #10 ClientConnectionBackoffTests.setUp() ClientConnectionBackoffTests.swift:95 (GRPCPackageTests:x86_64+0x4cae2d)
    #11 @objc ClientConnectionBackoffTests.setUp() <compiler-generated> (GRPCPackageTests:x86_64+0x4caf24)
    #12 -[XCTestCase(Failures) performFailableBlock:testCaseRun:shouldInterruptTest:] <null>:3201456 (XCTest:x86_64+0xa1faf)

SUMMARY: ThreadSanitizer: data race <compiler-generated> in ConnectivityStateMonitor.delegate.getter
==================
==================
WARNING: ThreadSanitizer: data race (pid=50737)
  Read of size 8 at 0x7b1c0000dc28 by thread T18 (mutexes: write M2633):
    #0 ConnectivityStateMonitor.delegate.getter <compiler-generated> (GRPCPackageTests:x86_64+0x38176c)
    #1 ConnectivityStateMonitor.setNewState(to:) ConnectivityState.swift:103 (GRPCPackageTests:x86_64+0x382f7e)
    #2 closure #1 in ConnectivityStateMonitor.state.setter ConnectivityState.swift:82 (GRPCPackageTests:x86_64+0x382897)
    #3 partial apply for closure #1 in ConnectivityStateMonitor.state.setter <compiler-generated> (GRPCPackageTests:x86_64+0x3828eb)
    #4 thunk for @callee_guaranteed () -> (@error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x4b300f)
    #5 partial apply for thunk for @callee_guaranteed () -> (@error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x808197)
    #6 Lock.withLock<A>(_:) lock.swift:79 (GRPCPackageTests:x86_64+0x807ecf)
    #7 Lock.withLockVoid(_:) lock.swift:85 (GRPCPackageTests:x86_64+0x8080be)
    #8 ConnectivityStateMonitor.state.setter ConnectivityState.swift:81 (GRPCPackageTests:x86_64+0x3827c1)
    #9 closure #3 in ClientConnection.willSetChannel(to:) ClientConnection.swift:229 (GRPCPackageTests:x86_64+0x35b00f)
    #10 partial apply for closure #3 in ClientConnection.willSetChannel(to:) <compiler-generated> (GRPCPackageTests:x86_64+0x367f2f)
    #11 thunk for @escaping @callee_guaranteed (@guaranteed Result<(), Error>) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x35bd17)
    #12 partial apply for thunk for @escaping @callee_guaranteed (@guaranteed Result<(), Error>) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x367fd0)
    #13 closure #1 in EventLoopFuture.whenComplete(_:) EventLoopFuture.swift:757 (GRPCPackageTests:x86_64+0x7001f5)
    #14 partial apply for closure #1 in EventLoopFuture.whenComplete(_:) <compiler-generated> (GRPCPackageTests:x86_64+0x7043ef)
    #15 CallbackList._run() EventLoopFuture.swift:83 (GRPCPackageTests:x86_64+0x6f3560)
    #16 EventLoopPromise._resolve(value:) EventLoopFuture.swift:230 (GRPCPackageTests:x86_64+0x6f52b5)
    #17 EventLoopPromise.succeed(_:) EventLoopFuture.swift:175 (GRPCPackageTests:x86_64+0x6f50a4)
    #18 closure #4 in BaseSocketChannel.close0(error:mode:promise:) BaseSocketChannel.swift:771 (GRPCPackageTests:x86_64+0x5fc0f2)
    #19 partial apply for closure #4 in BaseSocketChannel.close0(error:mode:promise:) <compiler-generated> (GRPCPackageTests:x86_64+0x609a6d)
    #20 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (GRPCPackageTests:x86_64+0x6df7f7)
    #21 partial apply for thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (GRPCPackageTests:x86_64+0x6f059d)
    #22 thunk for @escaping @callee_guaranteed () -> (@out ()) <compiler-generated> (GRPCPackageTests:x86_64+0x6df847)
    #23 partial apply for thunk for @escaping @callee_guaranteed () -> (@out ()) <compiler-generated> (GRPCPackageTests:x86_64+0x6eb4cb)
    #24 closure #3 in SelectableEventLoop.run() EventLoop.swift:943 (GRPCPackageTests:x86_64+0x6df8c4)
    #25 partial apply for closure #3 in SelectableEventLoop.run() <compiler-generated> (GRPCPackageTests:x86_64+0x6eb3bb)
    #26 thunk for @callee_guaranteed () -> (@error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x4b300f)
    #27 thunk for @callee_guaranteed () -> (@error @owned Error)partial apply <compiler-generated> (GRPCPackageTests:x86_64+0x6eb427)
    #28 closure #1 in withAutoReleasePool<A>(_:) EventLoop.swift:640 (GRPCPackageTests:x86_64+0x6d87a8)
    #29 partial apply for closure #1 in withAutoReleasePool<A>(_:) <compiler-generated> (GRPCPackageTests:x86_64+0x6f061a)
    #30 autoreleasepool<A>(invoking:) <null>:3201376 (libswiftObjectiveC.dylib:x86_64+0x2f0d)
    #31 SelectableEventLoop.run() EventLoop.swift:942 (GRPCPackageTests:x86_64+0x6ddbd4)
    #32 closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:initializer:) EventLoop.swift:1114 (GRPCPackageTests:x86_64+0x6e317a)
    #33 partial apply for closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:initializer:) <compiler-generated> (GRPCPackageTests:x86_64+0x6f0049)
    #34 thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x6e3b4b)
    #35 partial apply for thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> () <compiler-generated> (GRPCPackageTests:x86_64+0x7ee468)
    #36 closure #1 in static NIOThread.spawnAndRun(name:detachThread:body:) Thread.swift:110 (GRPCPackageTests:x86_64+0x7ee957)
    #37 @objc closure #1 in static NIOThread.spawnAndRun(name:detachThread:body:) <compiler-generated> (GRPCPackageTests:x86_64+0x7eea10)

  Previous write of size 8 at 0x7b1c0000dc28 by main thread:
    #0 ConnectivityStateMonitor.delegate.setter <compiler-generated> (GRPCPackageTests:x86_64+0x38184e)
    #1 ClientConnectionBackoffTests.tearDown() ClientConnectionBackoffTests.swift:101 (GRPCPackageTests:x86_64+0x4cb1b3)
    #2 @objc ClientConnectionBackoffTests.tearDown() <compiler-generated> (GRPCPackageTests:x86_64+0x4cc7b4)
    #3 -[XCTestCase(Failures) performFailableBlock:testCaseRun:shouldInterruptTest:] <null>:3201376 (XCTest:x86_64+0xa1faf)

  Location is heap block of size 98 at 0x7b1c0000dc10 allocated by main thread:
    #0 malloc <null>:3201408 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x4e6ba)
    #1 swift_slowAlloc <null>:3201408 (libswiftCore.dylib:x86_64+0x2cb698)
    #2 ClientConnection.init(configuration:) ClientConnection.swift:97 (GRPCPackageTests:x86_64+0x3546f0)
    #3 ClientConnection.__allocating_init(configuration:) ClientConnection.swift (GRPCPackageTests:x86_64+0x3543e1)
    #4 ClientConnectionBackoffTests.testClientEventuallyConnects() ClientConnectionBackoffTests.swift:155 (GRPCPackageTests:x86_64+0x4ce7c4)
    #5 @objc ClientConnectionBackoffTests.testClientEventuallyConnects() <compiler-generated> (GRPCPackageTests:x86_64+0x4cfb17)
    #6 __invoking___ <null>:3201408 (CoreFoundation:x86_64h+0x4a1cb)

  Mutex M2633 (0x7b100001e3c0) created at:
    #0 pthread_mutex_init <null>:3201264 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2ba03)
    #1 Lock.init() lock.swift:35 (GRPCPackageTests:x86_64+0x806d70)
    #2 Lock.__allocating_init() lock.swift (GRPCPackageTests:x86_64+0x806b34)
    #3 ConnectivityStateMonitor.init(delegate:) ConnectivityState.swift:62 (GRPCPackageTests:x86_64+0x381fb9)
    #4 ConnectivityStateMonitor.__allocating_init(delegate:) ConnectivityState.swift (GRPCPackageTests:x86_64+0x381d97)
    #5 ClientConnection.init(configuration:) ClientConnection.swift:97 (GRPCPackageTests:x86_64+0x3546f0)
    #6 ClientConnection.__allocating_init(configuration:) ClientConnection.swift (GRPCPackageTests:x86_64+0x3543e1)
    #7 ClientConnectionBackoffTests.testClientEventuallyConnects() ClientConnectionBackoffTests.swift:155 (GRPCPackageTests:x86_64+0x4ce7c4)
    #8 @objc ClientConnectionBackoffTests.testClientEventuallyConnects() <compiler-generated> (GRPCPackageTests:x86_64+0x4cfb17)
    #9 __invoking___ <null>:3201264 (CoreFoundation:x86_64h+0x4a1cb)

  Thread T18 (tid=10032874, running) created by main thread at:
    #0 pthread_create <null>:3201456 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2aa2d)
    #1 static NIOThread.spawnAndRun(name:detachThread:body:) Thread.swift:96 (GRPCPackageTests:x86_64+0x7ed8d8)
    #2 static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:initializer:) EventLoop.swift:1100 (GRPCPackageTests:x86_64+0x6e2ae7)
    #3 closure #1 in MultiThreadedEventLoopGroup.init(threadInitializers:) EventLoop.swift:1146 (GRPCPackageTests:x86_64+0x6e43e1)
    #4 partial apply for closure #1 in MultiThreadedEventLoopGroup.init(threadInitializers:) <compiler-generated> (GRPCPackageTests:x86_64+0x6ebd98)
    #5 thunk for @callee_guaranteed (@guaranteed @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()) -> (@owned SelectableEventLoop, @error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x6e4570)
    #6 partial apply for thunk for @callee_guaranteed (@guaranteed @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()) -> (@owned SelectableEventLoop, @error @owned Error) <compiler-generated> (GRPCPackageTests:x86_64+0x6ebe12)
    #7 Collection.map<A>(_:) <null>:3201456 (libswiftCore.dylib:x86_64+0xfc8e)
    #8 MultiThreadedEventLoopGroup.__allocating_init(threadInitializers:) EventLoop.swift (GRPCPackageTests:x86_64+0x6e3bcf)
    #9 MultiThreadedEventLoopGroup.__allocating_init(numberOfThreads:) EventLoop.swift:1134 (GRPCPackageTests:x86_64+0x6e3a7f)
    #10 ClientConnectionBackoffTests.setUp() ClientConnectionBackoffTests.swift:95 (GRPCPackageTests:x86_64+0x4cae2d)
    #11 @objc ClientConnectionBackoffTests.setUp() <compiler-generated> (GRPCPackageTests:x86_64+0x4caf24)
    #12 -[XCTestCase(Failures) performFailableBlock:testCaseRun:shouldInterruptTest:] <null>:3201456 (XCTest:x86_64+0xa1faf)

SUMMARY: ThreadSanitizer: data race <compiler-generated> in ConnectivityStateMonitor.delegate.getter
==================
Test Case '-[GRPCTests.ClientConnectionBackoffTests testClientEventuallyConnects]' passed (1.053 seconds).
@glbrntt glbrntt added the nio label Nov 11, 2019
glbrntt added a commit to glbrntt/grpc-swift that referenced this issue Nov 13, 2019
Motivation:

- It was not possible to update the connectivity delegate in a thread
  safe way.
- See grpc#622

Modifications:

Require the state lock to get/set the connectivity state delegate.

Result:

TSAN is happy.
glbrntt added a commit that referenced this issue Nov 13, 2019
Motivation:

- It was not possible to update the connectivity delegate in a thread
  safe way.
- See #622

Modifications:

Require the state lock to get/set the connectivity state delegate.

Result:

TSAN is happy.
@glbrntt glbrntt closed this as completed Nov 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants