api watch unblock func kills only its own channel

pull/11204/head
Alexander Polcyn 8 years ago
parent 42d858a99d
commit c24d53b0cf
  1. 56
      src/ruby/end2end/multiple_killed_watching_threads_driver.rb
  2. 18
      src/ruby/ext/grpc/rb_channel.c
  3. 1
      tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh

@ -0,0 +1,56 @@
#!/usr/bin/env ruby
# Copyright 2016, 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.
require_relative './end2end_common'
Thread.abort_on_exception = true
include GRPC::Core::ConnectivityStates
def watch_state(ch)
thd = Thread.new do
state = ch.connectivity_state(false)
fail "non-idle state: #{state}" unless state == IDLE
ch.watch_connectivity_state(IDLE, Time.now + 360)
end
sleep 0.1
thd.kill
end
def main
10.times do
ch = GRPC::Core::Channel.new('dummy_host',
nil, :this_channel_is_insecure)
watch_state(ch)
end
end
main

@ -366,6 +366,16 @@ static void *wait_for_watch_state_op_complete_without_gvl(void *arg) {
return success;
}
static void wait_for_watch_state_op_complete_unblocking_func(void *arg) {
bg_watched_channel *bg = (bg_watched_channel *)arg;
gpr_mu_lock(&global_connection_polling_mu);
if (!bg->channel_destroyed) {
grpc_channel_destroy(bg->channel);
bg->channel_destroyed = 1;
}
gpr_mu_unlock(&global_connection_polling_mu);
}
/* Wait until the channel's connectivity state becomes different from
* "last_state", or "deadline" expires.
* Returns true if the the channel's connectivity state becomes
@ -400,7 +410,7 @@ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self,
op_success = rb_thread_call_without_gvl(
wait_for_watch_state_op_complete_without_gvl, &stack,
run_poll_channels_loop_unblocking_func, NULL);
wait_for_watch_state_op_complete_unblocking_func, wrapper->bg_wrapped);
return op_success ? Qtrue : Qfalse;
}
@ -577,11 +587,7 @@ static void grpc_rb_channel_try_register_connection_polling(
return;
}
GPR_ASSERT(bg->refcount == 1);
if (bg->channel_destroyed) {
GPR_ASSERT(abort_channel_polling);
return;
}
if (abort_channel_polling) {
if (bg->channel_destroyed || abort_channel_polling) {
return;
}

@ -41,4 +41,5 @@ ruby src/ruby/end2end/sig_int_during_channel_watch_driver.rb || EXIT_CODE=1
ruby src/ruby/end2end/killed_client_thread_driver.rb || EXIT_CODE=1
ruby src/ruby/end2end/forking_client_driver.rb || EXIT_CODE=1
ruby src/ruby/end2end/grpc_class_init_driver.rb || EXIT_CODE=1
ruby src/ruby/end2end/multiple_killed_watching_threads_driver.rb || EXIT_CODE=1
exit $EXIT_CODE

Loading…
Cancel
Save