Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/renderer/scheduler/throttled_message_sender.h" | |
| 6 | |
| 7 #include "base/auto_reset.h" | |
| 8 #include "content/renderer/scheduler/renderer_scheduler.h" | |
| 9 #include "ipc/ipc_message.h" | |
| 10 | |
| 11 namespace content { | |
| 12 namespace { | |
| 13 | |
| 14 const int kReasonableFlushesPerSecond = 60; | |
|
picksi1
2015/01/13 11:24:44
Is this 60 related to the 60*4 in kMaxResourceMess
jdduke (slow)
2015/01/13 16:18:11
It's not really related, but I'll add a comment.
| |
| 15 | |
| 16 } // namespace | |
| 17 | |
| 18 ThrottledMessageSender::ThrottledMessageSender(IPC::Sender* proxied_sender, | |
| 19 RendererScheduler* scheduler, | |
| 20 int max_sent_messages_per_second) | |
| 21 : proxied_sender_(proxied_sender), | |
| 22 scheduler_(scheduler), | |
| 23 max_sent_messages_per_flush_( | |
| 24 std::max(1, | |
| 25 max_sent_messages_per_second / kReasonableFlushesPerSecond)), | |
| 26 flush_period_(base::TimeDelta::FromSecondsD( | |
| 27 1.f / | |
| 28 std::min(max_sent_messages_per_second, kReasonableFlushesPerSecond))), | |
| 29 sent_messages_since_last_flush_(0), | |
| 30 flush_timer_(FROM_HERE, | |
|
Sami
2015/01/13 14:47:35
I wonder if we should build some kind of use-idle-
rmcilroy
2015/01/13 15:24:37
I like this idea (if not the name... ;). How abou
jdduke (slow)
2015/01/13 16:18:11
All solid options, I'm open to whatever you all th
| |
| 31 flush_period_, | |
| 32 base::Bind(&ThrottledMessageSender::FlushThrottled, | |
| 33 base::Unretained(this)), | |
| 34 false /* is_repeating */), | |
| 35 is_sending_via_proxied_(false) { | |
| 36 DCHECK(proxied_sender); | |
| 37 DCHECK(scheduler); | |
| 38 DCHECK_GT(max_sent_messages_per_second, 0); | |
| 39 flush_timer_.SetTaskRunner(scheduler->DefaultTaskRunner()); | |
| 40 } | |
| 41 | |
| 42 ThrottledMessageSender::~ThrottledMessageSender() { | |
| 43 FlushAll(); | |
| 44 DCHECK(throttled_messages_.empty()); | |
| 45 } | |
| 46 | |
| 47 bool ThrottledMessageSender::Send(IPC::Message* msg) { | |
| 48 DCHECK(!is_sending_via_proxied_); | |
| 49 thread_checker_.CalledOnValidThread(); | |
| 50 | |
| 51 if (msg->is_sync()) { | |
| 52 FlushAll(); | |
| 53 return SendViaProxiedSender(msg); | |
| 54 } | |
| 55 | |
| 56 if (!throttled_messages_.empty()) { | |
| 57 throttled_messages_.push_back(msg); | |
|
picksi1
2015/01/13 11:24:44
cunning!
| |
| 58 return true; | |
| 59 } | |
| 60 | |
| 61 if (!scheduler_->ShouldYieldForHighPriorityWork()) | |
|
alex clarke (OOO till 29th)
2015/01/13 10:38:02
I think you'd get better results if the scheduler
Sami
2015/01/13 14:47:35
What advantage were you thinking of? This feels li
rmcilroy
2015/01/13 15:24:37
I agree with Sami here - I think this shouldn't be
alex clarke (OOO till 29th)
2015/01/13 15:46:55
As far as I understand it, the intent here is to t
jdduke (slow)
2015/01/13 16:18:11
I agree with Alex here, and was actually going to
| |
| 62 return SendViaProxiedSender(msg); | |
| 63 | |
| 64 if (Now() > (last_sent_message_time_ + flush_period_)) { | |
| 65 // If sufficient time has passed since the previous send, we can effectively | |
| 66 // mark the pipeline as flushed. | |
| 67 sent_messages_since_last_flush_ = 0; | |
| 68 return SendViaProxiedSender(msg); | |
| 69 } | |
| 70 | |
| 71 if (sent_messages_since_last_flush_ < max_sent_messages_per_flush_) | |
| 72 return SendViaProxiedSender(msg); | |
| 73 | |
| 74 throttled_messages_.push_back(msg); | |
| 75 DCHECK(!flush_timer_.IsRunning()); | |
| 76 flush_timer_.Reset(); | |
| 77 return true; | |
| 78 } | |
| 79 | |
| 80 base::TimeTicks ThrottledMessageSender::Now() const { | |
| 81 return base::TimeTicks::Now(); | |
| 82 } | |
| 83 | |
| 84 void ThrottledMessageSender::FlushAll() { | |
| 85 sent_messages_since_last_flush_ = 0; | |
|
picksi1
2015/01/13 11:24:44
Can you confirm that there are no threading issues
jdduke (slow)
2015/01/13 16:18:11
Yeah, I've got the |DCHECK(!is_sending_via_proxied
| |
| 86 flush_timer_.Stop(); | |
| 87 | |
| 88 for (auto& msg : throttled_messages_) | |
| 89 SendViaProxiedSender(msg); | |
| 90 throttled_messages_.clear(); | |
| 91 } | |
| 92 | |
| 93 void ThrottledMessageSender::FlushThrottled() { | |
| 94 sent_messages_since_last_flush_ = 0; | |
| 95 | |
| 96 while (!throttled_messages_.empty() && | |
|
picksi1
2015/01/13 11:24:44
Suggestion for discussion: Rather than checking fo
jdduke (slow)
2015/01/13 16:18:11
That's a solid option, though it would prevent the
| |
| 97 sent_messages_since_last_flush_ < max_sent_messages_per_flush_) { | |
| 98 IPC::Message* msg = throttled_messages_.front(); | |
| 99 throttled_messages_.pop_front(); | |
| 100 SendViaProxiedSender(msg); | |
|
Sami
2015/01/13 14:47:35
Should we yield here too (after sending at least o
jdduke (slow)
2015/01/13 16:18:11
Hmm, the |Send| itself should be fairly cheap (max
| |
| 101 } | |
| 102 | |
| 103 if (!throttled_messages_.empty()) | |
| 104 flush_timer_.Reset(); | |
| 105 } | |
| 106 | |
| 107 bool ThrottledMessageSender::SendViaProxiedSender(IPC::Message* msg) { | |
| 108 DCHECK(!is_sending_via_proxied_); | |
| 109 base::AutoReset<bool> is_sending_via_proxied_resetter( | |
| 110 &is_sending_via_proxied_, true); | |
| 111 last_sent_message_time_ = Now(); | |
| 112 ++sent_messages_since_last_flush_; | |
| 113 return proxied_sender_->Send(msg); | |
| 114 } | |
| 115 | |
| 116 } // namespace content | |
| OLD | NEW |