1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "pdx/client.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <log/log.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/trace.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Client::EnableAutoReconnect(int64_t reconnect_timeout_ms) { 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_factory_) { 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko reconnect_timeout_ms_ = reconnect_timeout_ms; 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto_reconnect_enabled_ = true; 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Client::DisableAutoReconnect() { auto_reconnect_enabled_ = false; } 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Client::IsConnected() const { return channel_.get() != nullptr; } 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Client::CheckReconnect() { 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<void> ret; 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool was_disconnected = !IsConnected(); 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (auto_reconnect_enabled_ && was_disconnected && channel_factory_) { 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = channel_factory_->Connect(reconnect_timeout_ms_); 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko error_ = -status.error(); 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret.SetError(status.error()); 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ret; 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_ = status.take(); 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!IsConnected()) { 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret.SetError(ESHUTDOWN); 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Call the subclass OnConnect handler. The subclass may choose to close the 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // connection in the handler, in which case error_ will be non-zero. 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (was_disconnected) 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko OnConnect(); 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!IsConnected()) 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret.SetError(-error_); 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret.SetValue(); 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ret; 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Client::NeedToDisconnectChannel(int error) const { 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return error == ESHUTDOWN && auto_reconnect_enabled_; 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Client::CheckDisconnect(int error) { 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (NeedToDisconnectChannel(error)) 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Close(error); 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClient::Client(std::unique_ptr<ClientChannel> channel) 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : channel_{std::move(channel)} {} 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoClient::Client(std::unique_ptr<ClientChannelFactory> channel_factory, 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t timeout_ms) 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : channel_factory_{std::move(channel_factory)} { 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = channel_factory_->Connect(timeout_ms); 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Client::Client: Failed to connect to service because: %s", 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko error_ = -status.error(); 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_ = status.take(); 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Client::IsInitialized() const { 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return IsConnected() || (channel_factory_ && auto_reconnect_enabled_); 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Client::OnConnect() {} 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Client::error() const { return error_; } 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Client::SendImpulse(int opcode) { 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko PDX_TRACE_NAME("Client::SendImpulse"); 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = CheckReconnect(); 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = channel_->SendImpulse(opcode, nullptr, 0); 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CheckDisconnect(status); 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Client::SendImpulse(int opcode, const void* buffer, 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t length) { 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko PDX_TRACE_NAME("Client::SendImpulse"); 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = CheckReconnect(); 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = channel_->SendImpulse(opcode, buffer, length); 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CheckDisconnect(status); 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Client::Close(int error) { 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_.reset(); 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Normalize error codes to negative integer space. 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko error_ = error <= 0 ? error : -error; 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Client::event_fd() const { 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return IsConnected() ? channel_->event_fd() : -1; 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoLocalChannelHandle& Client::GetChannelHandle() { 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return channel_->GetChannelHandle(); 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 122a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Caiconst LocalChannelHandle& Client::GetChannelHandle() const { 123a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai return channel_->GetChannelHandle(); 124a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai} 125a8049a284ecf3eafddbacf5230b0fefe85de8446Jiwen 'Steve' Cai 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////// Transaction implementation ////////////////////// 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTransaction::Transaction(Client& client) : client_{client} {} 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTransaction::~Transaction() { 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state_allocated_ && client_.GetChannel()) 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client_.GetChannel()->FreeTransactionState(state_); 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Transaction::EnsureStateAllocated() { 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!state_allocated_ && client_.GetChannel()) { 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_ = client_.GetChannel()->AllocateTransactionState(); 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_allocated_ = true; 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state_allocated_; 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Transaction::SendTransaction(int opcode, Status<void>* ret, 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, size_t send_count, 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *ret = client_.CheckReconnect(); 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!*ret) 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!EnsureStateAllocated()) { 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(ESHUTDOWN); 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = client_.GetChannel()->SendWithInt( 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_, opcode, send_vector, send_count, receive_vector, receive_count); 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) { 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetValue(); 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(status.error()); 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CheckDisconnect(status); 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Transaction::SendTransaction(int opcode, Status<int>* ret, 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, size_t send_count, 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = client_.CheckReconnect(); 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(status.error()); 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!EnsureStateAllocated()) { 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(ESHUTDOWN); 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *ret = client_.GetChannel()->SendWithInt( 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_, opcode, send_vector, send_count, receive_vector, receive_count); 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CheckDisconnect(*ret); 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Transaction::SendTransaction(int opcode, Status<LocalHandle>* ret, 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, size_t send_count, 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = client_.CheckReconnect(); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(status.error()); 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!EnsureStateAllocated()) { 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(ESHUTDOWN); 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *ret = client_.GetChannel()->SendWithFileHandle( 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_, opcode, send_vector, send_count, receive_vector, receive_count); 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CheckDisconnect(*ret); 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Transaction::SendTransaction(int opcode, Status<LocalChannelHandle>* ret, 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* send_vector, size_t send_count, 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const iovec* receive_vector, 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t receive_count) { 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = client_.CheckReconnect(); 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(status.error()); 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!EnsureStateAllocated()) { 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret->SetError(ESHUTDOWN); 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *ret = client_.GetChannel()->SendWithChannelHandle( 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_, opcode, send_vector, send_count, receive_vector, receive_count); 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CheckDisconnect(*ret); 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 230f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Transaction::PushFileHandle(const LocalHandle& handle) { 231f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (client_.CheckReconnect() && EnsureStateAllocated()) 232f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return client_.GetChannel()->PushFileHandle(state_, handle); 233f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ESHUTDOWN}; 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 236f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Transaction::PushFileHandle( 237f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const BorrowedHandle& handle) { 238f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (client_.CheckReconnect() && EnsureStateAllocated()) 239f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return client_.GetChannel()->PushFileHandle(state_, handle); 240f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ESHUTDOWN}; 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 243f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Transaction::PushFileHandle(const RemoteHandle& handle) { 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 247f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Transaction::PushChannelHandle( 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalChannelHandle& handle) { 249f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (client_.CheckReconnect() && EnsureStateAllocated()) 250f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return client_.GetChannel()->PushChannelHandle(state_, handle); 251f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ESHUTDOWN}; 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 254f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Transaction::PushChannelHandle( 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedChannelHandle& handle) { 256f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (client_.CheckReconnect() && EnsureStateAllocated()) 257f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return client_.GetChannel()->PushChannelHandle(state_, handle); 258f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ESHUTDOWN}; 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 261f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Transaction::PushChannelHandle( 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const RemoteChannelHandle& handle) { 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Transaction::GetFileHandle(FileReference ref, LocalHandle* handle) { 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return client_.CheckReconnect() && EnsureStateAllocated() && 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client_.GetChannel()->GetFileHandle(state_, ref, handle); 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Transaction::GetChannelHandle(ChannelReference ref, 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle* handle) { 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return client_.CheckReconnect() && EnsureStateAllocated() && 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client_.GetChannel()->GetChannelHandle(state_, ref, handle); 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Transaction::CheckDisconnect(int error) { 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (client_.NeedToDisconnectChannel(error)) { 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (state_allocated_) { 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (client_.GetChannel()) 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client_.GetChannel()->FreeTransactionState(state_); 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_ = nullptr; 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state_allocated_ = false; 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client_.Close(error); 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 291