void SubDone::Run() { Controller* main_cntl = NULL; const int rc = bthread_id_lock(_cid, (void**)&main_cntl); if (rc != 0) { // _cid must be valid because schan does not dtor before cancelling // all sub calls. LOG(ERROR) << "Fail to lock correlation_id=" << _cid.value << ": " << berror(rc); return; } // NOTE: Copying gettable-but-settable fields which are generally set // during the RPC to reflect details. main_cntl->_remote_side = _cntl._remote_side; // connection_type may be changed during CallMethod. main_cntl->set_connection_type(_cntl.connection_type()); Resource r; r.response = _cntl._response; r.sub_done = this; if (!_owner->PushFree(r)) { return; } const int saved_error = main_cntl->ErrorCode(); if (_cntl.Failed()) { if (_cntl.ErrorCode() == ENODATA || _cntl.ErrorCode() == EHOSTDOWN) { // LB could not find a server. Socket::SetFailed(_peer_id); // trigger HC. } main_cntl->SetFailed(_cntl._error_text); main_cntl->_error_code = _cntl._error_code; } else { if (_cntl._response != main_cntl->_response) { main_cntl->_response->GetReflection()->Swap( main_cntl->_response, _cntl._response); } } const Controller::CompletionInfo info = { _cid, true }; main_cntl->OnVersionedRPCReturned(info, false, saved_error); }
void Sender::Run() { _finished = true; if (_nfree != _nalloc) { const int saved_nalloc = _nalloc; int error = (_main_cntl->ErrorCode() == ERPCTIMEDOUT ? ERPCTIMEDOUT : ECANCELED); CallId ids[_nalloc]; for (int i = 0; i < _nalloc; ++i) { ids[i] = _alloc_resources[i].sub_done->_cntl.call_id(); } CallId cid = _main_cntl->call_id(); CHECK_EQ(0, bthread_id_unlock(cid)); for (int i = 0; i < saved_nalloc; ++i) { bthread_id_error(ids[i], error); } } else { Clear(); } }