blob: 1f8237eb3001c6399e9cfe6faf0f8e9548986b3a [file] [log] [blame]
[email protected]c47ad0d2012-02-25 00:56:141// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]39be4242008-08-07 18:31:405#ifndef BASE_SHARED_MEMORY_H_
6#define BASE_SHARED_MEMORY_H_
initial.commitd7cae122008-07-26 21:49:387
[email protected]5425c682008-11-14 20:08:028#include "build/build_config.h"
9
[email protected]a0c136a02012-02-25 06:28:5610#include <string>
11
[email protected]5425c682008-11-14 20:08:0212#if defined(OS_POSIX)
[email protected]c47ad0d2012-02-25 00:56:1413#include <stdio.h>
[email protected]e68e62fa2009-02-20 02:00:0414#include <sys/types.h>
[email protected]5425c682008-11-14 20:08:0215#include <semaphore.h>
16#endif
[email protected]5425c682008-11-14 20:08:0217
[email protected]0bea7252011-08-05 15:34:0018#include "base/base_export.h"
[email protected]39be4242008-08-07 18:31:4019#include "base/basictypes.h"
[email protected]de5abb92008-10-22 21:33:2720#include "base/process.h"
initial.commitd7cae122008-07-26 21:49:3821
[email protected]a0c136a02012-02-25 06:28:5622#if defined(OS_POSIX)
23#include "base/file_descriptor_posix.h"
24#endif
25
[email protected]abd97e422009-09-16 17:32:1126class FilePath;
27
[email protected]176aa482008-11-14 03:25:1528namespace base {
29
initial.commitd7cae122008-07-26 21:49:3830// SharedMemoryHandle is a platform specific type which represents
31// the underlying OS handle to a shared memory segment.
[email protected]39be4242008-08-07 18:31:4032#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3833typedef HANDLE SharedMemoryHandle;
34typedef HANDLE SharedMemoryLock;
[email protected]39be4242008-08-07 18:31:4035#elif defined(OS_POSIX)
[email protected]e68e62fa2009-02-20 02:00:0436// A SharedMemoryId is sufficient to identify a given shared memory segment on a
37// system, but insufficient to map it.
[email protected]5fe733de2009-02-11 18:59:2038typedef FileDescriptor SharedMemoryHandle;
[email protected]e68e62fa2009-02-20 02:00:0439typedef ino_t SharedMemoryId;
[email protected]ec031eb2009-02-05 19:04:3440// On POSIX, the lock is implemented as a lockf() on the mapped file,
41// so no additional member (or definition of SharedMemoryLock) is
42// needed.
initial.commitd7cae122008-07-26 21:49:3843#endif
44
[email protected]b05df6b2011-12-01 23:19:3145// Options for creating a shared memory object.
46struct SharedMemoryCreateOptions {
47 SharedMemoryCreateOptions() : name(NULL), size(0), open_existing(false),
48 executable(false) {}
49
50 // If NULL, the object is anonymous. This pointer is owned by the caller
51 // and must live through the call to Create().
52 const std::string* name;
53
54 // Size of the shared memory object to be created.
55 // When opening an existing object, this has no effect.
56 uint32 size;
57
58 // If true, and the shared memory already exists, Create() will open the
59 // existing shared memory and ignore the size parameter. If false,
60 // shared memory must not exist. This flag is meaningless unless name is
61 // non-NULL.
62 bool open_existing;
63
64 // If true, mappings might need to be made executable later.
65 bool executable;
66};
67
initial.commitd7cae122008-07-26 21:49:3868// Platform abstraction for shared memory. Provides a C++ wrapper
69// around the OS primitive for a memory mapped file.
[email protected]0bea7252011-08-05 15:34:0070class BASE_EXPORT SharedMemory {
initial.commitd7cae122008-07-26 21:49:3871 public:
initial.commitd7cae122008-07-26 21:49:3872 SharedMemory();
73
[email protected]8cc41942010-11-05 19:16:0774#if defined(OS_WIN)
75 // Similar to the default constructor, except that this allows for
76 // calling Lock() to acquire the named mutex before either Create or Open
77 // are called on Windows.
78 explicit SharedMemory(const std::wstring& name);
79#endif
80
initial.commitd7cae122008-07-26 21:49:3881 // Create a new SharedMemory object from an existing, open
82 // shared memory file.
83 SharedMemory(SharedMemoryHandle handle, bool read_only);
84
85 // Create a new SharedMemory object from an existing, open
86 // shared memory file that was created by a remote process and not shared
87 // to the current process.
88 SharedMemory(SharedMemoryHandle handle, bool read_only,
[email protected]b6128aa2010-04-29 17:44:4289 ProcessHandle process);
initial.commitd7cae122008-07-26 21:49:3890
[email protected]b6128aa2010-04-29 17:44:4291 // Closes any open files.
initial.commitd7cae122008-07-26 21:49:3892 ~SharedMemory();
93
[email protected]5fe733de2009-02-11 18:59:2094 // Return true iff the given handle is valid (i.e. not the distingished
95 // invalid value; NULL for a HANDLE and -1 for a file descriptor)
96 static bool IsHandleValid(const SharedMemoryHandle& handle);
97
[email protected]b6128aa2010-04-29 17:44:4298 // Returns invalid handle (see comment above for exact definition).
[email protected]76aac1e2009-03-16 16:45:3699 static SharedMemoryHandle NULLHandle();
100
[email protected]b6128aa2010-04-29 17:44:42101 // Closes a shared memory handle.
[email protected]b0af04c2009-05-18 17:46:31102 static void CloseHandle(const SharedMemoryHandle& handle);
103
[email protected]b05df6b2011-12-01 23:19:31104 // Creates a shared memory object as described by the options struct.
105 // Returns true on success and false on failure.
106 bool Create(const SharedMemoryCreateOptions& options);
107
[email protected]54e3dfa22010-10-27 18:16:06108 // Creates and maps an anonymous shared memory segment of size size.
109 // Returns true on success and false on failure.
110 bool CreateAndMapAnonymous(uint32 size);
111
112 // Creates an anonymous shared memory segment of size size.
113 // Returns true on success and false on failure.
[email protected]b05df6b2011-12-01 23:19:31114 bool CreateAnonymous(uint32 size) {
115 SharedMemoryCreateOptions options;
116 options.size = size;
117 return Create(options);
118 }
[email protected]54e3dfa22010-10-27 18:16:06119
initial.commitd7cae122008-07-26 21:49:38120 // Creates or opens a shared memory segment based on a name.
initial.commitd7cae122008-07-26 21:49:38121 // If open_existing is true, and the shared memory already exists,
122 // opens the existing shared memory and ignores the size parameter.
[email protected]54e3dfa22010-10-27 18:16:06123 // If open_existing is false, shared memory must not exist.
124 // size is the size of the block to be created.
initial.commitd7cae122008-07-26 21:49:38125 // Returns true on success, false on failure.
[email protected]b05df6b2011-12-01 23:19:31126 bool CreateNamed(const std::string& name, bool open_existing, uint32 size) {
127 SharedMemoryCreateOptions options;
128 options.name = &name;
129 options.open_existing = open_existing;
130 options.size = size;
131 return Create(options);
132 }
initial.commitd7cae122008-07-26 21:49:38133
[email protected]9e51af92009-02-04 00:58:39134 // Deletes resources associated with a shared memory segment based on name.
135 // Not all platforms require this call.
[email protected]b6413b49b2010-09-29 20:32:22136 bool Delete(const std::string& name);
[email protected]9e51af92009-02-04 00:58:39137
initial.commitd7cae122008-07-26 21:49:38138 // Opens a shared memory segment based on a name.
139 // If read_only is true, opens for read-only access.
140 // Returns true on success, false on failure.
[email protected]b6413b49b2010-09-29 20:32:22141 bool Open(const std::string& name, bool read_only);
initial.commitd7cae122008-07-26 21:49:38142
143 // Maps the shared memory into the caller's address space.
144 // Returns true on success, false otherwise. The memory address
[email protected]404a0582012-08-18 02:17:26145 // is accessed via the memory() accessor. The mapped address is guaranteed to
146 // have an alignment of at least MAP_MINIMUM_ALIGNMENT.
[email protected]b5ab3982010-02-16 23:58:27147 bool Map(uint32 bytes);
[email protected]404a0582012-08-18 02:17:26148 enum { MAP_MINIMUM_ALIGNMENT = 32 };
initial.commitd7cae122008-07-26 21:49:38149
150 // Unmaps the shared memory from the caller's address space.
151 // Returns true if successful; returns false on error or if the
152 // memory is not mapped.
153 bool Unmap();
154
[email protected]54e3dfa22010-10-27 18:16:06155 // Get the size of the shared memory backing file.
initial.commitd7cae122008-07-26 21:49:38156 // Note: This size is only available to the creator of the
157 // shared memory, and not to those that opened shared memory
158 // created externally.
[email protected]54e3dfa22010-10-27 18:16:06159 // Returns 0 if not created or unknown.
160 // Deprecated method, please keep track of the size yourself if you created
161 // it.
162 // http://crbug.com/60821
163 uint32 created_size() const { return created_size_; }
initial.commitd7cae122008-07-26 21:49:38164
165 // Gets a pointer to the opened memory space if it has been
166 // Mapped via Map(). Returns NULL if it is not mapped.
167 void *memory() const { return memory_; }
168
[email protected]b6128aa2010-04-29 17:44:42169 // Returns the underlying OS handle for this segment.
initial.commitd7cae122008-07-26 21:49:38170 // Use of this handle for anything other than an opaque
171 // identifier is not portable.
[email protected]5fe733de2009-02-11 18:59:20172 SharedMemoryHandle handle() const;
initial.commitd7cae122008-07-26 21:49:38173
[email protected]d600ce472012-07-16 20:04:11174#if defined(OS_POSIX) && !defined(OS_NACL)
[email protected]b6128aa2010-04-29 17:44:42175 // Returns a unique identifier for this shared memory segment. Inode numbers
[email protected]e68e62fa2009-02-20 02:00:04176 // are technically only unique to a single filesystem. However, we always
177 // allocate shared memory backing files from the same directory, so will end
178 // up on the same filesystem.
179 SharedMemoryId id() const { return inode_; }
180#endif
181
initial.commitd7cae122008-07-26 21:49:38182 // Closes the open shared memory segment.
183 // It is safe to call Close repeatedly.
184 void Close();
185
[email protected]b6128aa2010-04-29 17:44:42186 // Shares the shared memory to another process. Attempts
initial.commitd7cae122008-07-26 21:49:38187 // to create a platform-specific new_handle which can be
188 // used in a remote process to access the shared memory
189 // file. new_handle is an ouput parameter to receive
190 // the handle for use in the remote process.
191 // Returns true on success, false otherwise.
[email protected]b6128aa2010-04-29 17:44:42192 bool ShareToProcess(ProcessHandle process,
[email protected]de5abb92008-10-22 21:33:27193 SharedMemoryHandle* new_handle) {
initial.commitd7cae122008-07-26 21:49:38194 return ShareToProcessCommon(process, new_handle, false);
195 }
196
197 // Logically equivalent to:
198 // bool ok = ShareToProcess(process, new_handle);
199 // Close();
200 // return ok;
[email protected]ed1f53e2009-02-11 01:32:58201 // Note that the memory is unmapped by calling this method, regardless of the
202 // return value.
initial.commitd7cae122008-07-26 21:49:38203 bool GiveToProcess(ProcessHandle process,
[email protected]de5abb92008-10-22 21:33:27204 SharedMemoryHandle* new_handle) {
initial.commitd7cae122008-07-26 21:49:38205 return ShareToProcessCommon(process, new_handle, true);
206 }
207
[email protected]b6128aa2010-04-29 17:44:42208 // Locks the shared memory.
[email protected]a0c136a02012-02-25 06:28:56209 //
210 // WARNING: on POSIX the memory locking primitive only works across
211 // processes, not across threads. The Lock method is not currently
212 // used in inner loops, so we protect against multiple threads in a
213 // critical section using a class global lock.
initial.commitd7cae122008-07-26 21:49:38214 void Lock();
215
[email protected]8cc41942010-11-05 19:16:07216#if defined(OS_WIN)
[email protected]42155162010-11-16 14:25:03217 // A Lock() implementation with a timeout that also allows setting
218 // security attributes on the mutex. sec_attr may be NULL.
219 // Returns true if the Lock() has been acquired, false if the timeout was
220 // reached.
221 bool Lock(uint32 timeout_ms, SECURITY_ATTRIBUTES* sec_attr);
[email protected]8cc41942010-11-05 19:16:07222#endif
223
[email protected]b6128aa2010-04-29 17:44:42224 // Releases the shared memory lock.
initial.commitd7cae122008-07-26 21:49:38225 void Unlock();
226
227 private:
[email protected]d600ce472012-07-16 20:04:11228#if defined(OS_POSIX) && !defined(OS_NACL)
[email protected]54e3dfa22010-10-27 18:16:06229 bool PrepareMapFile(FILE *fp);
[email protected]b6413b49b2010-09-29 20:32:22230 bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
[email protected]ec031eb2009-02-05 19:04:34231 void LockOrUnlockCommon(int function);
[email protected]cba5d982008-08-13 19:59:07232#endif
initial.commitd7cae122008-07-26 21:49:38233 bool ShareToProcessCommon(ProcessHandle process,
[email protected]de5abb92008-10-22 21:33:27234 SharedMemoryHandle* new_handle,
235 bool close_self);
initial.commitd7cae122008-07-26 21:49:38236
[email protected]5fe733de2009-02-11 18:59:20237#if defined(OS_WIN)
[email protected]f25810a2009-04-04 00:44:22238 std::wstring name_;
[email protected]e68e62fa2009-02-20 02:00:04239 HANDLE mapped_file_;
[email protected]5fe733de2009-02-11 18:59:20240#elif defined(OS_POSIX)
[email protected]e68e62fa2009-02-20 02:00:04241 int mapped_file_;
[email protected]54e3dfa22010-10-27 18:16:06242 uint32 mapped_size_;
[email protected]e68e62fa2009-02-20 02:00:04243 ino_t inode_;
[email protected]5fe733de2009-02-11 18:59:20244#endif
initial.commitd7cae122008-07-26 21:49:38245 void* memory_;
246 bool read_only_;
[email protected]54e3dfa22010-10-27 18:16:06247 uint32 created_size_;
[email protected]ec031eb2009-02-05 19:04:34248#if !defined(OS_POSIX)
initial.commitd7cae122008-07-26 21:49:38249 SharedMemoryLock lock_;
[email protected]9e51af92009-02-04 00:58:39250#endif
initial.commitd7cae122008-07-26 21:49:38251
[email protected]fc29bc702010-06-04 16:13:51252 DISALLOW_COPY_AND_ASSIGN(SharedMemory);
initial.commitd7cae122008-07-26 21:49:38253};
254
255// A helper class that acquires the shared memory lock while
256// the SharedMemoryAutoLock is in scope.
257class SharedMemoryAutoLock {
258 public:
259 explicit SharedMemoryAutoLock(SharedMemory* shared_memory)
260 : shared_memory_(shared_memory) {
261 shared_memory_->Lock();
262 }
263
264 ~SharedMemoryAutoLock() {
265 shared_memory_->Unlock();
266 }
267
268 private:
269 SharedMemory* shared_memory_;
[email protected]fc29bc702010-06-04 16:13:51270 DISALLOW_COPY_AND_ASSIGN(SharedMemoryAutoLock);
initial.commitd7cae122008-07-26 21:49:38271};
272
[email protected]176aa482008-11-14 03:25:15273} // namespace base
initial.commitd7cae122008-07-26 21:49:38274
[email protected]39be4242008-08-07 18:31:40275#endif // BASE_SHARED_MEMORY_H_