Clean up the test

pull/19311/head
Mikko Rantanen 5 years ago
parent 0c9ddc9d23
commit a8ab03d758
No known key found for this signature in database
GPG Key ID: B680E9CE10A55798
  1. 107
      test/core/iomgr/pollset_windows_starvation_test.cc

@ -1,6 +1,6 @@
/*
*
* Copyright 2015 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,31 +15,27 @@
* limitations under the License.
*
*/
#if defined(GRPC_WINSOCK_SOCKET)
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
#include <vector>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iocp_windows.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_windows.h"
#include "src/core/lib/surface/init.h"
#include "test/core/util/test_config.h"
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
struct ThreadParams {
gpr_cv cv;
gpr_mu mu;
int complete;
};
int main(int argc, char** argv) {
grpc_init();
@ -60,49 +56,64 @@ int main(int argc, char** argv) {
// specific grpc_pollset_kick will also kick pollers from other pollsets
// if there are no pollers in the current pollset. This frees up the
// last thread and completes the test.
std::condition_variable cv;
std::mutex m;
int complete = 0;
std::vector<std::thread> threads;
ThreadParams params = {};
gpr_cv_init(&params.cv);
gpr_mu_init(&params.mu);
std::vector<grpc_core::Thread> threads;
for (int i = 0; i < 3; i++) {
threads.push_back(std::thread([&]() {
grpc_core::ExecCtx exec_ctx;
gpr_mu* g_mu;
grpc_pollset g_pollset = {};
grpc_pollset_init(&g_pollset, &g_mu);
gpr_mu_lock(g_mu);
// Queue for work and once we're done, make sure to kick the remaining
// threads.
grpc_error* error;
error = grpc_pollset_work(&g_pollset, NULL, GRPC_MILLIS_INF_FUTURE);
error = grpc_pollset_kick(&g_pollset, NULL);
gpr_mu_unlock(g_mu);
{
std::unique_lock<std::mutex> lock(m);
complete++;
cv.notify_all();
}
}));
grpc_core::Thread thd(
"Poller",
[](void* params) {
ThreadParams* tparams = static_cast<ThreadParams*>(params);
grpc_core::ExecCtx exec_ctx;
gpr_mu* mu;
grpc_pollset pollset = {};
grpc_pollset_init(&pollset, &mu);
gpr_mu_lock(mu);
// Queue for work and once we're done, make sure to kick the remaining
// threads.
grpc_millis deadline = grpc_timespec_to_millis_round_up(
grpc_timeout_seconds_to_deadline(5));
grpc_error* error;
error = grpc_pollset_work(&pollset, NULL, deadline);
error = grpc_pollset_kick(&pollset, NULL);
gpr_mu_unlock(mu);
{
gpr_mu_lock(&tparams->mu);
tparams->complete++;
gpr_cv_signal(&tparams->cv);
gpr_mu_unlock(&tparams->mu);
}
},
&params);
thd.Start();
threads.push_back(std::move(thd));
}
// Wait for the threads to start working and then kick one of them.
std::this_thread::sleep_for(std::chrono::milliseconds(10));
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(10));
grpc_iocp_kick();
// Wait for the threads to complete.
{
std::unique_lock<std::mutex> lock(m);
if (!cv.wait_for(lock, std::chrono::seconds(1),
[&] { return complete == 3; }))
return EXIT_FAILURE;
gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1);
gpr_mu_lock(&params.mu);
while (params.complete != 3 && !gpr_cv_wait(&params.cv, &params.mu, deadline))
;
if (params.complete != 3) {
gpr_mu_unlock(&params.mu);
for (auto& t : threads) t.Join();
return EXIT_FAILURE;
}
for (auto& t : threads) t.join();
gpr_mu_unlock(&params.mu);
for (auto& t : threads) t.Join();
return EXIT_SUCCESS;
}
#else /* defined(GRPC_WINSOCK_SOCKET) */
int main(int /*argc*/, char** /*argv*/) { return 0; }
#endif

Loading…
Cancel
Save