Isolate timer checking in its own thread

reviewable/pr10961/r1
Craig Tiller 8 years ago
parent 8bb3ca757e
commit c3571791a5
  1. 7
      CMakeLists.txt
  2. 7
      Makefile
  3. 1
      binding.gyp
  4. 2
      build.yaml
  5. 1
      config.m4
  6. 3
      gRPC-Core.podspec
  7. 2
      grpc.gemspec
  8. 2
      package.xml
  9. 25
      src/core/lib/iomgr/ev_epoll_linux.c
  10. 31
      src/core/lib/iomgr/ev_poll_posix.c
  11. 2
      src/core/lib/iomgr/ev_posix.c
  12. 2
      src/core/lib/iomgr/ev_posix.h
  13. 3
      src/core/lib/iomgr/iomgr.c
  14. 2
      src/core/lib/iomgr/pollset_windows.c
  15. 166
      src/core/lib/iomgr/timer_manager.c
  16. 43
      src/core/lib/iomgr/timer_manager.h
  17. 31
      src/core/lib/surface/completion_queue.c
  18. 1
      src/python/grpcio/grpc_core_dependencies.py
  19. 18
      test/cpp/qps/client_async.cc
  20. 2
      tools/doxygen/Doxyfile.c++.internal
  21. 2
      tools/doxygen/Doxyfile.core.internal
  22. 3
      tools/run_tests/generated/sources_and_headers.json
  23. 3
      vsprojects/vcxproj/grpc++/grpc++.vcxproj
  24. 6
      vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
  25. 3
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
  26. 6
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
  27. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj
  28. 6
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  29. 3
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
  30. 6
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
  31. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  32. 6
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -984,6 +984,7 @@ add_library(grpc
src/core/lib/iomgr/time_averaged_stats.c
src/core/lib/iomgr/timer_generic.c
src/core/lib/iomgr/timer_heap.c
src/core/lib/iomgr/timer_manager.c
src/core/lib/iomgr/timer_uv.c
src/core/lib/iomgr/udp_server.c
src/core/lib/iomgr/unix_sockets_posix.c
@ -1310,6 +1311,7 @@ add_library(grpc_cronet
src/core/lib/iomgr/time_averaged_stats.c
src/core/lib/iomgr/timer_generic.c
src/core/lib/iomgr/timer_heap.c
src/core/lib/iomgr/timer_manager.c
src/core/lib/iomgr/timer_uv.c
src/core/lib/iomgr/udp_server.c
src/core/lib/iomgr/unix_sockets_posix.c
@ -1621,6 +1623,7 @@ add_library(grpc_test_util
src/core/lib/iomgr/time_averaged_stats.c
src/core/lib/iomgr/timer_generic.c
src/core/lib/iomgr/timer_heap.c
src/core/lib/iomgr/timer_manager.c
src/core/lib/iomgr/timer_uv.c
src/core/lib/iomgr/udp_server.c
src/core/lib/iomgr/unix_sockets_posix.c
@ -1877,6 +1880,7 @@ add_library(grpc_unsecure
src/core/lib/iomgr/time_averaged_stats.c
src/core/lib/iomgr/timer_generic.c
src/core/lib/iomgr/timer_heap.c
src/core/lib/iomgr/timer_manager.c
src/core/lib/iomgr/timer_uv.c
src/core/lib/iomgr/udp_server.c
src/core/lib/iomgr/unix_sockets_posix.c
@ -2296,6 +2300,7 @@ add_library(grpc++
src/core/lib/iomgr/time_averaged_stats.c
src/core/lib/iomgr/timer_generic.c
src/core/lib/iomgr/timer_heap.c
src/core/lib/iomgr/timer_manager.c
src/core/lib/iomgr/timer_uv.c
src/core/lib/iomgr/udp_server.c
src/core/lib/iomgr/unix_sockets_posix.c
@ -2621,6 +2626,7 @@ add_library(grpc++_cronet
src/core/lib/iomgr/time_averaged_stats.c
src/core/lib/iomgr/timer_generic.c
src/core/lib/iomgr/timer_heap.c
src/core/lib/iomgr/timer_manager.c
src/core/lib/iomgr/timer_uv.c
src/core/lib/iomgr/udp_server.c
src/core/lib/iomgr/unix_sockets_posix.c
@ -3390,6 +3396,7 @@ add_library(grpc++_unsecure
src/core/lib/iomgr/time_averaged_stats.c
src/core/lib/iomgr/timer_generic.c
src/core/lib/iomgr/timer_heap.c
src/core/lib/iomgr/timer_manager.c
src/core/lib/iomgr/timer_uv.c
src/core/lib/iomgr/udp_server.c
src/core/lib/iomgr/unix_sockets_posix.c

@ -2967,6 +2967,7 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \
@ -3291,6 +3292,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \
@ -3601,6 +3603,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \
@ -3829,6 +3832,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \
@ -4225,6 +4229,7 @@ LIBGRPC++_SRC = \
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \
@ -4558,6 +4563,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \
@ -5317,6 +5323,7 @@ LIBGRPC++_UNSECURE_SRC = \
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \

@ -718,6 +718,7 @@
'src/core/lib/iomgr/time_averaged_stats.c',
'src/core/lib/iomgr/timer_generic.c',
'src/core/lib/iomgr/timer_heap.c',
'src/core/lib/iomgr/timer_manager.c',
'src/core/lib/iomgr/timer_uv.c',
'src/core/lib/iomgr/udp_server.c',
'src/core/lib/iomgr/unix_sockets_posix.c',

@ -238,6 +238,7 @@ filegroups:
- src/core/lib/iomgr/timer.h
- src/core/lib/iomgr/timer_generic.h
- src/core/lib/iomgr/timer_heap.h
- src/core/lib/iomgr/timer_manager.h
- src/core/lib/iomgr/timer_uv.h
- src/core/lib/iomgr/udp_server.h
- src/core/lib/iomgr/unix_sockets_posix.h
@ -350,6 +351,7 @@ filegroups:
- src/core/lib/iomgr/time_averaged_stats.c
- src/core/lib/iomgr/timer_generic.c
- src/core/lib/iomgr/timer_heap.c
- src/core/lib/iomgr/timer_manager.c
- src/core/lib/iomgr/timer_uv.c
- src/core/lib/iomgr/udp_server.c
- src/core/lib/iomgr/unix_sockets_posix.c

@ -154,6 +154,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/time_averaged_stats.c \
src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/udp_server.c \
src/core/lib/iomgr/unix_sockets_posix.c \

@ -320,6 +320,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/timer.h',
'src/core/lib/iomgr/timer_generic.h',
'src/core/lib/iomgr/timer_heap.h',
'src/core/lib/iomgr/timer_manager.h',
'src/core/lib/iomgr/timer_uv.h',
'src/core/lib/iomgr/udp_server.h',
'src/core/lib/iomgr/unix_sockets_posix.h',
@ -531,6 +532,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/time_averaged_stats.c',
'src/core/lib/iomgr/timer_generic.c',
'src/core/lib/iomgr/timer_heap.c',
'src/core/lib/iomgr/timer_manager.c',
'src/core/lib/iomgr/timer_uv.c',
'src/core/lib/iomgr/udp_server.c',
'src/core/lib/iomgr/unix_sockets_posix.c',
@ -781,6 +783,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/timer.h',
'src/core/lib/iomgr/timer_generic.h',
'src/core/lib/iomgr/timer_heap.h',
'src/core/lib/iomgr/timer_manager.h',
'src/core/lib/iomgr/timer_uv.h',
'src/core/lib/iomgr/udp_server.h',
'src/core/lib/iomgr/unix_sockets_posix.h',

@ -236,6 +236,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/timer.h )
s.files += %w( src/core/lib/iomgr/timer_generic.h )
s.files += %w( src/core/lib/iomgr/timer_heap.h )
s.files += %w( src/core/lib/iomgr/timer_manager.h )
s.files += %w( src/core/lib/iomgr/timer_uv.h )
s.files += %w( src/core/lib/iomgr/udp_server.h )
s.files += %w( src/core/lib/iomgr/unix_sockets_posix.h )
@ -447,6 +448,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/time_averaged_stats.c )
s.files += %w( src/core/lib/iomgr/timer_generic.c )
s.files += %w( src/core/lib/iomgr/timer_heap.c )
s.files += %w( src/core/lib/iomgr/timer_manager.c )
s.files += %w( src/core/lib/iomgr/timer_uv.c )
s.files += %w( src/core/lib/iomgr/udp_server.c )
s.files += %w( src/core/lib/iomgr/unix_sockets_posix.c )

@ -245,6 +245,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/timer.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_generic.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_heap.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_manager.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_uv.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/udp_server.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/unix_sockets_posix.h" role="src" />
@ -456,6 +457,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/time_averaged_stats.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_generic.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_heap.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_manager.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/timer_uv.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/udp_server.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/unix_sockets_posix.c" role="src" />

@ -76,11 +76,6 @@ static int grpc_polling_trace = 0; /* Disabled by default */
static int grpc_wakeup_signal = -1;
static bool is_grpc_wakeup_signal_initialized = false;
/* TODO: sreek: Right now, this wakes up all pollers. In future we should make
* sure to wake up one polling thread (which can wake up other threads if
* needed) */
static grpc_wakeup_fd global_wakeup_fd;
/* Implements the function defined in grpc_posix.h. This function might be
* called before even calling grpc_init() to set either a different signal to
* use. If signum == -1, then the use of signals is disabled */
@ -454,8 +449,8 @@ static void polling_island_add_wakeup_fd_locked(polling_island *pi,
gpr_asprintf(&err_msg,
"epoll_ctl (epoll_fd: %d) add wakeup fd: %d failed with "
"error: %d (%s)",
pi->epoll_fd, GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd),
errno, strerror(errno));
pi->epoll_fd, GRPC_WAKEUP_FD_GET_READ_FD(wakeup_fd), errno,
strerror(errno));
append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
gpr_free(err_msg);
}
@ -558,7 +553,6 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx,
goto done;
}
polling_island_add_wakeup_fd_locked(pi, &global_wakeup_fd, error);
polling_island_add_wakeup_fd_locked(pi, &pi->workqueue_wakeup_fd, error);
if (initial_fd != NULL) {
@ -1116,11 +1110,10 @@ static grpc_error *pollset_global_init(void) {
gpr_tls_init(&g_current_thread_pollset);
gpr_tls_init(&g_current_thread_worker);
poller_kick_init();
return grpc_wakeup_fd_init(&global_wakeup_fd);
return GRPC_ERROR_NONE;
}
static void pollset_global_shutdown(void) {
grpc_wakeup_fd_destroy(&global_wakeup_fd);
gpr_tls_destroy(&g_current_thread_pollset);
gpr_tls_destroy(&g_current_thread_worker);
}
@ -1226,10 +1219,6 @@ static grpc_error *pollset_kick(grpc_pollset *p,
return error;
}
static grpc_error *kick_poller(void) {
return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
}
static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
gpr_mu_init(&pollset->po.mu);
*mu = &pollset->po.mu;
@ -1453,11 +1442,7 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
for (int i = 0; i < ep_rv; ++i) {
void *data_ptr = ep_ev[i].data.ptr;
if (data_ptr == &global_wakeup_fd) {
grpc_timer_consume_kick();
append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
err_desc);
} else if (data_ptr == &pi->workqueue_wakeup_fd) {
if (data_ptr == &pi->workqueue_wakeup_fd) {
append_error(error,
grpc_wakeup_fd_consume_wakeup(&pi->workqueue_wakeup_fd),
err_desc);
@ -1897,8 +1882,6 @@ static const grpc_event_engine_vtable vtable = {
.pollset_set_add_fd = pollset_set_add_fd,
.pollset_set_del_fd = pollset_set_del_fd,
.kick_poller = kick_poller,
.workqueue_ref = workqueue_ref,
.workqueue_unref = workqueue_unref,
.workqueue_scheduler = workqueue_scheduler,

@ -122,8 +122,6 @@ struct grpc_fd {
grpc_pollset *read_notifier_pollset;
};
static grpc_wakeup_fd global_wakeup_fd;
/* Begin polling on an fd.
Registers that the given pollset is interested in this fd - so that if read
or writability interest changes, the pollset can be kicked to pick up that
@ -784,19 +782,14 @@ static grpc_error *pollset_kick(grpc_pollset *p,
static grpc_error *pollset_global_init(void) {
gpr_tls_init(&g_current_thread_poller);
gpr_tls_init(&g_current_thread_worker);
return grpc_wakeup_fd_init(&global_wakeup_fd);
return GRPC_ERROR_NONE;
}
static void pollset_global_shutdown(void) {
grpc_wakeup_fd_destroy(&global_wakeup_fd);
gpr_tls_destroy(&g_current_thread_poller);
gpr_tls_destroy(&g_current_thread_worker);
}
static grpc_error *kick_poller(void) {
return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
}
/* main interface */
static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
@ -952,13 +945,10 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
}
fd_count = 0;
pfd_count = 2;
pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd);
pfd_count = 1;
pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker.wakeup_fd->fd);
pfds[0].events = POLLIN;
pfds[0].revents = 0;
pfds[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker.wakeup_fd->fd);
pfds[1].events = POLLIN;
pfds[1].revents = 0;
for (i = 0; i < pollset->fd_count; i++) {
if (fd_is_orphaned(pollset->fds[i])) {
GRPC_FD_UNREF(pollset->fds[i], "multipoller");
@ -974,7 +964,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
pollset->fd_count = fd_count;
gpr_mu_unlock(&pollset->mu);
for (i = 2; i < pfd_count; i++) {
for (i = 1; i < pfd_count; i++) {
grpc_fd *fd = watchers[i].fd;
pfds[i].events = (short)fd_begin_poll(fd, pollset, &worker, POLLIN,
POLLOUT, &watchers[i]);
@ -992,7 +982,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
work_combine_error(&error, GRPC_OS_ERROR(errno, "poll"));
}
for (i = 2; i < pfd_count; i++) {
for (i = 1; i < pfd_count; i++) {
if (watchers[i].fd == NULL) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
} else {
@ -1002,20 +992,15 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
}
}
} else if (r == 0) {
for (i = 2; i < pfd_count; i++) {
for (i = 1; i < pfd_count; i++) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
}
} else {
if (pfds[0].revents & POLLIN_CHECK) {
grpc_timer_consume_kick();
work_combine_error(&error,
grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd));
}
if (pfds[1].revents & POLLIN_CHECK) {
work_combine_error(
&error, grpc_wakeup_fd_consume_wakeup(&worker.wakeup_fd->fd));
}
for (i = 2; i < pfd_count; i++) {
for (i = 1; i < pfd_count; i++) {
if (watchers[i].fd == NULL) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
} else {
@ -1560,8 +1545,6 @@ static const grpc_event_engine_vtable vtable = {
.pollset_set_add_fd = pollset_set_add_fd,
.pollset_set_del_fd = pollset_set_del_fd,
.kick_poller = kick_poller,
.workqueue_ref = workqueue_ref,
.workqueue_unref = workqueue_unref,
.workqueue_scheduler = workqueue_scheduler,

@ -260,8 +260,6 @@ void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
g_event_engine->pollset_set_del_fd(exec_ctx, pollset_set, fd);
}
grpc_error *grpc_kick_poller(void) { return g_event_engine->kick_poller(); }
#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG
grpc_workqueue *grpc_workqueue_ref(grpc_workqueue *workqueue, const char *file,
int line, const char *reason) {

@ -93,8 +93,6 @@ typedef struct grpc_event_engine_vtable {
void (*pollset_set_del_fd)(grpc_exec_ctx *exec_ctx,
grpc_pollset_set *pollset_set, grpc_fd *fd);
grpc_error *(*kick_poller)(void);
void (*shutdown_engine)(void);
#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG

@ -47,6 +47,7 @@
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/network_status_tracker.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/timer_manager.h"
#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"
@ -65,6 +66,7 @@ void grpc_iomgr_init(void) {
g_root_object.name = "root";
grpc_network_status_init();
grpc_iomgr_platform_init();
grpc_timer_manager_init();
}
static size_t count_objects(void) {
@ -88,6 +90,7 @@ void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx) {
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN));
gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
grpc_timer_manager_shutdown();
grpc_iomgr_platform_flush();
gpr_mu_lock(&g_mu);

@ -227,6 +227,4 @@ grpc_error *grpc_pollset_kick(grpc_pollset *p,
return GRPC_ERROR_NONE;
}
void grpc_kick_poller(void) { grpc_iocp_kick(); }
#endif /* GRPC_WINSOCK_SOCKET */

@ -0,0 +1,166 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/lib/iomgr/timer_manager.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/thd.h>
#include "src/core/lib/iomgr/timer.h"
typedef struct completed_thread {
gpr_thd_id t;
struct completed_thread *next;
} completed_thread;
static gpr_mu g_mu;
static gpr_cv g_cv_wait;
static gpr_cv g_cv_shutdown;
static int g_thread_count;
static int g_waiter_count;
static bool g_shutdown;
static completed_thread *g_completed_threads;
static bool g_kicked;
#define MAX_WAITERS 3
static void timer_thread(void *unused);
static void gc_completed_threads(void) {
if (g_completed_threads != NULL) {
completed_thread *to_gc = g_completed_threads;
g_completed_threads = NULL;
gpr_mu_unlock(&g_mu);
while (to_gc != NULL) {
gpr_thd_join(to_gc->t);
completed_thread *next = to_gc->next;
gpr_free(to_gc);
to_gc = next;
}
gpr_mu_lock(&g_mu);
}
}
static void start_timer_thread_and_unlock(void) {
++g_waiter_count;
++g_thread_count;
gpr_mu_unlock(&g_mu);
gpr_log(GPR_DEBUG, "Spawn timer thread");
gpr_thd_id thd;
gpr_thd_options opt = gpr_thd_options_default();
gpr_thd_options_set_joinable(&opt);
gpr_thd_new(&thd, timer_thread, NULL, &opt);
}
static void timer_thread(void *unused) {
grpc_exec_ctx exec_ctx =
GRPC_EXEC_CTX_INITIALIZER(0, grpc_never_ready_to_finish, NULL);
for (;;) {
gpr_timespec next = gpr_inf_future(GPR_CLOCK_MONOTONIC);
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
if (grpc_timer_check(&exec_ctx, now, &next)) {
gpr_mu_lock(&g_mu);
--g_waiter_count;
bool start_thread = g_waiter_count == 0;
if (start_thread && !g_shutdown) {
start_timer_thread_and_unlock();
} else {
gpr_mu_unlock(&g_mu);
}
grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(&g_mu);
gc_completed_threads();
++g_waiter_count;
gpr_mu_unlock(&g_mu);
} else {
gpr_mu_lock(&g_mu);
if (g_shutdown) break;
if (gpr_cv_wait(&g_cv_wait, &g_mu, next)) {
if (g_kicked) {
grpc_timer_consume_kick();
g_kicked = false;
} else if (g_waiter_count > MAX_WAITERS) {
break;
}
}
gpr_mu_unlock(&g_mu);
}
}
--g_waiter_count;
--g_thread_count;
if (0 == g_thread_count) {
gpr_cv_signal(&g_cv_shutdown);
}
completed_thread *ct = gpr_malloc(sizeof(*ct));
ct->t = gpr_thd_currentid();
ct->next = g_completed_threads;
g_completed_threads = ct;
gpr_mu_unlock(&g_mu);
gpr_log(GPR_DEBUG, "End timer thread");
}
void grpc_timer_manager_init(void) {
gpr_mu_init(&g_mu);
gpr_cv_init(&g_cv_wait);
gpr_cv_init(&g_cv_shutdown);
g_thread_count = 0;
g_waiter_count = 0;
g_shutdown = false;
g_completed_threads = NULL;
gpr_mu_lock(&g_mu);
start_timer_thread_and_unlock();
}
void grpc_timer_manager_shutdown(void) {
gpr_mu_lock(&g_mu);
g_shutdown = true;
gpr_cv_broadcast(&g_cv_wait);
while (g_thread_count > 0) {
gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(GPR_CLOCK_REALTIME));
gc_completed_threads();
}
gpr_mu_unlock(&g_mu);
gpr_mu_destroy(&g_mu);
gpr_cv_destroy(&g_cv_wait);
gpr_cv_destroy(&g_cv_shutdown);
}
void grpc_kick_poller(void) {
gpr_mu_lock(&g_mu);
g_kicked = true;
gpr_cv_signal(&g_cv_wait);
gpr_mu_unlock(&g_mu);
}

@ -0,0 +1,43 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_IOMGR_TIMER_MANAGER_H
#define GRPC_CORE_IOMGR_TIMER_MANAGER_H
/* Timer Manager tries to keep one thread waiting for the next timeout at all
times */
void grpc_timer_manager_init(void);
void grpc_timer_manager_shutdown(void);
#endif

@ -580,20 +580,8 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
dump_pending_tags(cc);
break;
}
/* Check alarms - these are a global resource so we just ping
each time through on every pollset.
May update deadline to ensure timely wakeups.
TODO(ctiller): can this work be localized? */
gpr_timespec iteration_deadline = deadline;
if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
GPR_TIMER_MARK("alarm_triggered", 0);
gpr_mu_unlock(cc->mu);
grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(cc->mu);
continue;
} else {
grpc_error *err = cc->poller_vtable->work(&exec_ctx, POLLSET_FROM_CQ(cc),
NULL, now, iteration_deadline);
NULL, now, deadline);
if (err != GRPC_ERROR_NONE) {
gpr_mu_unlock(cc->mu);
const char *msg = grpc_error_string(err);
@ -605,7 +593,6 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
dump_pending_tags(cc);
break;
}
}
is_finished_arg.first_loop = false;
}
GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
@ -773,19 +760,8 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
dump_pending_tags(cc);
break;
}
/* Check alarms - these are a global resource so we just ping
each time through on every pollset.
May update deadline to ensure timely wakeups.
TODO(ctiller): can this work be localized? */
gpr_timespec iteration_deadline = deadline;
if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
GPR_TIMER_MARK("alarm_triggered", 0);
gpr_mu_unlock(cc->mu);
grpc_exec_ctx_flush(&exec_ctx);
gpr_mu_lock(cc->mu);
} else {
grpc_error *err = cc->poller_vtable->work(
&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, iteration_deadline);
grpc_error *err = cc->poller_vtable->work(&exec_ctx, POLLSET_FROM_CQ(cc),
&worker, now, deadline);
if (err != GRPC_ERROR_NONE) {
del_plucker(cc, tag, &worker);
gpr_mu_unlock(cc->mu);
@ -798,7 +774,6 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
dump_pending_tags(cc);
break;
}
}
is_finished_arg.first_loop = false;
del_plucker(cc, tag, &worker);
}

