diff --git a/.travis.yml b/.travis.yml index 7d8634506c3..f1839ac174a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,19 @@ language: cpp before_install: - sudo add-apt-repository ppa:yjwong/gflags -y - sudo add-apt-repository ppa:h-rayflood/llvm -y + - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF + - echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list + - echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list - sudo apt-get update -qq - sudo apt-get install -qq libgtest-dev libgflags-dev python-virtualenv clang-3.5 - sudo pip install cpp-coveralls mako simplejson + - sudo apt-get install -qq mono-devel nunit + - wget www.nuget.org/NuGet.exe -O nuget.exe env: global: - RUBY_VERSION=2.1 - COVERALLS_PARALLEL=true + - NUGET="mono nuget.exe" matrix: - CONFIG=opt TEST=sanity - CONFIG=dbg TEST=c @@ -18,6 +24,7 @@ env: - CONFIG=opt TEST=node - CONFIG=opt TEST=ruby - CONFIG=opt TEST=python + - CONFIG=opt TEST=csharp - CONFIG=gcov TEST=c - CONFIG=gcov TEST=c++ - USE_GCC=4.4 CONFIG=opt TEST=build diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h index 19630c9b544..a58e9872e60 100644 --- a/include/grpc++/client_context.h +++ b/include/grpc++/client_context.h @@ -35,6 +35,7 @@ #define GRPCXX_CLIENT_CONTEXT_H #include +#include #include #include @@ -126,9 +127,10 @@ class ClientContext { friend class ::grpc::ClientAsyncResponseReader; grpc_call* call() { return call_; } - void set_call(grpc_call* call) { + void set_call(grpc_call* call, const std::shared_ptr& channel) { GPR_ASSERT(call_ == nullptr); call_ = call; + channel_ = channel; } grpc_completion_queue* cq() { return cq_; } @@ -137,6 +139,7 @@ class ClientContext { grpc::string authority() { return authority_; } bool initial_metadata_received_; + std::shared_ptr channel_; grpc_call* call_; grpc_completion_queue* cq_; gpr_timespec deadline_; diff --git a/include/grpc/support/tls.h b/include/grpc/support/tls.h index 1077fdec295..8dffd522559 100644 --- a/include/grpc/support/tls.h +++ b/include/grpc/support/tls.h @@ -44,7 +44,7 @@ Thread locals have type gpr_intptr. Declaring a thread local variable 'foo': - GPR_TLS_DECL(foo, initial_value); + GPR_TLS_DECL(foo); Thread locals always have static scope. Initializing a thread local (must be done at library initialization diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c index bcef7c35b5d..25b7cfda1a1 100644 --- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c +++ b/src/core/iomgr/pollset_multipoller_with_poll_posix.c @@ -203,7 +203,7 @@ static int multipoll_with_poll_pollset_maybe_work( } static void multipoll_with_poll_pollset_kick(grpc_pollset *p) { - grpc_pollset_kick_kick(&p->kick_state); + grpc_pollset_force_kick(p); } static void multipoll_with_poll_pollset_destroy(grpc_pollset *pollset) { diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c index 03fd94f1364..60d0dad6d87 100644 --- a/src/core/iomgr/pollset_posix.c +++ b/src/core/iomgr/pollset_posix.c @@ -47,9 +47,11 @@ #include "src/core/iomgr/fd_posix.h" #include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/socket_utils_posix.h" +#include "src/core/profiling/timers.h" #include #include #include +#include #include static grpc_pollset g_backup_pollset; @@ -57,6 +59,8 @@ static int g_shutdown_backup_poller; static gpr_event g_backup_poller_done; static gpr_event g_backup_pollset_shutdown_done; +GPR_TLS_DECL(g_current_thread_poller); + static void backup_poller(void *p) { gpr_timespec delta = gpr_time_from_millis(100); gpr_timespec last_poll = gpr_now(); @@ -76,17 +80,21 @@ static void backup_poller(void *p) { } void grpc_pollset_kick(grpc_pollset *p) { - if (p->counter) { + if (gpr_tls_get(&g_current_thread_poller) != (gpr_intptr)p && p->counter) { p->vtable->kick(p); } } void grpc_pollset_force_kick(grpc_pollset *p) { - grpc_pollset_kick_kick(&p->kick_state); + if (gpr_tls_get(&g_current_thread_poller) != (gpr_intptr)p) { + grpc_pollset_kick_kick(&p->kick_state); + } } static void kick_using_pollset_kick(grpc_pollset *p) { - grpc_pollset_kick_kick(&p->kick_state); + if (gpr_tls_get(&g_current_thread_poller) != (gpr_intptr)p) { + grpc_pollset_kick_kick(&p->kick_state); + } } /* global state management */ @@ -96,6 +104,8 @@ grpc_pollset *grpc_backup_pollset(void) { return &g_backup_pollset; } void grpc_pollset_global_init(void) { gpr_thd_id id; + gpr_tls_init(&g_current_thread_poller); + /* Initialize kick fd state */ grpc_pollset_kick_global_init(); @@ -129,6 +139,8 @@ void grpc_pollset_global_shutdown(void) { /* destroy the kick pipes */ grpc_pollset_kick_global_destroy(); + + gpr_tls_destroy(&g_current_thread_poller); } /* main interface */ @@ -161,8 +173,8 @@ void grpc_pollset_del_fd(grpc_pollset *pollset, grpc_fd *fd) { int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) { /* pollset->mu already held */ - gpr_timespec now; - now = gpr_now(); + gpr_timespec now = gpr_now(); + int r; if (gpr_time_cmp(now, deadline) > 0) { return 0; } @@ -172,7 +184,10 @@ int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) { if (grpc_alarm_check(&pollset->mu, now, &deadline)) { return 1; } - return pollset->vtable->maybe_work(pollset, deadline, now, 1); + gpr_tls_set(&g_current_thread_poller, (gpr_intptr)pollset); + r = pollset->vtable->maybe_work(pollset, deadline, now, 1); + gpr_tls_set(&g_current_thread_poller, 0); + return r; } void grpc_pollset_shutdown(grpc_pollset *pollset, @@ -396,6 +411,7 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset, pfd[1].events = grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher); r = poll(pfd, GPR_ARRAY_SIZE(pfd), timeout); + GRPC_TIMER_MARK(POLL_FINISHED, r); grpc_fd_end_poll(&fd_watcher); diff --git a/src/core/iomgr/resolve_address_windows.c b/src/core/iomgr/resolve_address_windows.c index ac31dadd9d7..9b416dfe8aa 100644 --- a/src/core/iomgr/resolve_address_windows.c +++ b/src/core/iomgr/resolve_address_windows.c @@ -65,7 +65,6 @@ grpc_resolved_addresses *grpc_blocking_resolve_address( int s; size_t i; grpc_resolved_addresses *addrs = NULL; - const gpr_timespec start_time = gpr_now(); /* parse name, splitting it into host and port parts */ gpr_split_host_port(name, &host, &port); @@ -108,9 +107,6 @@ grpc_resolved_addresses *grpc_blocking_resolve_address( } { - const gpr_timespec delay = gpr_time_sub(gpr_now(), start_time); - const int delay_ms = - delay.tv_sec * GPR_MS_PER_SEC + delay.tv_nsec / GPR_NS_PER_MS; for (i = 0; i < addrs->naddrs; i++) { char *buf; grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr, diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c index 6e10da97ccb..fe92846a716 100644 --- a/src/core/iomgr/tcp_server_windows.c +++ b/src/core/iomgr/tcp_server_windows.c @@ -192,7 +192,7 @@ static void start_accept(server_port *port) { } /* TODO(jtattermusch): probably a race here, we regularly get use-after-free on server shutdown */ - GPR_ASSERT(port->socket != 0xfeeefeee); + GPR_ASSERT(port->socket != (grpc_winsocket*)0xfeeefeee); success = port->AcceptEx(port->socket->socket, sock, port->addresses, 0, addrlen, addrlen, &bytes_received, &port->socket->read_info.overlapped); diff --git a/src/core/surface/server.c b/src/core/surface/server.c index e7719298701..3b129039bbf 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -1083,6 +1083,7 @@ static void begin_call(grpc_server *server, call_data *calld, &rc->data.batch.details->host_capacity, calld->host); cpstr(&rc->data.batch.details->method, &rc->data.batch.details->method_capacity, calld->path); + rc->data.batch.details->deadline = calld->deadline; grpc_call_set_completion_queue(calld->call, rc->data.batch.cq_bind); *rc->data.batch.call = calld->call; r->op = GRPC_IOREQ_RECV_INITIAL_METADATA; diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index 018ddc44563..b7c2859a1c9 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -34,6 +34,7 @@ #include "src/core/tsi/ssl_transport_security.h" #include +#include #include #include diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc index ba8882278f5..c541ddfb487 100644 --- a/src/cpp/client/channel.cc +++ b/src/cpp/client/channel.cc @@ -71,7 +71,7 @@ Call Channel::CreateCall(const RpcMethod& method, ClientContext* context, : context->authority().c_str(), context->raw_deadline()); GRPC_TIMER_MARK(CALL_CREATED, c_call); - context->set_call(c_call); + context->set_call(c_call, shared_from_this()); return Call(c_call, this, cq); } diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h index cd239247c82..46009d20bad 100644 --- a/src/cpp/client/channel.h +++ b/src/cpp/client/channel.h @@ -51,6 +51,7 @@ class Credentials; class StreamContextInterface; class Channel GRPC_FINAL : public GrpcLibrary, + public std::enable_shared_from_this, public ChannelInterface { public: Channel(const grpc::string& target, grpc_channel* c_channel); diff --git a/test/cpp/qps/smoke_test.cc b/test/cpp/qps/smoke_test.cc index e3907308325..2c60a9997c8 100644 --- a/test/cpp/qps/smoke_test.cc +++ b/test/cpp/qps/smoke_test.cc @@ -33,6 +33,8 @@ #include +#include + #include "test/cpp/qps/driver.h" #include "test/cpp/qps/report.h" @@ -136,6 +138,7 @@ static void RunQPS() { } // namespace grpc int main(int argc, char** argv) { + signal(SIGPIPE, SIG_IGN); using namespace grpc::testing; RunSynchronousStreamingPingPong(); RunSynchronousUnaryPingPong(); diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 6b6ed7ed386..beff8cc840c 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -1401,6 +1401,38 @@ grpc_cloud_prod_gen_csharp_mono_cmd() { echo $the_cmd } +# constructs the full dockerized csharp-mono service_account auth interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_service_account_creds_gen_csharp_mono_cmd() { + local workdir_flag="-w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug" + local env_flag="-e SSL_CERT_FILE=/cacerts/roots.pem " + env_flag+="-e GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json " + local cmd_prefix="sudo docker run $workdir_flag $env_flag grpc/csharp_mono"; + local test_script="mono Grpc.IntegrationTesting.Client.exe --use_tls=true"; + local gfe_flags=$(_grpc_prod_gfe_flags); + local the_cmd="$cmd_prefix $test_script $gfe_flags $@"; + echo $the_cmd +} + +# constructs the full dockerized csharp-mono gce auth interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_compute_engine_creds_gen_csharp_mono_cmd() { + local workdir_flag="-w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug" + local env_flag="-e SSL_CERT_FILE=/cacerts/roots.pem " + local cmd_prefix="sudo docker run $workdir_flag $env_flag grpc/csharp_mono"; + local test_script="mono Grpc.IntegrationTesting.Client.exe --use_tls=true"; + local gfe_flags=$(_grpc_prod_gfe_flags) + local added_gfe_flags=$(_grpc_gce_test_flags) + local the_cmd="$cmd_prefix $test_script $gfe_flags $added_gfe_flags $@"; + echo $the_cmd +} + # outputs the flags passed to gfe tests _grpc_prod_gfe_flags() { echo " --server_port=443 --server_host=grpc-test.sandbox.google.com --server_host_override=grpc-test.sandbox.google.com" diff --git a/tools/run_tests/build_csharp.sh b/tools/run_tests/build_csharp.sh index 8227ad37bca..eae7bd50405 100755 --- a/tools/run_tests/build_csharp.sh +++ b/tools/run_tests/build_csharp.sh @@ -30,9 +30,21 @@ set -ex +if [ "$CONFIG" = "dbg" ] +then + MSBUILD_CONFIG="Debug" +else + MSBUILD_CONFIG="Release" +fi + # change to gRPC repo root cd $(dirname $0)/../.. root=`pwd` -xbuild src/csharp/Grpc.sln +if [ -n "$NUGET" ] +then + $NUGET restore src/csharp/Grpc.sln +fi + +xbuild /p:Configuration=$MSBUILD_CONFIG src/csharp/Grpc.sln diff --git a/tools/run_tests/run_csharp.sh b/tools/run_tests/run_csharp.sh index d10a41ae9f4..752e83ef705 100755 --- a/tools/run_tests/run_csharp.sh +++ b/tools/run_tests/run_csharp.sh @@ -30,17 +30,22 @@ set -ex +CONFIG=${CONFIG:-opt} + +if [ "$CONFIG" = "dbg" ] +then + MSBUILD_CONFIG="Debug" +else + MSBUILD_CONFIG="Release" +fi + # change to gRPC repo root cd $(dirname $0)/../.. root=`pwd` cd src/csharp -# TODO: All the tests run pretty fast. In the future, we might need to teach -# run_tests.py about separate tests to make them run in parallel. -for assembly_name in Grpc.Core.Tests Grpc.Examples.Tests Grpc.IntegrationTesting -do - LD_LIBRARY_PATH=$root/libs/dbg nunit-console -labels $assembly_name/bin/Debug/$assembly_name.dll -done +export LD_LIBRARY_PATH=$root/libs/$CONFIG +nunit-console -labels "$1/bin/$MSBUILD_CONFIG/$1.dll" diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 5165983d970..50fdec7f5f2 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -61,7 +61,7 @@ class SimpleConfig(object): self.environ = environ self.environ['CONFIG'] = config - def job_spec(self, cmdline, hash_targets): + def job_spec(self, cmdline, hash_targets, shortname=None): """Construct a jobset.JobSpec for a test under this config Args: @@ -74,6 +74,7 @@ class SimpleConfig(object): be listed """ return jobset.JobSpec(cmdline=cmdline, + shortname=shortname, environ=self.environ, hash_targets=hash_targets if self.allow_hashing else None) @@ -218,9 +219,13 @@ class RubyLanguage(object): class CSharpLanguage(object): - def test_specs(self, config, travis): - return [config.job_spec('tools/run_tests/run_csharp.sh', None)] + assemblies = ['Grpc.Core.Tests', + 'Grpc.Examples.Tests', + 'Grpc.IntegrationTesting'] + return [config.job_spec(['tools/run_tests/run_csharp.sh', assembly], + None, shortname=assembly) + for assembly in assemblies ] def make_targets(self): return ['grpc_csharp_ext']