|
|
|
@ -382,62 +382,37 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { |
|
|
|
|
bool done1 = false; |
|
|
|
|
EchoRequest request1, request2, request3; |
|
|
|
|
request1.set_message("Hello locked world1."); |
|
|
|
|
EchoResponse response1; |
|
|
|
|
ClientContext cli_ctx1; |
|
|
|
|
request2.set_message("Hello locked world2."); |
|
|
|
|
request3.set_message("Hello locked world3."); |
|
|
|
|
EchoResponse response1, response2, response3; |
|
|
|
|
ClientContext cli_ctx1, cli_ctx2, cli_ctx3; |
|
|
|
|
{ |
|
|
|
|
std::unique_lock<std::mutex> l(mu1); |
|
|
|
|
stub_->experimental_async()->Echo( |
|
|
|
|
&cli_ctx1, &request1, &response1, |
|
|
|
|
[&mu1, this, &cv1, &done1, &request1, &response1](Status s1) { |
|
|
|
|
[this, &mu1, &mu2, &mu3, &cv1, &done1, &request1, &request2, &request3, &response1, &response2, &response3, &cli_ctx1, &cli_ctx2, &cli_ctx3](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) { |
|
|
|
|
this->stub_->experimental_async()->Echo(&cli_ctx2, &request2, &response2, |
|
|
|
|
[this, &mu2, &mu3, &cv1, &done1, &request2, &request3, &response2, &response3, &cli_ctx3](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) { |
|
|
|
|
[&mu3, &cv1, &done1, &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(); |
|
|
|
|
done1 = true; |
|
|
|
|
cv1.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(); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|