Temporarily re-enabling SizeAfterPrefChange test with traces (this time for Linux...
[chromium-blink-merge.git] / chrome / browser / extensions / updater / request_queue_impl.h
blobdb167e83cd6d92208bde684db451439628ddb715
1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_REQUEST_QUEUE_IMPL_H_
6 #define CHROME_BROWSER_EXTENSIONS_UPDATER_REQUEST_QUEUE_IMPL_H_
8 #include <algorithm>
10 #include "base/bind.h"
11 #include "base/compiler_specific.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/stl_util.h"
14 #include "chrome/browser/extensions/updater/request_queue.h"
16 namespace extensions {
18 template<typename T>
19 RequestQueue<T>::RequestQueue(
20 const net::BackoffEntry::Policy* const backoff_policy,
21 const base::Closure& start_request_callback)
22 : backoff_policy_(backoff_policy),
23 start_request_callback_(start_request_callback),
24 timer_(false, false) {
27 template<typename T>
28 RequestQueue<T>::~RequestQueue() {}
30 template<typename T>
31 T* RequestQueue<T>::active_request() {
32 return active_request_.get();
35 template<typename T>
36 int RequestQueue<T>::active_request_failure_count() {
37 return active_backoff_entry_->failure_count();
40 template<typename T>
41 scoped_ptr<T> RequestQueue<T>::reset_active_request() {
42 active_backoff_entry_.reset();
43 return active_request_.Pass();
46 template<typename T>
47 void RequestQueue<T>::ScheduleRequest(scoped_ptr<T> request) {
48 PushImpl(request.Pass(), scoped_ptr<net::BackoffEntry>(
49 new net::BackoffEntry(backoff_policy_)));
50 StartNextRequest();
53 template<typename T>
54 void RequestQueue<T>::PushImpl(scoped_ptr<T> request,
55 scoped_ptr<net::BackoffEntry> backoff_entry) {
56 pending_requests_.push_back(Request(
57 backoff_entry.release(), request.release()));
58 std::push_heap(pending_requests_.begin(), pending_requests_.end(),
59 CompareRequests);
62 template<typename T>
63 bool RequestQueue<T>::empty() const {
64 return pending_requests_.empty();
67 template<typename T>
68 size_t RequestQueue<T>::size() const {
69 return pending_requests_.size();
72 template<typename T>
73 base::TimeTicks RequestQueue<T>::NextReleaseTime() const {
74 return pending_requests_.front().backoff_entry->GetReleaseTime();
77 template<typename T>
78 void RequestQueue<T>::StartNextRequest() {
79 if (active_request_)
80 // Already running a request, assume this method will be called again when
81 // the request is done.
82 return;
84 if (empty())
85 // No requests in the queue, so we're done.
86 return;
88 base::TimeTicks next_release = NextReleaseTime();
89 base::TimeTicks now = base::TimeTicks::Now();
90 if (next_release > now) {
91 // Not ready for the next update check yet, call this method when it is
92 // time.
93 timer_.Start(FROM_HERE, next_release - now,
94 base::Bind(&RequestQueue<T>::StartNextRequest,
95 base::Unretained(this)));
96 return;
99 // pop_heap swaps the first and last elements of pending_requests_, and after
100 // that assures that the rest of pending_requests_ (excluding the
101 // now last/formerly first element) forms a proper heap. After pop_heap
102 // [begin, end-1) is a valid heap, and *(end - 1) contains the element that
103 // used to be at the top of the heap. Since no elements are actually
104 // removed from the container it is safe to read the entry being removed after
105 // pop_heap is called (but before pop_back is called).
106 std::pop_heap(pending_requests_.begin(), pending_requests_.end(),
107 CompareRequests);
109 active_backoff_entry_.reset(pending_requests_.back().backoff_entry.release());
110 active_request_.reset(pending_requests_.back().request.release());
112 pending_requests_.pop_back();
114 start_request_callback_.Run();
117 template<typename T>
118 void RequestQueue<T>::RetryRequest(const base::TimeDelta& min_backoff_delay) {
119 active_backoff_entry_->InformOfRequest(false);
120 if (active_backoff_entry_->GetTimeUntilRelease() < min_backoff_delay) {
121 active_backoff_entry_->SetCustomReleaseTime(
122 base::TimeTicks::Now() + min_backoff_delay);
124 PushImpl(active_request_.Pass(), active_backoff_entry_.Pass());
127 template<typename T>
128 typename RequestQueue<T>::iterator RequestQueue<T>::begin() {
129 return iterator(pending_requests_.begin());
132 template<typename T>
133 typename RequestQueue<T>::iterator RequestQueue<T>::end() {
134 return iterator(pending_requests_.end());
137 template<typename T>
138 void RequestQueue<T>::set_backoff_policy(
139 const net::BackoffEntry::Policy* backoff_policy) {
140 backoff_policy_ = backoff_policy;
143 // static
144 template<typename T>
145 bool RequestQueue<T>::CompareRequests(
146 const Request& a,
147 const Request& b) {
148 return a.backoff_entry->GetReleaseTime() >
149 b.backoff_entry->GetReleaseTime();
152 } // namespace extensions
154 #endif // CHROME_BROWSER_EXTENSIONS_UPDATER_REQUEST_QUEUE_IMPL_H_