Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / extensions / browser / updater / request_queue_impl.h
blob309dc824362f1ffdf28292ebba5d36899815129b
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 EXTENSIONS_BROWSER_UPDATER_REQUEST_QUEUE_IMPL_H_
6 #define EXTENSIONS_BROWSER_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 "extensions/browser/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() {
31 template <typename T>
32 T* RequestQueue<T>::active_request() {
33 return active_request_.get();
36 template <typename T>
37 int RequestQueue<T>::active_request_failure_count() {
38 return active_backoff_entry_->failure_count();
41 template <typename T>
42 scoped_ptr<T> RequestQueue<T>::reset_active_request() {
43 active_backoff_entry_.reset();
44 return active_request_.Pass();
47 template <typename T>
48 void RequestQueue<T>::ScheduleRequest(scoped_ptr<T> request) {
49 PushImpl(
50 request.Pass(),
51 scoped_ptr<net::BackoffEntry>(new net::BackoffEntry(backoff_policy_)));
52 StartNextRequest();
55 template <typename T>
56 void RequestQueue<T>::PushImpl(scoped_ptr<T> request,
57 scoped_ptr<net::BackoffEntry> backoff_entry) {
58 pending_requests_.push_back(
59 Request(backoff_entry.release(), request.release()));
60 std::push_heap(
61 pending_requests_.begin(), pending_requests_.end(), CompareRequests);
64 template <typename T>
65 bool RequestQueue<T>::empty() const {
66 return pending_requests_.empty();
69 template <typename T>
70 size_t RequestQueue<T>::size() const {
71 return pending_requests_.size();
74 template <typename T>
75 base::TimeTicks RequestQueue<T>::NextReleaseTime() const {
76 return pending_requests_.front().backoff_entry->GetReleaseTime();
79 template <typename T>
80 void RequestQueue<T>::StartNextRequest() {
81 if (active_request_)
82 // Already running a request, assume this method will be called again when
83 // the request is done.
84 return;
86 if (empty())
87 // No requests in the queue, so we're done.
88 return;
90 base::TimeTicks next_release = NextReleaseTime();
91 base::TimeTicks now = base::TimeTicks::Now();
92 if (next_release > now) {
93 // Not ready for the next update check yet, call this method when it is
94 // time.
95 timer_.Start(
96 FROM_HERE,
97 next_release - now,
98 base::Bind(&RequestQueue<T>::StartNextRequest, base::Unretained(this)));
99 return;
102 // pop_heap swaps the first and last elements of pending_requests_, and after
103 // that assures that the rest of pending_requests_ (excluding the
104 // now last/formerly first element) forms a proper heap. After pop_heap
105 // [begin, end-1) is a valid heap, and *(end - 1) contains the element that
106 // used to be at the top of the heap. Since no elements are actually
107 // removed from the container it is safe to read the entry being removed after
108 // pop_heap is called (but before pop_back is called).
109 std::pop_heap(
110 pending_requests_.begin(), pending_requests_.end(), CompareRequests);
112 active_backoff_entry_.reset(pending_requests_.back().backoff_entry.release());
113 active_request_.reset(pending_requests_.back().request.release());
115 pending_requests_.pop_back();
117 start_request_callback_.Run();
120 template <typename T>
121 void RequestQueue<T>::RetryRequest(const base::TimeDelta& min_backoff_delay) {
122 active_backoff_entry_->InformOfRequest(false);
123 if (active_backoff_entry_->GetTimeUntilRelease() < min_backoff_delay) {
124 active_backoff_entry_->SetCustomReleaseTime(base::TimeTicks::Now() +
125 min_backoff_delay);
127 PushImpl(active_request_.Pass(), active_backoff_entry_.Pass());
130 template <typename T>
131 typename RequestQueue<T>::iterator RequestQueue<T>::begin() {
132 return iterator(pending_requests_.begin());
135 template <typename T>
136 typename RequestQueue<T>::iterator RequestQueue<T>::end() {
137 return iterator(pending_requests_.end());
140 template <typename T>
141 void RequestQueue<T>::set_backoff_policy(
142 const net::BackoffEntry::Policy* backoff_policy) {
143 backoff_policy_ = backoff_policy;
146 // static
147 template <typename T>
148 bool RequestQueue<T>::CompareRequests(const Request& a, const Request& b) {
149 return a.backoff_entry->GetReleaseTime() > b.backoff_entry->GetReleaseTime();
152 } // namespace extensions
154 #endif // EXTENSIONS_BROWSER_UPDATER_REQUEST_QUEUE_IMPL_H_