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

Unified Diff: chrome/common/service_process_util.cc

Issue 6349029: Get service processes working on Mac and Linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix up small typo in comment Created 9 years, 11 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 | « chrome/common/service_process_util.h ('k') | chrome/common/service_process_util_posix.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/common/service_process_util.cc
diff --git a/chrome/common/service_process_util.cc b/chrome/common/service_process_util.cc
index 4062e0f21d877ee2f63ee7d2b8be864666e9d067..458f66210349bd747347248e9f68dd7cce873ea4 100644
--- a/chrome/common/service_process_util.cc
+++ b/chrome/common/service_process_util.cc
@@ -6,10 +6,13 @@
#include "base/file_util.h"
#include "base/logging.h"
+#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/path_service.h"
#include "base/process_util.h"
+#include "base/sha1.h"
#include "base/singleton.h"
#include "base/string16.h"
+#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/version.h"
@@ -36,29 +39,6 @@ std::string GetServiceProcessSharedMemName() {
return GetServiceProcessScopedName("_service_shmem");
}
-// Reads the named shared memory to get the shared data. Returns false if no
-// matching shared memory was found.
-bool GetServiceProcessSharedData(std::string* version, base::ProcessId* pid) {
- scoped_ptr<base::SharedMemory> shared_mem_service_data;
- shared_mem_service_data.reset(new base::SharedMemory());
- ServiceProcessSharedData* service_data = NULL;
- if (shared_mem_service_data.get() &&
- shared_mem_service_data->Open(GetServiceProcessSharedMemName(), true) &&
- shared_mem_service_data->Map(sizeof(ServiceProcessSharedData))) {
- service_data = reinterpret_cast<ServiceProcessSharedData*>(
- shared_mem_service_data->memory());
- // Make sure the version in shared memory is null-terminated. If it is not,
- // treat it as invalid.
- if (version && memchr(service_data->service_process_version, '\0',
- sizeof(service_data->service_process_version)))
- *version = service_data->service_process_version;
- if (pid)
- *pid = service_data->service_process_pid;
- return true;
- }
- return false;
-}
-
enum ServiceProcessRunningState {
SERVICE_NOT_RUNNING,
SERVICE_OLDER_VERSION_RUNNING,
@@ -67,12 +47,20 @@ enum ServiceProcessRunningState {
};
ServiceProcessRunningState GetServiceProcessRunningState(
- std::string* service_version_out) {
+ std::string* service_version_out, base::ProcessId* pid_out) {
std::string version;
- GetServiceProcessSharedData(&version, NULL);
- if (version.empty())
+ if (!GetServiceProcessSharedData(&version, pid_out))
return SERVICE_NOT_RUNNING;
+#if defined(OS_POSIX)
+ // We only need to check for service running on POSIX because Windows cleans
+ // up shared memory files when an app crashes, so there isn't a chance of
+ // us reading bogus data from shared memory for an app that has died.
+ if (!CheckServiceProcessReady()) {
+ return SERVICE_NOT_RUNNING;
+ }
+#endif // defined(OS_POSIX)
+
// At this time we have a version string. Set the out param if it exists.
if (service_version_out)
*service_version_out = version;
@@ -107,23 +95,22 @@ ServiceProcessRunningState GetServiceProcessRunningState(
return SERVICE_SAME_VERSION_RUNNING;
}
-
} // namespace
// Return a name that is scoped to this instance of the service process. We
-// use the user-data-dir as a scoping prefix.
+// use the hash of the user-data-dir as a scoping prefix. We can't use
+// the user-data-dir itself as we have limits on the size of the lock names.
std::string GetServiceProcessScopedName(const std::string& append_str) {
FilePath user_data_dir;
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
#if defined(OS_WIN)
- std::string scoped_name = WideToUTF8(user_data_dir.value());
+ std::string user_data_dir_path = WideToUTF8(user_data_dir.value());
#elif defined(OS_POSIX)
- std::string scoped_name = user_data_dir.value();
+ std::string user_data_dir_path = user_data_dir.value();
#endif // defined(OS_WIN)
- std::replace(scoped_name.begin(), scoped_name.end(), '\\', '!');
- std::replace(scoped_name.begin(), scoped_name.end(), '/', '!');
- scoped_name.append(append_str);
- return scoped_name;
+ std::string hash = base::SHA1HashString(user_data_dir_path);
+ std::string hex_hash = base::HexEncode(hash.c_str(), hash.length());
+ return hex_hash + "." + append_str;
}
// Return a name that is scoped to this instance of the service process. We
@@ -143,16 +130,40 @@ std::string GetServiceProcessChannelName() {
return GetServiceProcessScopedVersionedName("_service_ipc");
}
-base::ProcessId GetServiceProcessPid() {
- base::ProcessId pid = 0;
- GetServiceProcessSharedData(NULL, &pid);
- return pid;
+// Reads the named shared memory to get the shared data. Returns false if no
+// matching shared memory was found.
+bool GetServiceProcessSharedData(std::string* version, base::ProcessId* pid) {
+ scoped_ptr<base::SharedMemory> shared_mem_service_data;
+ shared_mem_service_data.reset(new base::SharedMemory());
+ ServiceProcessSharedData* service_data = NULL;
+ if (shared_mem_service_data.get() &&
+ shared_mem_service_data->Open(GetServiceProcessSharedMemName(), true) &&
+ shared_mem_service_data->Map(sizeof(ServiceProcessSharedData))) {
+ service_data = reinterpret_cast<ServiceProcessSharedData*>(
+ shared_mem_service_data->memory());
+ // Make sure the version in shared memory is null-terminated. If it is not,
+ // treat it as invalid.
+ if (version && memchr(service_data->service_process_version, '\0',
+ sizeof(service_data->service_process_version)))
+ *version = service_data->service_process_version;
+ if (pid)
+ *pid = service_data->service_process_pid;
+ return true;
+ }
+ return false;
}
ServiceProcessState::ServiceProcessState() : state_(NULL) {
}
ServiceProcessState::~ServiceProcessState() {
+ if (shared_mem_service_data_.get()) {
+ // Delete needs a pool wrapped around it because it calls some Obj-C on Mac,
+ // and since ServiceProcessState is a singleton, it gets destructed after
+ // the standard NSAutoreleasePools have already been cleaned up.
+ base::mac::ScopedNSAutoreleasePool pool;
+ shared_mem_service_data_->Delete(GetServiceProcessSharedMemName());
+ }
TearDownState();
}
@@ -167,30 +178,26 @@ bool ServiceProcessState::Initialize() {
}
// Now that we have the singleton, take care of killing an older version, if
// it exists.
- if (ShouldHandleOtherVersion() && !HandleOtherVersion())
+ if (!HandleOtherVersion())
return false;
- // TODO(sanjeevr): We can probably use the shared mem as the sole singleton
- // mechanism. For that the shared mem class needs to return whether it created
- // new instance or opened an existing one. Also shared memory on Linux uses
- // a file on disk which is not deleted when the process exits.
-
- // Now that we have the singleton, let is also write the version we are using
- // to shared memory. This can be used by a newer service to signal us to exit.
+ // Write the version we are using to shared memory. This can be used by a
+ // newer service to signal us to exit.
return CreateSharedData();
}
bool ServiceProcessState::HandleOtherVersion() {
std::string running_version;
+ base::ProcessId process_id;
ServiceProcessRunningState state =
- GetServiceProcessRunningState(&running_version);
+ GetServiceProcessRunningState(&running_version, &process_id);
switch (state) {
case SERVICE_SAME_VERSION_RUNNING:
case SERVICE_NEWER_VERSION_RUNNING:
return false;
case SERVICE_OLDER_VERSION_RUNNING:
// If an older version is running, kill it.
- ForceServiceProcessShutdown(running_version);
+ ForceServiceProcessShutdown(running_version, process_id);
break;
case SERVICE_NOT_RUNNING:
break;
@@ -211,8 +218,8 @@ bool ServiceProcessState::CreateSharedData() {
return false;
}
- scoped_ptr<base::SharedMemory> shared_mem_service_data;
- shared_mem_service_data.reset(new base::SharedMemory());
+ scoped_ptr<base::SharedMemory> shared_mem_service_data(
+ new base::SharedMemory());
if (!shared_mem_service_data.get())
return false;
@@ -235,7 +242,11 @@ bool ServiceProcessState::CreateSharedData() {
return true;
}
-
std::string ServiceProcessState::GetAutoRunKey() {
return GetServiceProcessScopedName("_service_run");
}
+
+void ServiceProcessState::SignalStopped() {
+ TearDownState();
+ shared_mem_service_data_.reset();
+}
« no previous file with comments | « chrome/common/service_process_util.h ('k') | chrome/common/service_process_util_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698