@ -143,6 +143,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/iomgr/time_averaged_stats.c',
'src/core/lib/iomgr/timer_generic.c',
'src/core/lib/iomgr/timer_heap.c',
'src/core/lib/iomgr/timer_manager.c',
'src/core/lib/iomgr/timer_uv.c',
'src/core/lib/iomgr/udp_server.c',
'src/core/lib/iomgr/unix_sockets_posix.c',

@ -238,10 +238,7 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
void* got_tag;
bool ok;
switch (cli_cqs_[thread_idx]->AsyncNext(
&got_tag, &ok,
std::chrono::system_clock::now() + std::chrono::milliseconds(10))) {
case CompletionQueue::GOT_EVENT: {
if (cli_cqs_[thread_idx]->Next(&got_tag, &ok)) {
// Got a regular event, so process it
ClientRpcContext* ctx = ClientRpcContext::detag(got_tag);
// Proceed while holding a lock to make sure that
@ -258,19 +255,10 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
delete ctx;
}
return true;
}
case CompletionQueue::TIMEOUT: {
std::lock_guard<std::mutex> l(shutdown_state_[thread_idx]->mutex);
if (shutdown_state_[thread_idx]->shutdown) {
return true;
}
return true;
}
case CompletionQueue::SHUTDOWN: // queue is shutting down, so we must be
// done
} else {
// queue is shutting down, so we must be done
return true;
}
GPR_UNREACHABLE_CODE(return true);
}
std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;

