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

Unified Diff: base/shared_memory_ptr.h

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/shared_any.h ('k') | base/shell.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/shared_memory_ptr.h
diff --git a/base/shared_memory_ptr.h b/base/shared_memory_ptr.h
deleted file mode 100644
index d813cc691996733e2b89daf780949acf955a3f43..0000000000000000000000000000000000000000
--- a/base/shared_memory_ptr.h
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright 2004-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-//
-// Defines template class used to share data
-// between processes.
-//
-
-#ifndef OMAHA_COMMON_SHARED_MEMORY_PTR_H__
-#define OMAHA_COMMON_SHARED_MEMORY_PTR_H__
-
-#include "base/debug.h"
-#include "base/singleton.h"
-#include "base/system_info.h"
-#include "base/vista_utils.h"
-
-namespace omaha {
-
-// SharedMemoryPtr class is designed to allow seamless data sharing process boundaries.
-// All the data passed as a template parameter will be shared between processes.
-// Very important to remember that for now - all shared data should be on stack.
-// For example if the class A had stl vector as a member, the members of the vector
-// would be allocated not from shared memory and therefore will not be shared.
-// That could be solved with allocators, but for now we don't need that.
-//
-// Here is a typical example of usage:
-// Class A {
-// int i_;
-// double d_;
-// .......
-// ........
-//
-// public:
-// set_double(double d){d_=d;}
-// double get_double(){return d_};
-//
-// };
-//
-// ... Prosess one...
-// SharedMemoryPtr<A> spA("ABC");
-// if (!spA)
-// return false;
-//
-// spA->set_double(3.14);
-//
-// ... Process two ...
-//
-//
-// SharedMemoryPtr<A> spA1("ABC");
-// if (!spA1)
-// return false;
-//
-// process two will see the value set by process one.
-// it will be 3.14
-// double d = spA1->get_double();
-//
-
-// You should implement a class member of SystemSharedData if the data you want
-// to share is several hundred bytes. Always try this approach first before you implement
-// new class that is derived from SharedMemoryPtr. The main difference is that SharedMemoryPtr
-// will allocate a least page of shared memory. If your class is just a member of SystemSharedData
-// memory mapped file will be shared between members. It is just more efficient.
-// Look in system_shared_data.h , shared_data_member.h, and system_shared_data_members.h
-// for more details.
-
-// Forward declaration.
-template <typename LockType, typename T> class SharedMemoryPtr;
-
-// During several code reviews it has been noticed that the same error gets repeated over and over.
-// People create SharedMemoryPtr<SomeData>. And than the access to member functions of SomeData
-// is not synchronized by __mutexBlock or __mutexScope. So we need to somehow find a way to make
-// automatic syncronization whenever people access shared data methods or members.
-// Since by design the only way we can acess shared data is through operator -> of SharedMemoryPtr
-// we need to somehow invoke synchronization at the time of access.
-// We can implement this mainly because of the mechanics of operator-> dictated by C++ standard.
-// When you apply operator-> to a type that's not a built-in pointer, the compiler does an interesting thing.
-// After looking up and applying the user-defined operator-> to that type, it applies operator-> again to the result.
-// The compiler keeps doing this recursively until it reaches a pointer to a built-in type, and only then proceeds with member access.
-// It follows that a SharedMemoryPtr<T> operator-> does not have to return a pointer.
-// It can return an object that in turn implements operator->, without changing the use syntax.
-// So we can implement: pre- and postfunction calls. (See Stroustrup 2000)
-// If you return an object of some type X
-// by value from operator->, the sequence of execution is as follows:
-// 1. Constructor of type X
-// 2. X::operator-> called; returns a pointer to an object of type T of SharedMemoryPtr
-// 3. Member access
-// 4. Destructor of X
-// In a nutshell, we have a way of implementing locked function calls.
-
-template <typename LockType, typename T>
-class SharedDataLockingProxy {
-public:
- // Lock on construction.
- SharedDataLockingProxy(SharedMemoryPtr<LockType, T> * mem_ptr, T* shared_data)
- : mem_ptr_(mem_ptr), shared_data_(shared_data) {
- mem_ptr_->Lock();
- }
- // Unlock on destruction.
- ~SharedDataLockingProxy() {
- mem_ptr_->Unlock();
- }
- // operator
- T* operator->() const {
- ASSERT(shared_data_ != NULL, (L"NULL object pointer being dereferenced"));
- return shared_data_;
- }
-private:
- SharedDataLockingProxy& operator=(const SharedDataLockingProxy&);
- SharedMemoryPtr<LockType, T>* mem_ptr_;
- T* shared_data_;
- // To allow this implicit locking - copy constructor must be
- // enabled. hence, no DISALLOW_EVIL_CONSTRUCTORS
-};
-
-template <typename LockType, typename T> class SharedMemoryPtr
- : public LockType {
- // Handle to disk file if we're backing this shared memory by a file
- HANDLE file_;
- // Local handle to file mapping.
- HANDLE file_mapping_;
- // pointer to a view.
- T* data_;
- // If the first time creation can do some initialization.
- bool first_instance_;
-public:
- // The heart of the whole idea. Points to shared memrory
- // instead of the beginning of the class.
- SharedDataLockingProxy<LockType, T> operator->() {
- return SharedDataLockingProxy<LockType, T>(this, data_);
- }
- // To check after creation.
- // For example:
- // SharedMemoryPtr<GLock, SomeClass> sm;
- // if (sm)
- // { do whatever you want}
- // else
- // {error reporting}
- operator bool() const {return ((file_mapping_ != NULL) && (data_ != NULL));}
-
- // Initialize memory mapped file and sync mechanics.
- // by calling InitializeSharedAccess
- SharedMemoryPtr(const CString& name,
- LPSECURITY_ATTRIBUTES sa,
- LPSECURITY_ATTRIBUTES sa_mutex,
- bool read_only)
- : file_(INVALID_HANDLE_VALUE),
- file_mapping_(NULL),
- data_(NULL) {
- HRESULT hr = InitializeSharedAccess(name, false, sa, sa_mutex, read_only);
- if (FAILED(hr)) {
- UTIL_LOG(LE, (_T("InitializeSharedAccess failed [%s][%s][0x%x]"),
- name, read_only ? _T("R") : _T("RW"), hr));
- }
- }
-
- // Use this constructor if you want to back the shared memory by a file.
- // NOTE: if using a persistent shared memory, every object with this same
- // name should be persistent. Otherwise, the objects marked as
- // non-persistent will lead to InitializeSharedData called again if
- // they are instantiated before the ones marked as persistent.
- SharedMemoryPtr(bool persist,
- LPSECURITY_ATTRIBUTES sa,
- LPSECURITY_ATTRIBUTES sa_mutex,
- bool read_only)
- : file_(INVALID_HANDLE_VALUE),
- file_mapping_(NULL),
- data_(NULL) {
- // Each shared data must implement GetFileName() to use this c-tor. The
- // implementation should be:
- // const CString GetFileName() const {return L"C:\\directory\file";}
- // This is purposedly different from GetSharedName, so that the user is
- // well aware that a file name is expected, not a mutex name.
- HRESULT hr = InitializeSharedAccess(data_->GetFileName(),
- persist,
- sa,
- sa_mutex,
- read_only);
- if (FAILED(hr)) {
- UTIL_LOG(LE, (_T("InitializeSharedAccess failed [%s][%s][0x%x]"),
- data_->GetFileName(), read_only ? _T("R") : _T("RW"), hr));
- }
- }
-
- // Initialize memory mapped file and sync mechanics.
- // by calling InitializeSharedAccess
- SharedMemoryPtr() :
- file_(INVALID_HANDLE_VALUE), file_mapping_(NULL), data_(NULL) {
- // This should never happen but let's assert
- // in case it does.
- // Each shared data must implement GetSharedData() to use this c-tor.
- // The implementation should be:
- // const TCHAR * GetSharedName() const
- // {return L"Some_unique_string_with_no_spaces";}
- HRESULT hr = InitializeSharedAccess(data_->GetSharedName(),
- false,
- NULL,
- NULL,
- false);
- if (FAILED(hr)) {
- UTIL_LOG(LE, (_T("InitializeSharedAccess failed [%s][%s][0x%x]"),
- data_->GetSharedName(), _T("RW"), hr));
- }
- }
-
- // Clean up.
- ~SharedMemoryPtr() {
- Cleanup();
- }
-
- void Cleanup() {
- __mutexScope(this);
- if (data_)
- UnmapViewOfFile(data_);
- if (file_mapping_)
- VERIFY(CloseHandle(file_mapping_), (L""));
- if (file_ != INVALID_HANDLE_VALUE)
- VERIFY(CloseHandle(file_), (L""));
- }
-
- // Initialize memory mapped file and sync object.
- bool InitializeSharedAccess(const CString& name,
- bool persist,
- LPSECURITY_ATTRIBUTES sa,
- LPSECURITY_ATTRIBUTES sa_mutex,
- bool read_only) {
- return InitializeSharedAccessInternal(name,
- persist,
- sa,
- sa_mutex,
- read_only,
- sizeof(T),
- &T::InitializeSharedData);
- }
-
- private:
- // Initialize memory mapped file and sync object.
- //
- // This internal method allows template method folding by only using things
- // that are consistent in all templates. Things that vary are passed in.
- bool InitializeSharedAccessInternal(const CString& name, bool persist,
- LPSECURITY_ATTRIBUTES sa,
- LPSECURITY_ATTRIBUTES sa_mutex,
- bool read_only,
- size_t data_size,
- void (T::*initialize_shared_data)
- (const CString&)) {
- // If this memory mapped object is backed by a file, then "name" is a fully
- // qualified name with backslashes. Since we can't use backslashes in a
- // mutex's name, let's make another name where we convert them to
- // underscores.
- CString mem_name(name);
- if (persist) {
- mem_name.Replace(_T('\\'), _T('_'));
- }
-
- // Initialize the mutex
- CString mutex_name(mem_name + _T("MUTEX"));
- LPSECURITY_ATTRIBUTES mutex_attr = sa_mutex ? sa_mutex : sa;
- if (!InitializeWithSecAttr(mutex_name, mutex_attr)) {
- ASSERT(false, (L"Failed to initialize mutex. Err=%i", ::GetLastError()));
- return false;
- }
-
- // everything is synchronized till the end of the function or return.
- __mutexScope(this);
-
- first_instance_ = false;
-
- if (persist) {
- // Back this shared memory by a file
- file_ = CreateFile(name,
- GENERIC_READ | (read_only ? 0 : GENERIC_WRITE),
- FILE_SHARE_READ | (read_only ? 0 : FILE_SHARE_WRITE),
- sa,
- OPEN_ALWAYS,
- NULL,
- NULL);
- if (file_ == INVALID_HANDLE_VALUE)
- return false;
-
- if (!read_only && GetLastError() != ERROR_ALREADY_EXISTS)
- first_instance_ = true;
- } else {
- ASSERT(file_ == INVALID_HANDLE_VALUE, (L""));
- file_ = INVALID_HANDLE_VALUE;
- }
-
- if (read_only) {
- file_mapping_ = OpenFileMapping(FILE_MAP_READ, false, mem_name);
- if (!file_mapping_) {
- UTIL_LOG(LW, (L"[OpenFileMapping failed][error %i]", ::GetLastError()));
- }
- } else {
- file_mapping_ = CreateFileMapping(file_, sa,
- PAGE_READWRITE, 0, data_size, mem_name);
- ASSERT(file_mapping_, (L"CreateFileMapping. Err=%i", ::GetLastError()));
- }
-
- if (!file_mapping_) {
- return false;
- } else if (!read_only &&
- file_ == INVALID_HANDLE_VALUE &&
- GetLastError() != ERROR_ALREADY_EXISTS) {
- first_instance_ = true;
- }
-
- data_ = reinterpret_cast<T*>(MapViewOfFile(file_mapping_,
- FILE_MAP_READ |
- (read_only ? 0 : FILE_MAP_WRITE),
- 0,
- 0,
- data_size));
-
- if (!data_) {
- ASSERT(false, (L"MapViewOfFile. Err=%i", ::GetLastError()));
- VERIFY(CloseHandle(file_mapping_), (L""));
- file_mapping_ = NULL;
-
- if (file_ != INVALID_HANDLE_VALUE) {
- VERIFY(CloseHandle(file_), (L""));
- file_ = INVALID_HANDLE_VALUE;
- }
-
- return false;
- }
-
- if (!first_instance_) {
- return true;
- }
-
- // If this is the first instance of shared object
- // call initialization function. This is nice but
- // at the same time we can not share built in data types.
- // SharedMemoryPtr<double> - will not compile. But this is OK
- // We don't want all the overhead to just share couple of bytes.
- // Signature is void InitializeSharedData()
- (data_->*initialize_shared_data)(name);
-
- return true;
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(SharedMemoryPtr);
-};
-
-// Sometimes we want Singletons that are shared between processes.
-// SharedMemoryPtr can do that. But if used in C-written module there will be
-// a need to make SharedMemoryPtr a global object. Making a Singleton from SharedMemoryPtr
-// is possible in this situation, but syntactically this is very difficult to read.
-// The following template solves the problem. It hides difficult to read details inside.
-// Usage is the same as SharedMemoryPtr (ONLY through -> operator). Completely thread-safe.
-// Can be used in two ways:
-// Class A {
-// public:
-// void foo(){}
-//
-//};
-// SharedMemorySingleton<A> a, b;
-// a->foo();
-// b->foo(); //refers to the same data in any process.
-//
-// or
-//
-// class A : public SharedMemorySingleton<A> {
-// public:
-// void foo(){}
-//};
-// A a, b;
-// a->foo();
-// b->foo(); //refers to the same data in any process.
-
-template <typename LockType, typename T> class SharedMemorySingleton {
-public:
- SharedDataLockingProxy<LockType, T> operator->() {
- return
- Singleton<SharedMemoryPtr<LockType, T> >::Instance()->operator->();
- }
-};
-
-} // namespace omaha
-
-#endif // OMAHA_COMMON_SHARED_MEMORY_PTR_H__
« no previous file with comments | « base/shared_any.h ('k') | base/shell.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698