Index: content/renderer/scheduler/throttled_message_sender.h |
diff --git a/content/renderer/scheduler/throttled_message_sender.h b/content/renderer/scheduler/throttled_message_sender.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..14ed5b982b065a92f25adbcd02c593599978a72e |
--- /dev/null |
+++ b/content/renderer/scheduler/throttled_message_sender.h |
@@ -0,0 +1,74 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CONTENT_RENDERER_SCHEDULER_THROTTLED_MESSAGE_SENDER_H_ |
+#define CONTENT_RENDERER_SCHEDULER_THROTTLED_MESSAGE_SENDER_H_ |
+ |
+#include <deque> |
+ |
+#include "base/threading/thread_checker.h" |
+#include "base/time/time.h" |
+#include "base/timer/timer.h" |
+#include "content/common/content_export.h" |
+#include "ipc/ipc_sender.h" |
+ |
+namespace content { |
+ |
+class RendererScheduler; |
+ |
+// Utility class for throttling a stream of IPC messages targetted to a specific |
+// IPC sender. The throttling itself is very basic: |
+// * When there is no high-priority work on the main thread, as indicated by |
+// the RendererScheduler, throttling is disabled. |
+// * When >= N messages have been sent in a given time window, messages are |
+// queued. A timer periodically flushes a portion of the queued messages |
+// until all messages have been flushed. |
+// * If a sync IPC is received, all queued messages are flushed immediately. |
+// |
+// This simplistic approach is particularly useful for IPC types that can |
+// 1) be sent at a very high rate (multiple messages per frame) and |
+// 2) interrupt page responsiveness due to the induced work, particularly on |
+// the receiver's IO thread. |
+// Such is the case, for example, for ResourceHostMsg_RequestResource messages. |
+class CONTENT_EXPORT ThrottledMessageSender : public IPC::Sender { |
+ public: |
+ // |max_sent_messages_per_second| must be strictly positive. |
+ ThrottledMessageSender(IPC::Sender* proxied_sender, |
+ RendererScheduler* scheduler, |
+ int max_sent_messages_per_second); |
+ ~ThrottledMessageSender() override; |
+ |
+ // IPC::Sender implementation: |
+ bool Send(IPC::Message* msg) override; |
+ |
+ protected: |
+ // Virtual for testing. |
+ virtual base::TimeTicks Now() const; |
+ |
+ private: |
+ friend class ThrottledMessageSenderTest; |
+ |
+ void FlushAll(); |
+ void FlushThrottled(); |
+ bool SendViaProxiedSender(IPC::Message* msg); |
+ |
+ base::ThreadChecker thread_checker_; |
+ IPC::Sender* const proxied_sender_; |
+ RendererScheduler* const scheduler_; |
+ |
+ const int max_sent_messages_per_flush_; |
+ const base::TimeDelta flush_period_; |
+ base::TimeTicks last_sent_message_time_; |
+ int sent_messages_since_last_flush_; |
+ base::Timer flush_timer_; |
+ |
+ std::deque<IPC::Message*> throttled_messages_; |
+ bool is_sending_via_proxied_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ThrottledMessageSender); |
+}; |
+ |
+} // namespace content |
+ |
+#endif // CONTENT_RENDERER_SCHEDULER_THROTTLED_MESSAGE_SENDER_H_ |