|
|
|
@ -35,17 +35,77 @@ |
|
|
|
|
#include <grpc/slice.h> |
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
#include <grpc/support/thd.h> |
|
|
|
|
#include "src/core/lib/profiling/timers.h" |
|
|
|
|
|
|
|
|
|
namespace grpc { |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
void WatchStateChange(void* arg); |
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
// Constantly watches channel connectivity status to reconnect a transiently
|
|
|
|
|
// disconnected channel. This is a temporary work-around before we have retry
|
|
|
|
|
// support.
|
|
|
|
|
class ChannelConnectivityWatcher { |
|
|
|
|
public: |
|
|
|
|
ChannelConnectivityWatcher(Channel* channel) |
|
|
|
|
: channel_(channel), thd_id_(0), being_destroyed_(0) {} |
|
|
|
|
|
|
|
|
|
void WatchStateChangeImpl() { |
|
|
|
|
grpc_connectivity_state state = GRPC_CHANNEL_IDLE; |
|
|
|
|
while (state != GRPC_CHANNEL_SHUTDOWN) { |
|
|
|
|
if (gpr_atm_no_barrier_load(&being_destroyed_) == 1) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
channel_->WaitForStateChange( |
|
|
|
|
state, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
|
|
|
|
gpr_time_from_seconds(1, GPR_TIMESPAN))); |
|
|
|
|
state = channel_->GetState(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void StartWatching() { |
|
|
|
|
gpr_thd_options options = gpr_thd_options_default(); |
|
|
|
|
gpr_thd_options_set_joinable(&options); |
|
|
|
|
gpr_thd_new(&thd_id_, &WatchStateChange, this, &options); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Destroy() { |
|
|
|
|
if (thd_id_ != 0) { |
|
|
|
|
gpr_atm_no_barrier_store(&being_destroyed_, 1); |
|
|
|
|
gpr_thd_join(thd_id_); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
Channel* channel_; |
|
|
|
|
gpr_thd_id thd_id_; |
|
|
|
|
gpr_atm being_destroyed_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
void WatchStateChange(void* arg) { |
|
|
|
|
ChannelConnectivityWatcher* watcher = |
|
|
|
|
static_cast<ChannelConnectivityWatcher*>(arg); |
|
|
|
|
watcher->WatchStateChangeImpl(); |
|
|
|
|
} |
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
static internal::GrpcLibraryInitializer g_gli_initializer; |
|
|
|
|
Channel::Channel(const grpc::string& host, grpc_channel* channel) |
|
|
|
|
: host_(host), c_channel_(channel) { |
|
|
|
|
: connectivity_watcher_(new ChannelConnectivityWatcher(this)), |
|
|
|
|
host_(host), |
|
|
|
|
c_channel_(channel) { |
|
|
|
|
g_gli_initializer.summon(); |
|
|
|
|
if (host != "inproc") { |
|
|
|
|
connectivity_watcher_->StartWatching(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Channel::~Channel() { grpc_channel_destroy(c_channel_); } |
|
|
|
|
Channel::~Channel() { |
|
|
|
|
connectivity_watcher_->Destroy(); |
|
|
|
|
grpc_channel_destroy(c_channel_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|