调整了设备移除函数,现在不会异常崩溃了
This commit is contained in:
@@ -776,10 +776,12 @@ void ClientManager::remove_device(const std::string& device_id) {
|
||||
}
|
||||
|
||||
auto& ctx = it->second;
|
||||
it->second->shutdown = true;
|
||||
ctx->shutdown = true;
|
||||
|
||||
// 确保所有定时器都停止
|
||||
// 1. 先停止所有定时器,避免定时器回调干扰
|
||||
ctx->stop_timers();
|
||||
|
||||
// 2. 清空动作队列,防止新的操作被触发
|
||||
{
|
||||
std::lock_guard<std::mutex> state_lock(ctx->state_mutex_);
|
||||
std::queue<StateAction> empty;
|
||||
@@ -787,10 +789,37 @@ void ClientManager::remove_device(const std::string& device_id) {
|
||||
ctx->current_state_ = DeviceState::IDLE;
|
||||
}
|
||||
|
||||
// 关闭连接并移除
|
||||
it->second->close_handles();
|
||||
// 3. 关闭TCP客户端句柄(关键修改:确保只关闭一次且正确同步)
|
||||
if (!uv_is_closing((uv_handle_t*)&ctx->client)) {
|
||||
// 设置句柄数据为nullptr,避免关闭回调中访问已释放资源
|
||||
ctx->client.data = nullptr;
|
||||
uv_close((uv_handle_t*)&ctx->client, [](uv_handle_t* handle) {
|
||||
// 回调中不再操作ClientContext,因为可能已被释放
|
||||
std::cout << "TCP handle closed successfully\n";
|
||||
});
|
||||
}
|
||||
|
||||
// 4. 关闭定时器句柄(如果未关闭)
|
||||
if (!uv_is_closing((uv_handle_t*)&ctx->timer)) {
|
||||
ctx->timer.data = nullptr;
|
||||
uv_close((uv_handle_t*)&ctx->timer, nullptr);
|
||||
}
|
||||
if (!uv_is_closing((uv_handle_t*)&ctx->reconnect_timer)) {
|
||||
ctx->reconnect_timer.data = nullptr;
|
||||
uv_close((uv_handle_t*)&ctx->reconnect_timer, nullptr);
|
||||
}
|
||||
|
||||
// 5. 从管理器中移除设备(关键修改:延迟到事件循环处理完关闭操作后再释放)
|
||||
// 将智能指针转移到栈上,确保在本函数结束后才销毁
|
||||
auto ctx_ptr = std::move(it->second);
|
||||
clients_.erase(it);
|
||||
std::cout << "[Device " << device_id << "] Removed successfully\n";
|
||||
|
||||
std::cout << "[Device " << device_id << "] Removal process initiated\n";
|
||||
|
||||
// 6. 强制事件循环处理一次关闭操作(非阻塞)
|
||||
if (loop_) {
|
||||
uv_run(loop_, UV_RUN_NOWAIT);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientManager::stop_all() {
|
||||
|
||||
Reference in New Issue
Block a user