|
|
|
@ -64,7 +64,7 @@ namespace testing { |
|
|
|
|
|
|
|
|
|
class AsyncQpsServerTest : public Server { |
|
|
|
|
public: |
|
|
|
|
AsyncQpsServerTest(const ServerConfig &config, int port) : shutdown_(false) { |
|
|
|
|
AsyncQpsServerTest(const ServerConfig &config, int port) { |
|
|
|
|
char *server_address = NULL; |
|
|
|
|
gpr_join_host_port(&server_address, "::", port); |
|
|
|
|
|
|
|
|
@ -96,6 +96,9 @@ class AsyncQpsServerTest : public Server { |
|
|
|
|
request_streaming, ProcessRPC)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < config.threads(); i++) { |
|
|
|
|
shutdown_state_.emplace_back(new PerThreadShutdownState()); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < config.threads(); i++) { |
|
|
|
|
threads_.push_back(std::thread([=]() { |
|
|
|
|
// Wait until work is available or we are shutting down
|
|
|
|
@ -105,11 +108,9 @@ class AsyncQpsServerTest : public Server { |
|
|
|
|
ServerRpcContext *ctx = detag(got_tag); |
|
|
|
|
// The tag is a pointer to an RPC context to invoke
|
|
|
|
|
bool still_going = ctx->RunNextState(ok); |
|
|
|
|
std::unique_lock<std::mutex> g(shutdown_mutex_); |
|
|
|
|
if (!shutdown_) { |
|
|
|
|
if (!shutdown_state_[i]->shutdown()) { |
|
|
|
|
// this RPC context is done, so refresh it
|
|
|
|
|
if (!still_going) { |
|
|
|
|
g.unlock(); |
|
|
|
|
ctx->Reset(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -122,9 +123,8 @@ class AsyncQpsServerTest : public Server { |
|
|
|
|
} |
|
|
|
|
~AsyncQpsServerTest() { |
|
|
|
|
server_->Shutdown(); |
|
|
|
|
{ |
|
|
|
|
std::lock_guard<std::mutex> g(shutdown_mutex_); |
|
|
|
|
shutdown_ = true; |
|
|
|
|
for (auto ss = shutdown_state_.begin(); ss != shutdown_state_.end(); ++ss) { |
|
|
|
|
(*ss)->set_shutdown(); |
|
|
|
|
} |
|
|
|
|
for (auto thr = threads_.begin(); thr != threads_.end(); thr++) { |
|
|
|
|
thr->join(); |
|
|
|
@ -316,8 +316,25 @@ class AsyncQpsServerTest : public Server { |
|
|
|
|
TestService::AsyncService async_service_; |
|
|
|
|
std::forward_list<ServerRpcContext *> contexts_; |
|
|
|
|
|
|
|
|
|
std::mutex shutdown_mutex_; |
|
|
|
|
bool shutdown_; |
|
|
|
|
class PerThreadShutdownState { |
|
|
|
|
public: |
|
|
|
|
PerThreadShutdownState() : shutdown_(false) {} |
|
|
|
|
|
|
|
|
|
bool shutdown() const { |
|
|
|
|
std::lock_guard<std::mutex> lock(mutex_); |
|
|
|
|
return shutdown_; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void set_shutdown() { |
|
|
|
|
std::lock_guard<std::mutex> lock(mutex_); |
|
|
|
|
shutdown_ = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
mutable std::mutex mutex_; |
|
|
|
|
bool shutdown_; |
|
|
|
|
}; |
|
|
|
|
std::vector<std::unique_ptr<PerThreadShutdownState>> shutdown_state_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
std::unique_ptr<Server> CreateAsyncServer(const ServerConfig &config, |
|
|
|
|