Previously, signal handlers were only given a chance to run upon receipt of an
entry in the RPC stream. Since there is no time bound on how long that might
take, there can be an arbitrarily long time gap between receipt of the signal
and the execution of the application's signal handlers.
Signal handlers are only run on the main thread. The cpython implementation
takes great care to ensure that the main thread does not block for an
arbitrarily long period between signal checks.
Our indefinite blocking was due to wait() invocations on condition variables
without a timeout.
This changes all usages of wait() in the the channel implementation to use a
wrapper that is responsive to signals even while waiting on an RPC.
A test has been added to verify this.
Tests are currently disabled under gevent due to
https://github.com/grpc/grpc/issues/18980, but a fix for that has been
found and should be merged shortly.
For each client side call, we execute grpc_error_get_status; in the common case
that there is no error, we save roughly 30 instructions and a call to strlen.
A closer reading of the API for getsockopt revealed that we were
depending on an implementation detail of getsockopt on Linux. This
assumption breaks down on MacOS.
getsockopt merely guarantees that it will return on 0 in case of failure
and a value greater than 0 in case of success. There is no guarantee as
to *which* non-zero value you will receive. On Linux, it seems to be 1,
the value which was explicitly set. On MacOS, it seems to be the value
of the FLAG which was set, i.e. 512 for SO_REUSEPORT.
This commit ensures the check we use does not rely on either of these
implementation details.
Bazel builds of test/cpp/end2end:end2end_test were failing on Mac OS with v1.8.0 due to missing gtest symbols. The issue is not seen in v1.8.1. A WORKSPACE file was added to gtest repo in 1.8.1, so gtest.BUILD can be removed.