File: chrome_process_singleton.cc

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (140 lines) | stat: -rw-r--r-- 5,094 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chrome_process_singleton.h"

#include <utility>

#include "build/build_config.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>

#include "base/compiler_specific.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/common/chrome_features.h"
#include "components/app_launch_prefetch/app_launch_prefetch.h"
#endif

namespace {

ChromeProcessSingleton* g_chrome_process_singleton_ = nullptr;

}  // namespace

ChromeProcessSingleton::ChromeProcessSingleton(
    const base::FilePath& user_data_dir)
    : startup_lock_(
          base::BindRepeating(&ChromeProcessSingleton::NotificationCallback,
                              base::Unretained(this))),
      process_singleton_(user_data_dir,
                         startup_lock_.AsNotificationCallback()) {}

ChromeProcessSingleton::~ChromeProcessSingleton() = default;

ProcessSingleton::NotifyResult
    ChromeProcessSingleton::NotifyOtherProcessOrCreate() {
  CHECK(!is_singleton_instance_);
  ProcessSingleton::NotifyResult result =
      process_singleton_.NotifyOtherProcessOrCreate();
  if (result == ProcessSingleton::PROCESS_NONE) {
    is_singleton_instance_ = true;
  }
  return result;
}

void ChromeProcessSingleton::StartWatching() {
  process_singleton_.StartWatching();
}

void ChromeProcessSingleton::Cleanup() {
  if (is_singleton_instance_) {
    process_singleton_.Cleanup();
  }
}

void ChromeProcessSingleton::Unlock(
    const ProcessSingleton::NotificationCallback& notification_callback) {
  notification_callback_ = notification_callback;
  startup_lock_.Unlock();
}

#if BUILDFLAG(IS_WIN)
void ChromeProcessSingleton::InitializeFeatures() {
  // On Windows, App Launch Prefetch (ALPF) will monitor the disk accesses done
  // by processes launched, and load the resources used into memory before the
  // process needs them, if possible. Different Chrome process types use
  // different resources, and this is signaled to ALPF via the command line:
  // passing "/prefetch:N" on the command line with different numbers causes
  // ALPF to treat two launches placed in different buckets as separarate
  // applications for its purposes.
  //
  // Short lived browser processes occur on notification and rendezvous, both
  // cases where nearly nothing will be used from disk, and which are not
  // launched with `/prefetch`, and are thus considered "browser" processes
  // according to ALPF. This may be polluting the ALPF cache.
  //
  // The `::ProcessOverrideSubsequentPrefetchParameter` process information
  // attribute will change the behavior of ALPF to explicitly consider
  // subsequent launches while this singleton process is running (rendezvous,
  // toast) of Chrome which do not specify a prefetch bucket as if they had
  // specified the `kCatchAll` bucket.
  //
  // It is expected that this will overall improve the behavior of ALPF on
  // Windows, which should decrease startup time for ordinary browser processes.
  if (is_singleton_instance_ &&
      (UNSAFE_TODO(wcsstr(::GetCommandLineW(), L"/prefetch:")) == nullptr) &&
      base::FeatureList::IsEnabled(features::kOverridePrefetchOnSingleton)) {
    OVERRIDE_PREFETCH_PARAMETER prefetch_parameter = {};
    prefetch_parameter.Value = app_launch_prefetch::GetPrefetchBucket(
        app_launch_prefetch::SubprocessType::kCatchAll);
    // This is not fatal because it is an optimization and has no bearing on the
    // functionality of the browser. See crbug.com/380088804 for details. It has
    // been seen that occasionally (in CQ), this call fails with
    // ERROR_INTERNAL_ERROR.
    base::UmaHistogramSparse(
        "Startup.PrefetchOverrideErrorCode",
        ::SetProcessInformation(::GetCurrentProcess(),
                                ::ProcessOverrideSubsequentPrefetchParameter,
                                &prefetch_parameter, sizeof(prefetch_parameter))
            ? ERROR_SUCCESS
            : ::GetLastError());
  }
}
#endif

// static
void ChromeProcessSingleton::CreateInstance(
    const base::FilePath& user_data_dir) {
  DCHECK(!g_chrome_process_singleton_);
  DCHECK(!user_data_dir.empty());
  g_chrome_process_singleton_ = new ChromeProcessSingleton(user_data_dir);
}

// static
void ChromeProcessSingleton::DeleteInstance() {
  if (g_chrome_process_singleton_) {
    delete g_chrome_process_singleton_;
    g_chrome_process_singleton_ = nullptr;
  }
}

// static
ChromeProcessSingleton* ChromeProcessSingleton::GetInstance() {
  CHECK(g_chrome_process_singleton_);
  return g_chrome_process_singleton_;
}

// static
bool ChromeProcessSingleton::IsSingletonInstance() {
  return g_chrome_process_singleton_ &&
         g_chrome_process_singleton_->is_singleton_instance_;
}

bool ChromeProcessSingleton::NotificationCallback(
    base::CommandLine command_line,
    const base::FilePath& current_directory) {
  DCHECK(notification_callback_);
  return notification_callback_.Run(std::move(command_line), current_directory);
}