Chromium Code Reviews| 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..a6f656292f468da13dd71ef8276f8cb3dc9bcfdc 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,9 +47,9 @@ enum ServiceProcessRunningState { |
| }; |
| ServiceProcessRunningState GetServiceProcessRunningState( |
| - std::string* service_version_out) { |
| + std::string* service_version_out, base::ProcessId* pid_out) { |
| std::string version; |
| - GetServiceProcessSharedData(&version, NULL); |
| + GetServiceProcessSharedData(&version, pid_out); |
| if (version.empty()) |
| return SERVICE_NOT_RUNNING; |
| @@ -111,19 +91,19 @@ ServiceProcessRunningState GetServiceProcessRunningState( |
| } // 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 +123,38 @@ 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; |
|
Scott Byer
2011/02/02 00:12:38
Did this function need to get moved? It's not like
dmac
2011/02/02 00:56:25
Yes, I needed to take it out of the anonymous name
|
| + 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 call some obj-c on Mac. |
| + base::mac::ScopedNSAutoreleasePool pool; |
| + shared_mem_service_data_->Delete(GetServiceProcessSharedMemName()); |
| + } |
| TearDownState(); |
| } |
| @@ -182,15 +184,16 @@ bool ServiceProcessState::Initialize() { |
| 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 +214,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 +238,11 @@ bool ServiceProcessState::CreateSharedData() { |
| return true; |
| } |
| - |
| std::string ServiceProcessState::GetAutoRunKey() { |
| return GetServiceProcessScopedName("_service_run"); |
| } |
| + |
| +void ServiceProcessState::SignalStopped() { |
| + TearDownState(); |
| + shared_mem_service_data_.reset(); |
| +} |