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

Unified Diff: chrome/browser/browser_process_impl.cc

Issue 378863003: Revert of Fix Windows logoff race. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/lifetime/application_lifetime.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/browser_process_impl.cc
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index e014c1803ea454929ce339613e4ed93614a111b5..a36ac9fa8ed0e36a3cdbc28cb6ed078173008095 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -8,7 +8,6 @@
#include <map>
#include <vector>
-#include "base/atomic_ref_count.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
@@ -316,6 +315,12 @@
io_thread_.reset();
}
+#if defined(USE_X11) || defined(OS_WIN)
+static void Signal(base::WaitableEvent* event) {
+ event->Signal();
+}
+#endif
+
unsigned int BrowserProcessImpl::AddRefModule() {
DCHECK(CalledOnValidThread());
@@ -379,81 +384,12 @@
return module_ref_count_;
}
-namespace {
-
-// Used at the end of session to block the UI thread for completion of sentinel
-// tasks on the set of threads used to persist profile data and local state.
-// This is done to ensure that the data has been persisted to disk before
-// continuing.
-class RundownTaskCounter :
- public base::RefCountedThreadSafe<RundownTaskCounter> {
- public:
- RundownTaskCounter();
-
- // Posts a rundown task to |task_runner|, can be invoked an arbitrary number
- // of times before calling TimedWait.
- void Post(base::SequencedTaskRunner* task_runner);
-
- // Waits until the count is zero or |max_time| has passed.
- // This can only be called once per instance.
- bool TimedWait(const base::TimeDelta& max_time);
-
- private:
- friend class base::RefCountedThreadSafe<RundownTaskCounter>;
- ~RundownTaskCounter() {}
-
- // Decrements the counter and releases the waitable event on transition to
- // zero.
- void Decrement();
-
- // The count starts at one to defer the possibility of one->zero transitions
- // until TimedWait is called.
- base::AtomicRefCount count_;
- base::WaitableEvent waitable_event_;
-
- DISALLOW_COPY_AND_ASSIGN(RundownTaskCounter);
-};
-
-RundownTaskCounter::RundownTaskCounter()
- : count_(1), waitable_event_(true, false) {
-}
-
-void RundownTaskCounter::Post(base::SequencedTaskRunner* task_runner) {
- // As the count starts off at one, it should never get to zero unless
- // TimedWait has been called.
- DCHECK(!base::AtomicRefCountIsZero(&count_));
-
- base::AtomicRefCountInc(&count_);
-
- task_runner->PostTask(FROM_HERE,
- base::Bind(&RundownTaskCounter::Decrement, this));
-}
-
-void RundownTaskCounter::Decrement() {
- if (!base::AtomicRefCountDec(&count_))
- waitable_event_.Signal();
-}
-
-bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) {
- // Decrement the excess count from the constructor.
- Decrement();
-
- return waitable_event_.TimedWait(max_time);
-}
-
-} // namespace
-
void BrowserProcessImpl::EndSession() {
// Mark all the profiles as clean.
ProfileManager* pm = profile_manager();
std::vector<Profile*> profiles(pm->GetLoadedProfiles());
- scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter());
- for (size_t i = 0; i < profiles.size(); ++i) {
- Profile* profile = profiles[i];
- profile->SetExitType(Profile::EXIT_SESSION_ENDED);
-
- rundown_counter->Post(profile->GetIOTaskRunner());
- }
+ for (size_t i = 0; i < profiles.size(); ++i)
+ profiles[i]->SetExitType(Profile::EXIT_SESSION_ENDED);
// Tell the metrics service it was cleanly shutdown.
MetricsService* metrics = g_browser_process->metrics_service();
@@ -464,8 +400,6 @@
// On ChromeOS, chrome gets killed when hangs, so no need to
// commit metrics::prefs::kStabilitySessionEndCompleted change immediately.
local_state()->CommitPendingWrite();
-
- rundown_counter->Post(local_state_task_runner_);
#endif
}
@@ -476,9 +410,7 @@
// otherwise on startup we'll think we crashed. So we block until done and
// then proceed with normal shutdown.
#if defined(USE_X11) || defined(OS_WIN)
- // Do a best-effort wait on the successful countdown of rundown tasks. Note
- // that if we don't complete "quickly enough", Windows will terminate our
- // process.
+ // Create a waitable event to block on file writing being complete.
//
// On Windows, we previously posted a message to FILE and then ran a nested
// message loop, waiting for that message to be processed until quitting.
@@ -489,8 +421,16 @@
// GPU process synchronously. Because the system may not be allowing
// processes to launch, this can result in a hang. See
// http://crbug.com/318527.
- rundown_counter->TimedWait(
- base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds));
+ scoped_ptr<base::WaitableEvent> done_writing(
+ new base::WaitableEvent(false, false));
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(Signal, done_writing.get()));
+ // If all file writes haven't cleared in the timeout, leak the WaitableEvent
+ // so that there's no race to reference it in Signal().
+ if (!done_writing->TimedWait(
+ base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds))) {
+ ignore_result(done_writing.release());
+ }
#else
NOTIMPLEMENTED();
#endif
« no previous file with comments | « no previous file | chrome/browser/lifetime/application_lifetime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698