| 1284 | } |
| 1285 | |
| 1286 | int Controller::HandleSocketFailed(bthread_id_t id, void* data, int error_code, |
| 1287 | const std::string& error_text) { |
| 1288 | Controller* cntl = static_cast<Controller*>(data); |
| 1289 | if (!cntl->is_used_by_rpc()) { |
| 1290 | // Cannot destroy the call_id before RPC otherwise an async RPC |
| 1291 | // using the controller cannot be joined and related resources may be |
| 1292 | // destroyed before done->Run() running in another bthread. |
| 1293 | // The error set will be detected in Channel::CallMethod and fail |
| 1294 | // the RPC. |
| 1295 | cntl->SetFailed(error_code, "Cancel call_id=%" PRId64 |
| 1296 | " before CallMethod()", id.value); |
| 1297 | return bthread_id_unlock(id); |
| 1298 | } |
| 1299 | const int saved_error = cntl->ErrorCode(); |
| 1300 | if (error_code == ERPCTIMEDOUT) { |
| 1301 | cntl->SetFailed(error_code, "Reached timeout=%" PRId64 "ms @%s", |
| 1302 | cntl->timeout_ms(), |
| 1303 | butil::endpoint2str(cntl->remote_side()).c_str()); |
| 1304 | } else if (error_code == EBACKUPREQUEST) { |
| 1305 | cntl->SetFailed(error_code, "Reached backup timeout=%" PRId64 "ms @%s", |
| 1306 | cntl->backup_request_ms(), |
| 1307 | butil::endpoint2str(cntl->remote_side()).c_str()); |
| 1308 | } else if (!error_text.empty()) { |
| 1309 | cntl->SetFailed(error_code, "%s", error_text.c_str()); |
| 1310 | } else { |
| 1311 | cntl->SetFailed(error_code, "%s @%s", berror(error_code), |
| 1312 | butil::endpoint2str(cntl->remote_side()).c_str()); |
| 1313 | } |
| 1314 | |
| 1315 | struct OnVersionedRPCReturnedArgs { |
| 1316 | bthread_id_t id; |
| 1317 | Controller* cntl; |
| 1318 | int error; |
| 1319 | }; |
| 1320 | auto func = [](void* p) -> void* { |
| 1321 | std::unique_ptr<OnVersionedRPCReturnedArgs> args(static_cast<OnVersionedRPCReturnedArgs*>(p)); |
| 1322 | CompletionInfo info = { args->id, false }; |
| 1323 | args->cntl->OnVersionedRPCReturned(info, true, args->error); |
| 1324 | return NULL; |
| 1325 | }; |
| 1326 | |
| 1327 | auto* args = new OnVersionedRPCReturnedArgs{ id, cntl, saved_error }; |
| 1328 | bthread_t tid; |
| 1329 | // RetryPolicy may block current bthread, so start a new bthread to run OnVersionedRPCReturned |
| 1330 | if (!cntl->_retry_policy || bthread_start_background(&tid, NULL, func, args) != 0) { |
| 1331 | func(args); |
| 1332 | } |
| 1333 | return 0; |
| 1334 | } |
| 1335 | |
| 1336 | CallId Controller::call_id() { |
| 1337 | butil::atomic<uint64_t>* target = |
nothing calls this directly
no test coverage detected