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 |