diff --git a/modules/eventx/timeout_monitor.hpp b/modules/eventx/timeout_monitor.hpp index 86309e13cea0344954e783c0af846d298353a1a5..7359bf86988053e3c6205c5cbba5dee2832e2e83 100644 --- a/modules/eventx/timeout_monitor.hpp +++ b/modules/eventx/timeout_monitor.hpp @@ -57,6 +57,7 @@ class TimeoutMonitor { void setCallback(const Callback &cb) { cb_ = cb; } void add(const T &value); + void clear(); void cleanup(); diff --git a/modules/eventx/timeout_monitor_impl.hpp b/modules/eventx/timeout_monitor_impl.hpp index 74fd93dd51f0cee8f9789e03e818ca4909e608aa..0131c47da0a59eb120fb2076f2ff8bf06ad40d49 100644 --- a/modules/eventx/timeout_monitor_impl.hpp +++ b/modules/eventx/timeout_monitor_impl.hpp @@ -73,15 +73,31 @@ void TimeoutMonitor::add(const T &value) ++value_number_; } +template +void TimeoutMonitor::clear() +{ + if (value_number_ > 0) { + value_number_ = 0; + sp_timer_->disable(); + + PollItem *item = curr_item_; + do { + item->items.clear(); + item = item->next; + } while (item != curr_item_); + } +} + template void TimeoutMonitor::cleanup() { if (curr_item_ == nullptr) return; - if (value_number_ > 0) + if (value_number_ > 0) { sp_timer_->disable(); - value_number_ = 0; + value_number_ = 0; + } PollItem *item = curr_item_->next; curr_item_->next = nullptr; diff --git a/modules/eventx/timeout_monitor_test.cpp b/modules/eventx/timeout_monitor_test.cpp index 98ae83f9ee7fa7ce36a7989de2989a330f6970f9..8e4205b79aa49ac36aee79e93c2ac9b9707e40d6 100644 --- a/modules/eventx/timeout_monitor_test.cpp +++ b/modules/eventx/timeout_monitor_test.cpp @@ -55,6 +55,39 @@ TEST(TimeoutMonitor, Basic) EXPECT_TRUE(run); } +//! 测试中途clear()的操作,观察有没有被误触发 +TEST(TimeoutMonitor, Clear) +{ + auto sp_loop = Loop::New(); + auto sp_timer = sp_loop->newTimerEvent(); + SetScopeExitAction( + [=] { + delete sp_loop; + delete sp_timer; + } + ); + sp_timer->initialize(std::chrono::milliseconds(25), Event::Mode::kOneshot); + + TimeoutMonitor tm(sp_loop); + tm.initialize(milliseconds(10), 3); + + sp_timer->setCallback([&] { tm.clear(); }); + sp_timer->enable(); + + bool run = false; + tm.setCallback([&] (int value) { + run = true; + }); + + tm.add(100); + tm.add(101); + + sp_loop->exitLoop(milliseconds(120)); + sp_loop->runLoop(); + + EXPECT_FALSE(run); +} + } } } diff --git a/modules/jsonrpc/proto.h b/modules/jsonrpc/proto.h index df079126df4cd1f0f9e897189b6c54dbc4913ae9..118f6b259b60f4792d7e93644d6856772c2434dc 100644 --- a/modules/jsonrpc/proto.h +++ b/modules/jsonrpc/proto.h @@ -36,6 +36,8 @@ class Proto { using RecvRespondStrCallback = std::function; using SendDataCallback = std::function; + virtual ~Proto() {} + void setRecvCallback(RecvRequestIntCallback &&req_cb, RecvRespondIntCallback &&rsp_cb); void setRecvCallback(RecvRequestStrCallback &&req_cb, RecvRespondStrCallback &&rsp_cb); void setSendCallback(SendDataCallback &&cb); diff --git a/modules/jsonrpc/rpc.cpp b/modules/jsonrpc/rpc.cpp index 5a225bc26e8b7e236b50287c4a0c4742fd42f372..b5d5c6a46599fa5951bd34e62c339bfbd70927e9 100644 --- a/modules/jsonrpc/rpc.cpp +++ b/modules/jsonrpc/rpc.cpp @@ -199,6 +199,17 @@ void Rpc::setStrIdGenFunc(StrIdGenFunc &&func) } } +void Rpc::clear() +{ + int_id_alloc_ = 0; + request_callback_.clear(); + tobe_respond_.clear(); + request_timeout_.clear(); + respond_timeout_.clear(); + int_to_str_map_.clear(); + str_to_int_map_.clear(); +} + void Rpc::onRecvRequestInt(int int_id, const std::string &method, const Json &js_params) { RECORD_SCOPE(); diff --git a/modules/jsonrpc/rpc.h b/modules/jsonrpc/rpc.h index db764aa587d3ac670452ff39a6587c1edbd6a824..da6309f72c5a0cfd3d308bec855d95a1367adad3 100644 --- a/modules/jsonrpc/rpc.h +++ b/modules/jsonrpc/rpc.h @@ -89,6 +89,9 @@ class Rpc { //! 设置string id生成函数,默认为UUIDv4 void setStrIdGenFunc(StrIdGenFunc &&func); + //! 清除缓存数据,恢复到没有收发数据之前的状态 + void clear(); + protected: void onRecvRequestInt(int int_id, const std::string &method, const Json ¶ms); void onRecvRespondInt(int int_id, const Response &response); diff --git a/modules/jsonrpc/rpc_int_test.cpp b/modules/jsonrpc/rpc_int_test.cpp index 84dd94f542b2e9815e523d6628caf46c113429e8..b17636c51c09a1c00125ebbf29f0ca025e3676c2 100644 --- a/modules/jsonrpc/rpc_int_test.cpp +++ b/modules/jsonrpc/rpc_int_test.cpp @@ -205,5 +205,41 @@ TEST(RpcInt, RequestTimeout) { EXPECT_TRUE(is_method_cb_invoke); } +//! 发了一个请求,在回复之前被clear +TEST(RpcInt, Clear) { + auto loop = event::Loop::New(); + auto timer = loop->newTimerEvent(); + SetScopeExitAction( + [=] { + delete loop; + delete timer; + } + ); + + timer->initialize(std::chrono::milliseconds(50), event::Event::Mode::kOneshot); + + Rpc rpc(loop); + RawStreamProto proto; + rpc.initialize(&proto, 1); + + timer->setCallback([&] { rpc.clear(); }); + timer->enable(); + + bool is_method_cb_invoke = false; + loop->run( + [&] { + rpc.request("A", Json(), + [&] (const Response &r) { + is_method_cb_invoke = true; + } + ); + } + ); + loop->exitLoop(std::chrono::milliseconds(1001)); + loop->runLoop(); + + EXPECT_FALSE(is_method_cb_invoke); +} + } }