1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/process_singleton_startup_lock.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ProcessSingletonStartupLock::ProcessSingletonStartupLock(
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProcessSingleton::NotificationCallback& original_callback)
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : locked_(true),
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      original_callback_(original_callback) {}
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ProcessSingletonStartupLock::~ProcessSingletonStartupLock() {}
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ProcessSingleton::NotificationCallback
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ProcessSingletonStartupLock::AsNotificationCallback() {
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return base::Bind(&ProcessSingletonStartupLock::NotificationCallbackImpl,
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    base::Unretained(this));
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProcessSingletonStartupLock::Unlock() {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(CalledOnValidThread());
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  locked_ = false;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Replay the command lines of the messages which were received while the
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // ProcessSingleton was locked. Only replay each message once.
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<DelayedStartupMessage> replayed_messages;
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (std::vector<DelayedStartupMessage>::const_iterator it =
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           saved_startup_messages_.begin();
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       it != saved_startup_messages_.end(); ++it) {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (replayed_messages.find(*it) != replayed_messages.end())
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    original_callback_.Run(CommandLine(it->first), it->second);
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    replayed_messages.insert(*it);
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  saved_startup_messages_.clear();
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ProcessSingletonStartupLock::NotificationCallbackImpl(
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const CommandLine& command_line,
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& current_directory) {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (locked_) {
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If locked, it means we are not ready to process this message because
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // we are probably in a first run critical phase.
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    saved_startup_messages_.push_back(
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::make_pair(command_line.argv(), current_directory));
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return original_callback_.Run(command_line, current_directory);
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
54