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_
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
{
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) {
28 RequestQueue
<T
>::~RequestQueue() {}
31 T
* RequestQueue
<T
>::active_request() {
32 return active_request_
.get();
36 int RequestQueue
<T
>::active_request_failure_count() {
37 return active_backoff_entry_
->failure_count();
41 scoped_ptr
<T
> RequestQueue
<T
>::reset_active_request() {
42 active_backoff_entry_
.reset();
43 return active_request_
.Pass();
47 void RequestQueue
<T
>::ScheduleRequest(scoped_ptr
<T
> request
) {
48 PushImpl(request
.Pass(), scoped_ptr
<net::BackoffEntry
>(
49 new net::BackoffEntry(backoff_policy_
)));
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(),
63 bool RequestQueue
<T
>::empty() const {
64 return pending_requests_
.empty();
68 size_t RequestQueue
<T
>::size() const {
69 return pending_requests_
.size();
73 base::TimeTicks RequestQueue
<T
>::NextReleaseTime() const {
74 return pending_requests_
.front().backoff_entry
->GetReleaseTime();
78 void RequestQueue
<T
>::StartNextRequest() {
80 // Already running a request, assume this method will be called again when
81 // the request is done.
85 // No requests in the queue, so we're done.
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
93 timer_
.Start(FROM_HERE
, next_release
- now
,
94 base::Bind(&RequestQueue
<T
>::StartNextRequest
,
95 base::Unretained(this)));
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(),
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();
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());
128 typename RequestQueue
<T
>::iterator RequestQueue
<T
>::begin() {
129 return iterator(pending_requests_
.begin());
133 typename RequestQueue
<T
>::iterator RequestQueue
<T
>::end() {
134 return iterator(pending_requests_
.end());
138 void RequestQueue
<T
>::set_backoff_policy(
139 const net::BackoffEntry::Policy
* backoff_policy
) {
140 backoff_policy_
= backoff_policy
;
145 bool RequestQueue
<T
>::CompareRequests(
148 return a
.backoff_entry
->GetReleaseTime() >
149 b
.backoff_entry
->GetReleaseTime();
152 } // namespace extensions
154 #endif // CHROME_BROWSER_EXTENSIONS_UPDATER_REQUEST_QUEUE_IMPL_H_