Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: chrome/browser/sync/notifier/communicator/auto_reconnect.cc

Issue 194065: Initial commit of sync engine code to browser/sync.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fixes to gtest include path, reverted syncapi. Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 "chrome/browser/sync/notifier/communicator/auto_reconnect.h"
6
7 #include "chrome/browser/sync/notifier/base/network_status_detector_task.h"
8 #include "chrome/browser/sync/notifier/base/time.h"
9 #include "chrome/browser/sync/notifier/base/timer.h"
10 #include "talk/base/common.h"
11
12 namespace notifier {
13 const int kResetReconnectInfoDelaySec = 2;
14
15 AutoReconnect::AutoReconnect(talk_base::Task* parent,
16 NetworkStatusDetectorTask* network_status)
17 : reconnect_interval_ns_(0),
18 reconnect_timer_(NULL),
19 delayed_reset_timer_(NULL),
20 parent_(parent),
21 is_idle_(false) {
22 SetupReconnectInterval();
23 if (network_status) {
24 network_status->SignalNetworkStateDetected.connect(
25 this, &AutoReconnect::OnNetworkStateDetected);
26 }
27 }
28
29 void AutoReconnect::OnNetworkStateDetected(bool was_alive, bool is_alive) {
30 if (is_retrying() && !was_alive && is_alive) {
31 // Reconnect in 1 to 9 seconds (vary the time a little to try to avoid
32 // spikey behavior on network hiccups).
33 StartReconnectTimerWithInterval((rand() % 9 + 1) * kSecsTo100ns);
34 }
35 }
36
37 int AutoReconnect::seconds_until() const {
38 if (!is_retrying() || !reconnect_timer_->get_timeout_time()) {
39 return 0;
40 }
41 int64 time_until_100ns =
42 reconnect_timer_->get_timeout_time() - GetCurrent100NSTime();
43 if (time_until_100ns < 0) {
44 return 0;
45 }
46
47 // Do a ceiling on the value (to avoid returning before its time)
48 return (time_until_100ns + kSecsTo100ns - 1) / kSecsTo100ns;
49 }
50
51 void AutoReconnect::StartReconnectTimer() {
52 StartReconnectTimerWithInterval(reconnect_interval_ns_);
53 }
54
55 void AutoReconnect::StartReconnectTimerWithInterval(time64 interval_ns) {
56 // Don't call StopReconnectTimer because we don't
57 // want other classes to detect that the intermediate state of
58 // the timer being stopped. (We're avoiding the call to SignalTimerStartStop
59 // while reconnect_timer_ is NULL.)
60 if (reconnect_timer_) {
61 reconnect_timer_->Abort();
62 reconnect_timer_ = NULL;
63 }
64 reconnect_timer_ = new Timer(parent_,
65 static_cast<int>(interval_ns / kSecsTo100ns),
66 false); // repeat
67 reconnect_timer_->SignalTimeout.connect(this,
68 &AutoReconnect::DoReconnect);
69 SignalTimerStartStop();
70 }
71
72 void AutoReconnect::DoReconnect() {
73 reconnect_timer_ = NULL;
74
75 // if timed out again, double autoreconnect time up to 30 minutes
76 reconnect_interval_ns_ *= 2;
77 if (reconnect_interval_ns_ > 30 * kMinsTo100ns) {
78 reconnect_interval_ns_ = 30 * kMinsTo100ns;
79 }
80 SignalStartConnection();
81 }
82
83 void AutoReconnect::StopReconnectTimer() {
84 if (reconnect_timer_) {
85 reconnect_timer_->Abort();
86 reconnect_timer_ = NULL;
87 SignalTimerStartStop();
88 }
89 }
90
91 void AutoReconnect::StopDelayedResetTimer() {
92 if (delayed_reset_timer_) {
93 delayed_reset_timer_->Abort();
94 delayed_reset_timer_ = NULL;
95 }
96 }
97
98 void AutoReconnect::ResetState() {
99 StopDelayedResetTimer();
100 StopReconnectTimer();
101 SetupReconnectInterval();
102 }
103
104 void AutoReconnect::SetupReconnectInterval() {
105 if (is_idle_) {
106 // If we were idle, start the timer over again (120 - 360 seconds).
107 reconnect_interval_ns_ = (rand() % 240 + 120) * kSecsTo100ns;
108 } else {
109 // If we weren't idle, try the connection 5 - 25 seconds later.
110 reconnect_interval_ns_ = (rand() % 20 + 5) * kSecsTo100ns;
111 }
112 }
113
114 void AutoReconnect::OnPowerSuspend(bool suspended) {
115 if (suspended) {
116 // When the computer comes back on, ensure that the reconnect
117 // happens quickly (5 - 25 seconds).
118 reconnect_interval_ns_ = (rand() % 20 + 5) * kSecsTo100ns;
119 }
120 }
121
122 void AutoReconnect::OnClientStateChange(Login::ConnectionState state) {
123 // On any state change, stop the reset timer.
124 StopDelayedResetTimer();
125 switch (state) {
126 case Login::STATE_RETRYING:
127 // do nothing
128 break;
129
130 case Login::STATE_CLOSED:
131 // When the user has been logged out and no auto-reconnect
132 // is happening, then the autoreconnect intervals should be
133 // reset.
134 ResetState();
135 break;
136
137 case Login::STATE_OPENING:
138 StopReconnectTimer();
139 break;
140
141 case Login::STATE_OPENED:
142 // Reset autoreconnect timeout sequence after being connected
143 // for a bit of time. This helps in the case that we are
144 // connecting briefly and then getting disconnect like when
145 // an account hits an abuse limit.
146 StopReconnectTimer();
147 delayed_reset_timer_ = new Timer(parent_,
148 kResetReconnectInfoDelaySec,
149 false); // repeat
150 delayed_reset_timer_->SignalTimeout.connect(this,
151 &AutoReconnect::ResetState);
152 break;
153 }
154 }
155 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698