Comment the requirements for changing grpc_poll_function and do

poll overrides in such a way as to avoid polling races
pull/5258/head
vjpai 9 years ago
parent 8afd49f359
commit cf4daebe27
  1. 4
      src/core/iomgr/pollset_posix.h
  2. 16
      test/cpp/end2end/async_end2end_test.cc

@ -142,6 +142,10 @@ int grpc_pollset_has_workers(grpc_pollset *pollset);
void grpc_remove_fd_from_all_epoll_sets(int fd); void grpc_remove_fd_from_all_epoll_sets(int fd);
/* override to allow tests to hook poll() usage */ /* override to allow tests to hook poll() usage */
/* NOTE: Any changes to grpc_poll_function must take place when the gRPC
is certainly not doing any polling anywhere.
Otherwise, there might be a race between changing the variable and actually
doing a polling operation */
typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int); typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int);
extern grpc_poll_function_type grpc_poll_function; extern grpc_poll_function_type grpc_poll_function;
extern grpc_wakeup_fd grpc_global_wakeup_fd; extern grpc_wakeup_fd grpc_global_wakeup_fd;

@ -86,21 +86,21 @@ class PollOverride {
grpc_poll_function_type prev_; grpc_poll_function_type prev_;
}; };
class PollingCheckRegion : public PollOverride { class PollingOverrider : public PollOverride {
public: public:
explicit PollingCheckRegion(bool allow_blocking) explicit PollingOverrider(bool allow_blocking)
: PollOverride(allow_blocking ? poll : assert_non_blocking_poll) {} : PollOverride(allow_blocking ? poll : assert_non_blocking_poll) {}
}; };
#else #else
class PollingCheckRegion { class PollingOverrider {
public: public:
explicit PollingCheckRegion(bool allow_blocking) {} explicit PollingOverrider(bool allow_blocking) {}
}; };
#endif #endif
class Verifier : public PollingCheckRegion { class Verifier {
public: public:
explicit Verifier(bool spin) : PollingCheckRegion(!spin), spin_(spin) {} explicit Verifier(bool spin) : spin_(spin) {}
Verifier& Expect(int i, bool expect_ok) { Verifier& Expect(int i, bool expect_ok) {
expectations_[tag(i)] = expect_ok; expectations_[tag(i)] = expect_ok;
return *this; return *this;
@ -180,7 +180,7 @@ class Verifier : public PollingCheckRegion {
class AsyncEnd2endTest : public ::testing::TestWithParam<bool> { class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
protected: protected:
AsyncEnd2endTest() {} AsyncEnd2endTest(): poll_override_(GetParam()) {}
void SetUp() GRPC_OVERRIDE { void SetUp() GRPC_OVERRIDE {
int port = grpc_pick_unused_port_or_die(); int port = grpc_pick_unused_port_or_die();
@ -249,6 +249,8 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
std::unique_ptr<Server> server_; std::unique_ptr<Server> server_;
grpc::testing::EchoTestService::AsyncService service_; grpc::testing::EchoTestService::AsyncService service_;
std::ostringstream server_address_; std::ostringstream server_address_;
PollingOverrider poll_override_;
}; };
TEST_P(AsyncEnd2endTest, SimpleRpc) { TEST_P(AsyncEnd2endTest, SimpleRpc) {

Loading…
Cancel
Save