Loading system/gd/l2cap/internal/data_pipeline_manager.cc +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ void DataPipelineManager::AttachChannel(Cid cid, std::shared_ptr<ChannelImpl> ch void DataPipelineManager::DetachChannel(Cid cid) { ASSERT(sender_map_.find(cid) != sender_map_.end()); sender_map_.erase(cid); scheduler_->RemoveChannel(cid); scheduler_->SetChannelTxPriority(cid, false); } Loading system/gd/l2cap/internal/scheduler.h +5 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,11 @@ class Scheduler { */ virtual void SetChannelTxPriority(Cid cid, bool high_priority) {} /** * Called by data controller to indicate that a channel is closed and packets should be dropped */ virtual void RemoveChannel(Cid cid) {} virtual ~Scheduler() = default; }; Loading system/gd/l2cap/internal/scheduler_fifo.cc +13 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,19 @@ void Fifo::SetChannelTxPriority(Cid cid, bool high_priority) { } } void Fifo::RemoveChannel(Cid cid) { for (int i = 0; i < next_to_dequeue_and_num_packets.size(); i++) { auto& channel_id_and_number_packets = next_to_dequeue_and_num_packets.front(); if (channel_id_and_number_packets.second != cid) { next_to_dequeue_and_num_packets.push(channel_id_and_number_packets); } next_to_dequeue_and_num_packets.pop(); } if (next_to_dequeue_and_num_packets.empty() && link_queue_enqueue_registered_.exchange(false)) { link_queue_up_end_->UnregisterEnqueue(); } } // Invoked from some external Queue Reactable context std::unique_ptr<Fifo::UpperDequeue> Fifo::link_queue_enqueue_callback() { ASSERT(!next_to_dequeue_and_num_packets.empty()); Loading system/gd/l2cap/internal/scheduler_fifo.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ class Fifo : public Scheduler { ~Fifo(); void OnPacketsReady(Cid cid, int number_packets) override; void SetChannelTxPriority(Cid cid, bool high_priority) override; void RemoveChannel(Cid cid) override; private: DataPipelineManager* data_pipeline_manager_; Loading system/gd/l2cap/internal/scheduler_fifo_test.cc +23 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,29 @@ TEST_F(L2capSchedulerFifoTest, prioritize_channel) { enqueue_.enqueued.pop(); } TEST_F(L2capSchedulerFifoTest, remove_channel) { auto frame = BasicFrameBuilder::Create(1, CreateSdu({'a', 'b', 'c'})); data_controller_1_.next_packets.push(std::move(frame)); frame = BasicFrameBuilder::Create(2, CreateSdu({'d', 'e', 'f'})); data_controller_2_.next_packets.push(std::move(frame)); EXPECT_CALL(*mock_data_pipeline_manager_, GetDataController(1)).WillRepeatedly(Return(&data_controller_1_)); EXPECT_CALL(*mock_data_pipeline_manager_, GetDataController(2)).WillRepeatedly(Return(&data_controller_2_)); EXPECT_CALL(*mock_data_pipeline_manager_, OnPacketSent(2)); fifo_->OnPacketsReady(1, 1); fifo_->OnPacketsReady(2, 1); fifo_->RemoveChannel(1); enqueue_.run_enqueue(1); auto packet1 = std::move(enqueue_.enqueued.front()); auto packet_view = GetPacketView(std::move(packet1)); auto basic_frame_view = BasicFrameView::Create(packet_view); ASSERT_TRUE(basic_frame_view.IsValid()); ASSERT_EQ(basic_frame_view.GetChannelId(), 2); auto payload = basic_frame_view.GetPayload(); ASSERT_EQ(std::string(payload.begin(), payload.end()), "def"); enqueue_.enqueued.pop(); } } // namespace } // namespace internal } // namespace l2cap Loading Loading
system/gd/l2cap/internal/data_pipeline_manager.cc +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ void DataPipelineManager::AttachChannel(Cid cid, std::shared_ptr<ChannelImpl> ch void DataPipelineManager::DetachChannel(Cid cid) { ASSERT(sender_map_.find(cid) != sender_map_.end()); sender_map_.erase(cid); scheduler_->RemoveChannel(cid); scheduler_->SetChannelTxPriority(cid, false); } Loading
system/gd/l2cap/internal/scheduler.h +5 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,11 @@ class Scheduler { */ virtual void SetChannelTxPriority(Cid cid, bool high_priority) {} /** * Called by data controller to indicate that a channel is closed and packets should be dropped */ virtual void RemoveChannel(Cid cid) {} virtual ~Scheduler() = default; }; Loading
system/gd/l2cap/internal/scheduler_fifo.cc +13 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,19 @@ void Fifo::SetChannelTxPriority(Cid cid, bool high_priority) { } } void Fifo::RemoveChannel(Cid cid) { for (int i = 0; i < next_to_dequeue_and_num_packets.size(); i++) { auto& channel_id_and_number_packets = next_to_dequeue_and_num_packets.front(); if (channel_id_and_number_packets.second != cid) { next_to_dequeue_and_num_packets.push(channel_id_and_number_packets); } next_to_dequeue_and_num_packets.pop(); } if (next_to_dequeue_and_num_packets.empty() && link_queue_enqueue_registered_.exchange(false)) { link_queue_up_end_->UnregisterEnqueue(); } } // Invoked from some external Queue Reactable context std::unique_ptr<Fifo::UpperDequeue> Fifo::link_queue_enqueue_callback() { ASSERT(!next_to_dequeue_and_num_packets.empty()); Loading
system/gd/l2cap/internal/scheduler_fifo.h +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ class Fifo : public Scheduler { ~Fifo(); void OnPacketsReady(Cid cid, int number_packets) override; void SetChannelTxPriority(Cid cid, bool high_priority) override; void RemoveChannel(Cid cid) override; private: DataPipelineManager* data_pipeline_manager_; Loading
system/gd/l2cap/internal/scheduler_fifo_test.cc +23 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,29 @@ TEST_F(L2capSchedulerFifoTest, prioritize_channel) { enqueue_.enqueued.pop(); } TEST_F(L2capSchedulerFifoTest, remove_channel) { auto frame = BasicFrameBuilder::Create(1, CreateSdu({'a', 'b', 'c'})); data_controller_1_.next_packets.push(std::move(frame)); frame = BasicFrameBuilder::Create(2, CreateSdu({'d', 'e', 'f'})); data_controller_2_.next_packets.push(std::move(frame)); EXPECT_CALL(*mock_data_pipeline_manager_, GetDataController(1)).WillRepeatedly(Return(&data_controller_1_)); EXPECT_CALL(*mock_data_pipeline_manager_, GetDataController(2)).WillRepeatedly(Return(&data_controller_2_)); EXPECT_CALL(*mock_data_pipeline_manager_, OnPacketSent(2)); fifo_->OnPacketsReady(1, 1); fifo_->OnPacketsReady(2, 1); fifo_->RemoveChannel(1); enqueue_.run_enqueue(1); auto packet1 = std::move(enqueue_.enqueued.front()); auto packet_view = GetPacketView(std::move(packet1)); auto basic_frame_view = BasicFrameView::Create(packet_view); ASSERT_TRUE(basic_frame_view.IsValid()); ASSERT_EQ(basic_frame_view.GetChannelId(), 2); auto payload = basic_frame_view.GetPayload(); ASSERT_EQ(std::string(payload.begin(), payload.end()), "def"); enqueue_.enqueued.pop(); } } // namespace } // namespace internal } // namespace l2cap Loading