runner: syncronize shimListener connChan access Concurrent writes and closes on a channel are a data race. The shimListener connChan is written to by the shimDispatcher and closed by the shimListener such that the operations can happen concurrently. There is already a lock on shimListener to set the error and close the channel, so reuse that lock to syncronize the writes to the channel as well. This is slightly slower, but that should be fine. Ideally the write and close operations would be more tightly coupled, but that would require a more significant refactor, the shape of which is not obvious. Change-Id: I534aebacaa3c99a18d34858fa1ca7686727fdada Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/88907 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/shim_dispatcher.go b/ssl/test/runner/shim_dispatcher.go index 4fd421f..04303e6 100644 --- a/ssl/test/runner/shim_dispatcher.go +++ b/ssl/test/runner/shim_dispatcher.go
@@ -113,7 +113,16 @@ return fmt.Errorf("shim ID %d not found", shimID) } + // Concurrent channel writes and closes can cause data races. Locking + // ensures that the channel is not closed while we are writing to it. This + // is slightly slower, but that should be fine. + shim.lock.Lock() + defer shim.lock.Unlock() + if shim.err != nil { + return fmt.Errorf("shim ID %d has been closed", shimID) + } shim.connChan <- conn + return nil }