1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/shared_memory.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,206 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_SHARED_MEMORY_H_ 1.9 +#define BASE_SHARED_MEMORY_H_ 1.10 + 1.11 +#include "build/build_config.h" 1.12 + 1.13 +#if defined(OS_POSIX) 1.14 +#include <sys/types.h> 1.15 +#include <semaphore.h> 1.16 +#include "base/file_descriptor_posix.h" 1.17 +#endif 1.18 +#include <string> 1.19 + 1.20 +#include "base/basictypes.h" 1.21 +#include "base/process.h" 1.22 + 1.23 +namespace base { 1.24 + 1.25 +// SharedMemoryHandle is a platform specific type which represents 1.26 +// the underlying OS handle to a shared memory segment. 1.27 +#if defined(OS_WIN) 1.28 +typedef HANDLE SharedMemoryHandle; 1.29 +typedef HANDLE SharedMemoryLock; 1.30 +#elif defined(OS_POSIX) 1.31 +// A SharedMemoryId is sufficient to identify a given shared memory segment on a 1.32 +// system, but insufficient to map it. 1.33 +typedef FileDescriptor SharedMemoryHandle; 1.34 +typedef ino_t SharedMemoryId; 1.35 +// On POSIX, the lock is implemented as a lockf() on the mapped file, 1.36 +// so no additional member (or definition of SharedMemoryLock) is 1.37 +// needed. 1.38 +#endif 1.39 + 1.40 +// Platform abstraction for shared memory. Provides a C++ wrapper 1.41 +// around the OS primitive for a memory mapped file. 1.42 +class SharedMemory { 1.43 + public: 1.44 + // Create a new SharedMemory object. 1.45 + SharedMemory(); 1.46 + 1.47 + // Create a new SharedMemory object from an existing, open 1.48 + // shared memory file. 1.49 + SharedMemory(SharedMemoryHandle handle, bool read_only); 1.50 + 1.51 + // Create a new SharedMemory object from an existing, open 1.52 + // shared memory file that was created by a remote process and not shared 1.53 + // to the current process. 1.54 + SharedMemory(SharedMemoryHandle handle, bool read_only, 1.55 + base::ProcessHandle process); 1.56 + 1.57 + // Destructor. Will close any open files. 1.58 + ~SharedMemory(); 1.59 + 1.60 + // Return true iff the given handle is valid (i.e. not the distingished 1.61 + // invalid value; NULL for a HANDLE and -1 for a file descriptor) 1.62 + static bool IsHandleValid(const SharedMemoryHandle& handle); 1.63 + 1.64 + // Return invalid handle (see comment above for exact definition). 1.65 + static SharedMemoryHandle NULLHandle(); 1.66 + 1.67 + // Creates or opens a shared memory segment based on a name. 1.68 + // If read_only is true, opens the memory as read-only. 1.69 + // If open_existing is true, and the shared memory already exists, 1.70 + // opens the existing shared memory and ignores the size parameter. 1.71 + // If name is the empty string, use a unique name. 1.72 + // Returns true on success, false on failure. 1.73 + bool Create(const std::string& name, bool read_only, bool open_existing, 1.74 + size_t size); 1.75 + 1.76 + // Deletes resources associated with a shared memory segment based on name. 1.77 + // Not all platforms require this call. 1.78 + bool Delete(const std::wstring& name); 1.79 + 1.80 + // Opens a shared memory segment based on a name. 1.81 + // If read_only is true, opens for read-only access. 1.82 + // If name is the empty string, use a unique name. 1.83 + // Returns true on success, false on failure. 1.84 + bool Open(const std::wstring& name, bool read_only); 1.85 + 1.86 + // Maps the shared memory into the caller's address space. 1.87 + // Returns true on success, false otherwise. The memory address 1.88 + // is accessed via the memory() accessor. 1.89 + bool Map(size_t bytes); 1.90 + 1.91 + // Unmaps the shared memory from the caller's address space. 1.92 + // Returns true if successful; returns false on error or if the 1.93 + // memory is not mapped. 1.94 + bool Unmap(); 1.95 + 1.96 + // Get the size of the opened shared memory backing file. 1.97 + // Note: This size is only available to the creator of the 1.98 + // shared memory, and not to those that opened shared memory 1.99 + // created externally. 1.100 + // Returns 0 if not opened or unknown. 1.101 + size_t max_size() const { return max_size_; } 1.102 + 1.103 + // Gets a pointer to the opened memory space if it has been 1.104 + // Mapped via Map(). Returns NULL if it is not mapped. 1.105 + void *memory() const { return memory_; } 1.106 + 1.107 + // Get access to the underlying OS handle for this segment. 1.108 + // Use of this handle for anything other than an opaque 1.109 + // identifier is not portable. 1.110 + SharedMemoryHandle handle() const; 1.111 + 1.112 +#if defined(OS_POSIX) 1.113 + // Return a unique identifier for this shared memory segment. Inode numbers 1.114 + // are technically only unique to a single filesystem. However, we always 1.115 + // allocate shared memory backing files from the same directory, so will end 1.116 + // up on the same filesystem. 1.117 + SharedMemoryId id() const { return inode_; } 1.118 +#endif 1.119 + 1.120 + // Closes the open shared memory segment. 1.121 + // It is safe to call Close repeatedly. 1.122 + void Close(); 1.123 + 1.124 + // Share the shared memory to another process. Attempts 1.125 + // to create a platform-specific new_handle which can be 1.126 + // used in a remote process to access the shared memory 1.127 + // file. new_handle is an ouput parameter to receive 1.128 + // the handle for use in the remote process. 1.129 + // Returns true on success, false otherwise. 1.130 + bool ShareToProcess(base::ProcessHandle process, 1.131 + SharedMemoryHandle* new_handle) { 1.132 + return ShareToProcessCommon(process, new_handle, false); 1.133 + } 1.134 + 1.135 + // Logically equivalent to: 1.136 + // bool ok = ShareToProcess(process, new_handle); 1.137 + // Close(); 1.138 + // return ok; 1.139 + // Note that the memory is unmapped by calling this method, regardless of the 1.140 + // return value. 1.141 + bool GiveToProcess(ProcessHandle process, 1.142 + SharedMemoryHandle* new_handle) { 1.143 + return ShareToProcessCommon(process, new_handle, true); 1.144 + } 1.145 + 1.146 + // Lock the shared memory. 1.147 + // This is a cross-process lock which may be recursively 1.148 + // locked by the same thread. 1.149 + // TODO(port): 1.150 + // WARNING: on POSIX the lock only works across processes, not 1.151 + // across threads. 2 threads in the same process can both grab the 1.152 + // lock at the same time. There are several solutions for this 1.153 + // (futex, lockf+anon_semaphore) but none are both clean and common 1.154 + // across Mac and Linux. 1.155 + void Lock(); 1.156 + 1.157 + // Release the shared memory lock. 1.158 + void Unlock(); 1.159 + 1.160 + private: 1.161 +#if defined(OS_POSIX) 1.162 + bool CreateOrOpen(const std::wstring &name, int posix_flags, size_t size); 1.163 + bool FilenameForMemoryName(const std::wstring &memname, 1.164 + std::wstring *filename); 1.165 + void LockOrUnlockCommon(int function); 1.166 + 1.167 +#endif 1.168 + bool ShareToProcessCommon(ProcessHandle process, 1.169 + SharedMemoryHandle* new_handle, 1.170 + bool close_self); 1.171 + 1.172 +#if defined(OS_WIN) 1.173 + std::wstring name_; 1.174 + HANDLE mapped_file_; 1.175 +#elif defined(OS_POSIX) 1.176 + int mapped_file_; 1.177 + ino_t inode_; 1.178 +#endif 1.179 + void* memory_; 1.180 + bool read_only_; 1.181 + size_t max_size_; 1.182 +#if !defined(OS_POSIX) 1.183 + SharedMemoryLock lock_; 1.184 +#endif 1.185 + 1.186 + DISALLOW_EVIL_CONSTRUCTORS(SharedMemory); 1.187 +}; 1.188 + 1.189 +// A helper class that acquires the shared memory lock while 1.190 +// the SharedMemoryAutoLock is in scope. 1.191 +class SharedMemoryAutoLock { 1.192 + public: 1.193 + explicit SharedMemoryAutoLock(SharedMemory* shared_memory) 1.194 + : shared_memory_(shared_memory) { 1.195 + shared_memory_->Lock(); 1.196 + } 1.197 + 1.198 + ~SharedMemoryAutoLock() { 1.199 + shared_memory_->Unlock(); 1.200 + } 1.201 + 1.202 + private: 1.203 + SharedMemory* shared_memory_; 1.204 + DISALLOW_EVIL_CONSTRUCTORS(SharedMemoryAutoLock); 1.205 +}; 1.206 + 1.207 +} // namespace base 1.208 + 1.209 +#endif // BASE_SHARED_MEMORY_H_