@ -1026,6 +1026,8 @@ src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_generic.h \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_heap.h \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_manager.h \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/timer_uv.h \
src/core/lib/iomgr/udp_server.c \

@ -1161,6 +1161,8 @@ src/core/lib/iomgr/timer_generic.c \
src/core/lib/iomgr/timer_generic.h \
src/core/lib/iomgr/timer_heap.c \
src/core/lib/iomgr/timer_heap.h \
src/core/lib/iomgr/timer_manager.c \
src/core/lib/iomgr/timer_manager.h \
src/core/lib/iomgr/timer_uv.c \
src/core/lib/iomgr/timer_uv.h \
src/core/lib/iomgr/udp_server.c \

@ -7791,6 +7791,7 @@
"src/core/lib/iomgr/timer.h",
"src/core/lib/iomgr/timer_generic.h",
"src/core/lib/iomgr/timer_heap.h",
"src/core/lib/iomgr/timer_manager.h",
"src/core/lib/iomgr/timer_uv.h",
"src/core/lib/iomgr/udp_server.h",
"src/core/lib/iomgr/unix_sockets_posix.h",
@ -7978,6 +7979,8 @@
"src/core/lib/iomgr/timer_generic.h",
"src/core/lib/iomgr/timer_heap.c",
"src/core/lib/iomgr/timer_heap.h",
"src/core/lib/iomgr/timer_manager.c",
"src/core/lib/iomgr/timer_manager.h",
"src/core/lib/iomgr/timer_uv.c",
"src/core/lib/iomgr/timer_uv.h",
"src/core/lib/iomgr/udp_server.c",

@ -437,6 +437,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
@ -702,6 +703,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">

@ -322,6 +322,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
@ -1031,6 +1034,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>

@ -431,6 +431,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
@ -686,6 +687,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">

@ -307,6 +307,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
@ -998,6 +1001,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>

@ -361,6 +361,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
@ -641,6 +642,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">

@ -202,6 +202,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
@ -992,6 +995,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>

@ -256,6 +256,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
@ -475,6 +476,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">

@ -259,6 +259,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
@ -746,6 +749,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>

@ -351,6 +351,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_generic.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
@ -608,6 +609,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">

@ -205,6 +205,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.c">
<Filter>src\core\lib\iomgr</Filter>
</ClCompile>
@ -902,6 +905,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_manager.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_uv.h">
<Filter>src\core\lib\iomgr</Filter>
</ClInclude>

Loading…
Cancel
Save