|
|
@ -374,6 +374,79 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { |
|
|
|
SendRpcs(1, false); |
|
|
|
SendRpcs(1, false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { |
|
|
|
|
|
|
|
MAYBE_SKIP_TEST; |
|
|
|
|
|
|
|
ResetStub(); |
|
|
|
|
|
|
|
std::mutex mu1, mu2, mu3; |
|
|
|
|
|
|
|
std::condition_variable cv1, cv2, cv3; |
|
|
|
|
|
|
|
bool done1 = false; |
|
|
|
|
|
|
|
EchoRequest request1, request2, request3; |
|
|
|
|
|
|
|
request1.set_message("Hello locked world1."); |
|
|
|
|
|
|
|
EchoResponse response1; |
|
|
|
|
|
|
|
ClientContext cli_ctx1; |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l(mu1); |
|
|
|
|
|
|
|
stub_->experimental_async()->Echo( |
|
|
|
|
|
|
|
&cli_ctx1, &request1, &response1, |
|
|
|
|
|
|
|
[&mu1, this, &cv1, &done1, &request1, &response1](Status s1) { |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l1(mu1); |
|
|
|
|
|
|
|
EXPECT_TRUE(s1.ok()); |
|
|
|
|
|
|
|
EXPECT_EQ(request1.message(), response1.message()); |
|
|
|
|
|
|
|
// start the second level of nesting
|
|
|
|
|
|
|
|
std::mutex mu2; |
|
|
|
|
|
|
|
bool done2 = false; |
|
|
|
|
|
|
|
std::condition_variable cv2; |
|
|
|
|
|
|
|
EchoRequest request2; |
|
|
|
|
|
|
|
request2.set_message("Hello locked world2."); |
|
|
|
|
|
|
|
EchoResponse response2; |
|
|
|
|
|
|
|
ClientContext cli_ctx2; |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l2(mu2); |
|
|
|
|
|
|
|
stub_->experimental_async()->Echo( |
|
|
|
|
|
|
|
&cli_ctx2, &request2, &response2, |
|
|
|
|
|
|
|
[&mu2, this, &cv2, &done2, &request2, &response2](Status s2) { |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l2(mu2); |
|
|
|
|
|
|
|
EXPECT_TRUE(s2.ok()); |
|
|
|
|
|
|
|
EXPECT_EQ(request2.message(), response2.message()); |
|
|
|
|
|
|
|
// start the third level of nesting
|
|
|
|
|
|
|
|
std::mutex mu3; |
|
|
|
|
|
|
|
bool done3 = false; |
|
|
|
|
|
|
|
std::condition_variable cv3; |
|
|
|
|
|
|
|
EchoRequest request3; |
|
|
|
|
|
|
|
request3.set_message("Hello locked world2."); |
|
|
|
|
|
|
|
EchoResponse response3; |
|
|
|
|
|
|
|
ClientContext cli_ctx3; |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l3(mu3); |
|
|
|
|
|
|
|
stub_->experimental_async()->Echo( |
|
|
|
|
|
|
|
&cli_ctx3, &request3, &response3, |
|
|
|
|
|
|
|
[&mu3, &cv3, &done3, &request3, &response3](Status s3) { |
|
|
|
|
|
|
|
std::lock_guard<std::mutex> l(mu3); |
|
|
|
|
|
|
|
EXPECT_TRUE(s3.ok()); |
|
|
|
|
|
|
|
EXPECT_EQ(request3.message(), response3.message()); |
|
|
|
|
|
|
|
done3 = true; |
|
|
|
|
|
|
|
cv3.notify_all(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
done2 = true; |
|
|
|
|
|
|
|
cv2.notify_all(); |
|
|
|
|
|
|
|
// Wait for inner most rpc to return.
|
|
|
|
|
|
|
|
while (!done3) { |
|
|
|
|
|
|
|
cv3.wait(l3); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
// Wait for second rpc to return.
|
|
|
|
|
|
|
|
while (!done2) { |
|
|
|
|
|
|
|
cv2.wait(l2); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
done1 = true; |
|
|
|
|
|
|
|
cv1.notify_all(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l1(mu1); |
|
|
|
|
|
|
|
while (!done1) { |
|
|
|
|
|
|
|
cv1.wait(l1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { |
|
|
|
TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { |
|
|
|
MAYBE_SKIP_TEST; |
|
|
|
MAYBE_SKIP_TEST; |
|
|
|
ResetStub(); |
|
|
|
ResetStub(); |
|
|
|