| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include "chrome/browser/sync/engine/syncer_thread.h" | 4 #include "chrome/browser/sync/engine/syncer_thread.h" |
| 5 | 5 |
| 6 #include "build/build_config.h" | 6 #include "build/build_config.h" |
| 7 | 7 |
| 8 #if defined(OS_MACOSX) | 8 #if defined(OS_MACOSX) |
| 9 #include <CoreFoundation/CFNumber.h> | 9 #include <CoreFoundation/CFNumber.h> |
| 10 #include <IOKit/IOTypes.h> | 10 #include <IOKit/IOTypes.h> |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 // actually up and running. This is for consistency with the old pthread | 121 // actually up and running. This is for consistency with the old pthread |
| 122 // impl because pthread_create would do this in one step. | 122 // impl because pthread_create would do this in one step. |
| 123 thread_main_started_.Wait(); | 123 thread_main_started_.Wait(); |
| 124 LOG(INFO) << "SyncerThread started."; | 124 LOG(INFO) << "SyncerThread started."; |
| 125 return true; | 125 return true; |
| 126 } | 126 } |
| 127 | 127 |
| 128 // Stop processing. A max wait of at least 2*server RTT time is recommended. | 128 // Stop processing. A max wait of at least 2*server RTT time is recommended. |
| 129 // Returns true if we stopped, false otherwise. | 129 // Returns true if we stopped, false otherwise. |
| 130 bool SyncerThread::Stop(int max_wait) { | 130 bool SyncerThread::Stop(int max_wait) { |
| 131 RequestSyncerExitAndSetThreadStopConditions(); |
| 132 |
| 133 // This will join, and finish when ThreadMain terminates. |
| 134 thread_.Stop(); |
| 135 return true; |
| 136 } |
| 137 |
| 138 void SyncerThread::RequestSyncerExitAndSetThreadStopConditions() { |
| 131 { | 139 { |
| 132 AutoLock lock(lock_); | 140 AutoLock lock(lock_); |
| 133 // If the thread has been started, then we either already have or are about | 141 // If the thread has been started, then we either already have or are about |
| 134 // to enter ThreadMainLoop so we have to proceed with shutdown and wait for | 142 // to enter ThreadMainLoop so we have to proceed with shutdown and wait for |
| 135 // it to finish. If the thread has not been started --and we now own the | 143 // it to finish. If the thread has not been started --and we now own the |
| 136 // lock-- then we can early out because the caller has not called Start(). | 144 // lock-- then we can early out because the caller has not called Start(). |
| 137 if (!thread_.IsRunning()) | 145 if (!thread_.IsRunning()) |
| 138 return true; | 146 return; |
| 139 | 147 |
| 140 LOG(INFO) << "SyncerThread::Stop - setting ThreadMain exit condition to " | 148 LOG(INFO) << "SyncerThread::Stop - setting ThreadMain exit condition to " |
| 141 << "true (vault_.stop_syncer_thread_)"; | 149 << "true (vault_.stop_syncer_thread_)"; |
| 142 // Exit the ThreadMainLoop once the syncer finishes (we tell it to exit | 150 // Exit the ThreadMainLoop once the syncer finishes (we tell it to exit |
| 143 // below). | 151 // below). |
| 144 vault_.stop_syncer_thread_ = true; | 152 vault_.stop_syncer_thread_ = true; |
| 145 if (NULL != vault_.syncer_) { | 153 if (NULL != vault_.syncer_) { |
| 146 // Try to early exit the syncer itself, which could be looping inside | 154 // Try to early exit the syncer itself, which could be looping inside |
| 147 // SyncShare. | 155 // SyncShare. |
| 148 vault_.syncer_->RequestEarlyExit(); | 156 vault_.syncer_->RequestEarlyExit(); |
| 149 } | 157 } |
| 150 | 158 |
| 151 // stop_syncer_thread_ is now true and the Syncer has been told to exit. | 159 // stop_syncer_thread_ is now true and the Syncer has been told to exit. |
| 152 // We want to wake up all waiters so they can re-examine state. We signal, | 160 // We want to wake up all waiters so they can re-examine state. We signal, |
| 153 // causing all waiters to try to re-acquire the lock, and then we release | 161 // causing all waiters to try to re-acquire the lock, and then we release |
| 154 // the lock, and join on our internal thread which should soon run off the | 162 // the lock, and join on our internal thread which should soon run off the |
| 155 // end of ThreadMain. | 163 // end of ThreadMain. |
| 156 vault_field_changed_.Broadcast(); | 164 vault_field_changed_.Broadcast(); |
| 157 } | 165 } |
| 158 | |
| 159 // This will join, and finish when ThreadMain terminates. | |
| 160 thread_.Stop(); | |
| 161 return true; | |
| 162 } | 166 } |
| 163 | 167 |
| 164 bool SyncerThread::RequestPause() { | 168 bool SyncerThread::RequestPause() { |
| 165 AutoLock lock(lock_); | 169 AutoLock lock(lock_); |
| 166 if (vault_.pause_requested_ || vault_.paused_) | 170 if (vault_.pause_requested_ || vault_.paused_) |
| 167 return false; | 171 return false; |
| 168 | 172 |
| 169 if (thread_.IsRunning()) { | 173 if (thread_.IsRunning()) { |
| 170 // Set the pause request. The syncer thread will read this | 174 // Set the pause request. The syncer thread will read this |
| 171 // request, enter the paused state, and send the PAUSED | 175 // request, enter the paused state, and send the PAUSED |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 | 230 |
| 227 bool SyncerThread::IsSyncingCurrentlySilenced() { | 231 bool SyncerThread::IsSyncingCurrentlySilenced() { |
| 228 // We should ignore reads from silenced_until_ under ThreadSanitizer | 232 // We should ignore reads from silenced_until_ under ThreadSanitizer |
| 229 // since this is a benign race. | 233 // since this is a benign race. |
| 230 ANNOTATE_IGNORE_READS_BEGIN(); | 234 ANNOTATE_IGNORE_READS_BEGIN(); |
| 231 bool ret = (silenced_until_ - TimeTicks::Now()) >= TimeDelta::FromSeconds(0); | 235 bool ret = (silenced_until_ - TimeTicks::Now()) >= TimeDelta::FromSeconds(0); |
| 232 ANNOTATE_IGNORE_READS_END(); | 236 ANNOTATE_IGNORE_READS_END(); |
| 233 return ret; | 237 return ret; |
| 234 } | 238 } |
| 235 | 239 |
| 240 void SyncerThread::OnShouldStopSyncingPermanently() { |
| 241 RequestSyncerExitAndSetThreadStopConditions(); |
| 242 |
| 243 SyncerEvent event(SyncerEvent::STOP_SYNCING_PERMANENTLY); |
| 244 relay_channel()->Notify(event); |
| 245 } |
| 246 |
| 236 void SyncerThread::ThreadMainLoop() { | 247 void SyncerThread::ThreadMainLoop() { |
| 237 // This is called with lock_ acquired. | 248 // This is called with lock_ acquired. |
| 238 lock_.AssertAcquired(); | 249 lock_.AssertAcquired(); |
| 239 LOG(INFO) << "In thread main loop."; | 250 LOG(INFO) << "In thread main loop."; |
| 240 | 251 |
| 241 // Use the short poll value by default. | 252 // Use the short poll value by default. |
| 242 vault_.current_wait_interval_.poll_delta = | 253 vault_.current_wait_interval_.poll_delta = |
| 243 TimeDelta::FromSeconds(syncer_short_poll_interval_seconds_); | 254 TimeDelta::FromSeconds(syncer_short_poll_interval_seconds_); |
| 244 int user_idle_milliseconds = 0; | 255 int user_idle_milliseconds = 0; |
| 245 TimeTicks last_sync_time; | 256 TimeTicks last_sync_time; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 vault_field_changed_.Wait(); | 390 vault_field_changed_.Wait(); |
| 380 | 391 |
| 381 // Notify that we have resumed if we are not shutting down. | 392 // Notify that we have resumed if we are not shutting down. |
| 382 if (!vault_.stop_syncer_thread_) | 393 if (!vault_.stop_syncer_thread_) |
| 383 ExitPausedState(); | 394 ExitPausedState(); |
| 384 | 395 |
| 385 LOG(INFO) << "Syncer thread exiting pause."; | 396 LOG(INFO) << "Syncer thread exiting pause."; |
| 386 } | 397 } |
| 387 | 398 |
| 388 void SyncerThread::EnterPausedState() { | 399 void SyncerThread::EnterPausedState() { |
| 400 lock_.AssertAcquired(); |
| 389 vault_.pause_requested_ = false; | 401 vault_.pause_requested_ = false; |
| 390 vault_.paused_ = true; | 402 vault_.paused_ = true; |
| 403 vault_field_changed_.Broadcast(); |
| 391 SyncerEvent event(SyncerEvent::PAUSED); | 404 SyncerEvent event(SyncerEvent::PAUSED); |
| 392 relay_channel()->Notify(event); | 405 relay_channel()->Notify(event); |
| 393 } | 406 } |
| 394 | 407 |
| 395 void SyncerThread::ExitPausedState() { | 408 void SyncerThread::ExitPausedState() { |
| 409 lock_.AssertAcquired(); |
| 396 vault_.paused_ = false; | 410 vault_.paused_ = false; |
| 411 vault_field_changed_.Broadcast(); |
| 397 SyncerEvent event(SyncerEvent::RESUMED); | 412 SyncerEvent event(SyncerEvent::RESUMED); |
| 398 relay_channel()->Notify(event); | 413 relay_channel()->Notify(event); |
| 399 } | 414 } |
| 400 | 415 |
| 401 // We check how long the user's been idle and sync less often if the machine is | 416 // We check how long the user's been idle and sync less often if the machine is |
| 402 // not in use. The aim is to reduce server load. | 417 // not in use. The aim is to reduce server load. |
| 403 // TODO(timsteele): Should use Time(Delta). | 418 // TODO(timsteele): Should use Time(Delta). |
| 404 SyncerThread::WaitInterval SyncerThread::CalculatePollingWaitTime( | 419 SyncerThread::WaitInterval SyncerThread::CalculatePollingWaitTime( |
| 405 const AllStatus::Status& status, | 420 const AllStatus::Status& status, |
| 406 int last_poll_wait, // Time in seconds. | 421 int last_poll_wait, // Time in seconds. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 return return_interval; | 496 return return_interval; |
| 482 } | 497 } |
| 483 | 498 |
| 484 void SyncerThread::ThreadMain() { | 499 void SyncerThread::ThreadMain() { |
| 485 AutoLock lock(lock_); | 500 AutoLock lock(lock_); |
| 486 // Signal Start() to let it know we've made it safely onto the message loop, | 501 // Signal Start() to let it know we've made it safely onto the message loop, |
| 487 // and unblock it's caller. | 502 // and unblock it's caller. |
| 488 thread_main_started_.Signal(); | 503 thread_main_started_.Signal(); |
| 489 ThreadMainLoop(); | 504 ThreadMainLoop(); |
| 490 LOG(INFO) << "Syncer thread ThreadMain is done."; | 505 LOG(INFO) << "Syncer thread ThreadMain is done."; |
| 506 SyncerEvent event(SyncerEvent::SYNCER_THREAD_EXITING); |
| 507 relay_channel()->Notify(event); |
| 491 } | 508 } |
| 492 | 509 |
| 493 void SyncerThread::SyncMain(Syncer* syncer) { | 510 void SyncerThread::SyncMain(Syncer* syncer) { |
| 494 CHECK(syncer); | 511 CHECK(syncer); |
| 495 | 512 |
| 496 // Since we are initiating a new session for which we are the delegate, we | 513 // Since we are initiating a new session for which we are the delegate, we |
| 497 // are not currently silenced so reset this state for the next session which | 514 // are not currently silenced so reset this state for the next session which |
| 498 // may need to use it. | 515 // may need to use it. |
| 499 silenced_until_ = base::TimeTicks(); | 516 silenced_until_ = base::TimeTicks(); |
| 500 | 517 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 was_logged = true; | 767 was_logged = true; |
| 751 LOG(INFO) << "UserIdleTime unimplemented on this platform, " | 768 LOG(INFO) << "UserIdleTime unimplemented on this platform, " |
| 752 "synchronization will not throttle when user idle"; | 769 "synchronization will not throttle when user idle"; |
| 753 } | 770 } |
| 754 #endif | 771 #endif |
| 755 | 772 |
| 756 return 0; | 773 return 0; |
| 757 } | 774 } |
| 758 | 775 |
| 759 } // namespace browser_sync | 776 } // namespace browser_sync |
| OLD | NEW |