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

Side by Side Diff: base/linux_util.cc

Issue 273026: Make GetLinuxDistro thread-safe. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: rename the class to LinuxDistroHelper, so the enum can be LinuxDistroState Created 11 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 4
5 #include "base/linux_util.h" 5 #include "base/linux_util.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/lock.h"
12 #include "base/process_util.h" 13 #include "base/process_util.h"
14 #include "base/singleton.h"
13 #include "base/string_util.h" 15 #include "base/string_util.h"
14 16
15 namespace { 17 namespace {
16 18
17 class EnvironmentVariableGetterImpl 19 class EnvironmentVariableGetterImpl
18 : public base::EnvironmentVariableGetter { 20 : public base::EnvironmentVariableGetter {
19 public: 21 public:
20 virtual bool Getenv(const char* variable_name, std::string* result) { 22 virtual bool Getenv(const char* variable_name, std::string* result) {
21 const char* env_value = ::getenv(variable_name); 23 const char* env_value = ::getenv(variable_name);
22 if (env_value) { 24 if (env_value) {
(...skipping 14 matching lines...) Expand all
37 return false; 39 return false;
38 env_value = ::getenv(alternate_case_var.c_str()); 40 env_value = ::getenv(alternate_case_var.c_str());
39 if (env_value) { 41 if (env_value) {
40 *result = env_value; 42 *result = env_value;
41 return true; 43 return true;
42 } 44 }
43 return false; 45 return false;
44 } 46 }
45 }; 47 };
46 48
47 } // anonymous namespace 49 enum LinuxDistroState {
50 STATE_DID_NOT_CHECK = 0,
51 STATE_CHECK_STARTED = 1,
52 STATE_CHECK_FINISHED = 2,
53 };
54
55 // Helper class for GetLinuxDistro().
56 class LinuxDistroHelper {
57 public:
58 // Retrieves the Singleton.
59 static LinuxDistroHelper* Get() {
60 return Singleton<LinuxDistroHelper>::get();
61 }
62
63 // The simple state machine goes from:
64 // STATE_DID_NOT_CHECK -> STATE_CHECK_STARTED -> STATE_CHECK_FINISHED.
65 LinuxDistroHelper() : state_(STATE_DID_NOT_CHECK) {}
66 ~LinuxDistroHelper() {}
67
68 // Retrieve the current state, if we're in STATE_DID_NOT_CHECK,
69 // we automatically move to STATE_CHECK_STARTED so nobody else will
70 // do the check.
71 LinuxDistroState State() {
72 AutoLock scoped_lock(lock_);
73 if (STATE_DID_NOT_CHECK == state_) {
74 state_ = STATE_CHECK_STARTED;
75 return STATE_DID_NOT_CHECK;
76 }
77 return state_;
78 }
79
80 // Indicate the check finished, move to STATE_CHECK_FINISHED.
81 void CheckFinished() {
82 AutoLock scoped_lock(lock_);
83 DCHECK(state_ == STATE_CHECK_STARTED);
84 state_ = STATE_CHECK_FINISHED;
85 }
86
87 private:
88 Lock lock_;
89 LinuxDistroState state_;
90 };
91
92 } // anonymous namespace
48 93
49 namespace base { 94 namespace base {
50 95
51 uint8_t* BGRAToRGBA(const uint8_t* pixels, int width, int height, int stride) { 96 uint8_t* BGRAToRGBA(const uint8_t* pixels, int width, int height, int stride) {
52 if (stride == 0) 97 if (stride == 0)
53 stride = width * 4; 98 stride = width * 4;
54 99
55 uint8_t* new_pixels = static_cast<uint8_t*>(malloc(height * stride)); 100 uint8_t* new_pixels = static_cast<uint8_t*>(malloc(height * stride));
56 101
57 // We have to copy the pixels and swap from BGRA to RGBA. 102 // We have to copy the pixels and swap from BGRA to RGBA.
58 for (int i = 0; i < height; ++i) { 103 for (int i = 0; i < height; ++i) {
59 for (int j = 0; j < width; ++j) { 104 for (int j = 0; j < width; ++j) {
60 int idx = i * stride + j * 4; 105 int idx = i * stride + j * 4;
61 new_pixels[idx] = pixels[idx + 2]; 106 new_pixels[idx] = pixels[idx + 2];
62 new_pixels[idx + 1] = pixels[idx + 1]; 107 new_pixels[idx + 1] = pixels[idx + 1];
63 new_pixels[idx + 2] = pixels[idx]; 108 new_pixels[idx + 2] = pixels[idx];
64 new_pixels[idx + 3] = pixels[idx + 3]; 109 new_pixels[idx + 3] = pixels[idx + 3];
65 } 110 }
66 } 111 }
67 112
68 return new_pixels; 113 return new_pixels;
69 } 114 }
70 115
71 // We use this static string to hold the Linux distro info. If we 116 // We use this static string to hold the Linux distro info. If we
72 // crash, the crash handler code will send this in the crash dump. 117 // crash, the crash handler code will send this in the crash dump.
73 std::string linux_distro = "Unknown"; 118 std::string linux_distro = "Unknown";
74 119
75 std::string GetLinuxDistro() { 120 std::string GetLinuxDistro() {
76 static bool checked_distro = false; 121 LinuxDistroHelper* distro_state_singleton = LinuxDistroHelper::Get();
77 if (!checked_distro) { 122 LinuxDistroState state = distro_state_singleton->State();
123 if (STATE_DID_NOT_CHECK == state) {
124 // We do this check only once per process. If it fails, there's
125 // little reason to believe it will work if we attempt to run
126 // lsb_release again.
78 std::vector<std::string> argv; 127 std::vector<std::string> argv;
79 argv.push_back("lsb_release"); 128 argv.push_back("lsb_release");
80 argv.push_back("-d"); 129 argv.push_back("-d");
81 std::string output; 130 std::string output;
82 base::GetAppOutput(CommandLine(argv), &output); 131 base::GetAppOutput(CommandLine(argv), &output);
83 if (output.length() > 0) { 132 if (output.length() > 0) {
84 // lsb_release -d should return: Description:<tab>Distro Info 133 // lsb_release -d should return: Description:<tab>Distro Info
85 static const std::string field = "Description:\t"; 134 static const std::string field = "Description:\t";
86 if (output.compare(0, field.length(), field) == 0) 135 if (output.compare(0, field.length(), field) == 0)
87 linux_distro = output.substr(field.length()); 136 linux_distro = output.substr(field.length());
88 } 137 }
89 // We do this check only once per process. If it fails, there's 138 distro_state_singleton->CheckFinished();
90 // little reason to believe it will work if we attempt to run 139 return linux_distro;
91 // lsb_release again. 140 } else if (STATE_CHECK_STARTED == state) {
92 checked_distro = true; 141 // If the distro check above is in progress in some other thread, we're
142 // not going to wait for the results.
143 return "Unknown";
144 } else {
145 // In STATE_CHECK_FINISHED, no more writing to |linux_distro|.
146 return linux_distro;
93 } 147 }
94 return linux_distro;
95 } 148 }
96 149
97 // static 150 // static
98 EnvironmentVariableGetter* EnvironmentVariableGetter::Create() { 151 EnvironmentVariableGetter* EnvironmentVariableGetter::Create() {
99 return new EnvironmentVariableGetterImpl(); 152 return new EnvironmentVariableGetterImpl();
100 } 153 }
101 154
102 DesktopEnvironment GetDesktopEnvironment(EnvironmentVariableGetter* env) { 155 DesktopEnvironment GetDesktopEnvironment(EnvironmentVariableGetter* env) {
103 std::string desktop_session; 156 std::string desktop_session;
104 if (env->Getenv("DESKTOP_SESSION", &desktop_session)) { 157 if (env->Getenv("DESKTOP_SESSION", &desktop_session)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 return "KDE4"; 189 return "KDE4";
137 } 190 }
138 return NULL; 191 return NULL;
139 } 192 }
140 193
141 const char* GetDesktopEnvironmentName(EnvironmentVariableGetter* env) { 194 const char* GetDesktopEnvironmentName(EnvironmentVariableGetter* env) {
142 return GetDesktopEnvironmentName(GetDesktopEnvironment(env)); 195 return GetDesktopEnvironmentName(GetDesktopEnvironment(env));
143 } 196 }
144 197
145 } // namespace base 198 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698