blob: 8cb27ecd2ee4bd8caf7db337dfe4cd56e96420d0 [file] [log] [blame]
[email protected]90509cb2011-03-25 18:46:381// Copyright (c) 2011 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_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commitd7cae122008-07-26 21:49:388
[email protected]5425c682008-11-14 20:08:029#include "build/build_config.h"
10
11#if defined(OS_POSIX)
[email protected]e68e62fa2009-02-20 02:00:0412#include <sys/types.h>
[email protected]5425c682008-11-14 20:08:0213#include <semaphore.h>
[email protected]5fe733de2009-02-11 18:59:2014#include "base/file_descriptor_posix.h"
[email protected]5425c682008-11-14 20:08:0215#endif
[email protected]de5abb92008-10-22 21:33:2716#include <string>
[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]abd97e422009-09-16 17:32:1122class FilePath;
23
[email protected]176aa482008-11-14 03:25:1524namespace base {
25
initial.commitd7cae122008-07-26 21:49:3826// SharedMemoryHandle is a platform specific type which represents
27// the underlying OS handle to a shared memory segment.
[email protected]39be4242008-08-07 18:31:4028#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3829typedef HANDLE SharedMemoryHandle;
30typedef HANDLE SharedMemoryLock;
[email protected]39be4242008-08-07 18:31:4031#elif defined(OS_POSIX)
[email protected]e68e62fa2009-02-20 02:00:0432// A SharedMemoryId is sufficient to identify a given shared memory segment on a
33// system, but insufficient to map it.
[email protected]5fe733de2009-02-11 18:59:2034typedef FileDescriptor SharedMemoryHandle;
[email protected]e68e62fa2009-02-20 02:00:0435typedef ino_t SharedMemoryId;
[email protected]ec031eb2009-02-05 19:04:3436// On POSIX, the lock is implemented as a lockf() on the mapped file,
37// so no additional member (or definition of SharedMemoryLock) is
38// needed.
initial.commitd7cae122008-07-26 21:49:3839#endif
40
[email protected]b05df6b2011-12-01 23:19:3141// Options for creating a shared memory object.
42struct SharedMemoryCreateOptions {
43 SharedMemoryCreateOptions() : name(NULL), size(0), open_existing(false),
44 executable(false) {}
45
46 // If NULL, the object is anonymous. This pointer is owned by the caller
47 // and must live through the call to Create().
48 const std::string* name;
49
50 // Size of the shared memory object to be created.
51 // When opening an existing object, this has no effect.
52 uint32 size;
53
54 // If true, and the shared memory already exists, Create() will open the
55 // existing shared memory and ignore the size parameter. If false,
56 // shared memory must not exist. This flag is meaningless unless name is
57 // non-NULL.
58 bool open_existing;
59
60 // If true, mappings might need to be made executable later.
61 bool executable;
62};
63
initial.commitd7cae122008-07-26 21:49:3864// Platform abstraction for shared memory. Provides a C++ wrapper
65// around the OS primitive for a memory mapped file.
[email protected]0bea7252011-08-05 15:34:0066class BASE_EXPORT SharedMemory {
initial.commitd7cae122008-07-26 21:49:3867 public:
initial.commitd7cae122008-07-26 21:49:3868 SharedMemory();
69
[email protected]8cc41942010-11-05 19:16:0770#if defined(OS_WIN)
71 // Similar to the default constructor, except that this allows for
72 // calling Lock() to acquire the named mutex before either Create or Open
73 // are called on Windows.
74 explicit SharedMemory(const std::wstring& name);
75#endif
76
initial.commitd7cae122008-07-26 21:49:3877 // Create a new SharedMemory object from an existing, open
78 // shared memory file.
79 SharedMemory(SharedMemoryHandle handle, bool read_only);
80
81 // Create a new SharedMemory object from an existing, open
82 // shared memory file that was created by a remote process and not shared
83 // to the current process.
84 SharedMemory(SharedMemoryHandle handle, bool read_only,
[email protected]b6128aa2010-04-29 17:44:4285 ProcessHandle process);
initial.commitd7cae122008-07-26 21:49:3886
[email protected]b6128aa2010-04-29 17:44:4287 // Closes any open files.
initial.commitd7cae122008-07-26 21:49:3888 ~SharedMemory();
89
[email protected]5fe733de2009-02-11 18:59:2090 // Return true iff the given handle is valid (i.e. not the distingished
91 // invalid value; NULL for a HANDLE and -1 for a file descriptor)
92 static bool IsHandleValid(const SharedMemoryHandle& handle);
93
[email protected]b6128aa2010-04-29 17:44:4294 // Returns invalid handle (see comment above for exact definition).
[email protected]76aac1e2009-03-16 16:45:3695 static SharedMemoryHandle NULLHandle();
96
[email protected]b6128aa2010-04-29 17:44:4297 // Closes a shared memory handle.
[email protected]b0af04c2009-05-18 17:46:3198 static void CloseHandle(const SharedMemoryHandle& handle);
99
[email protected]b05df6b2011-12-01 23:19:31100 // Creates a shared memory object as described by the options struct.
101 // Returns true on success and false on failure.
102 bool Create(const SharedMemoryCreateOptions& options);
103
[email protected]54e3dfa22010-10-27 18:16:06104 // Creates and maps an anonymous shared memory segment of size size.
105 // Returns true on success and false on failure.
106 bool CreateAndMapAnonymous(uint32 size);
107
108 // Creates an anonymous shared memory segment of size size.
109 // Returns true on success and false on failure.
[email protected]b05df6b2011-12-01 23:19:31110 bool CreateAnonymous(uint32 size) {
111 SharedMemoryCreateOptions options;
112 options.size = size;
113 return Create(options);
114 }
[email protected]54e3dfa22010-10-27 18:16:06115
initial.commitd7cae122008-07-26 21:49:38116 // Creates or opens a shared memory segment based on a name.
initial.commitd7cae122008-07-26 21:49:38117 // If open_existing is true, and the shared memory already exists,
118 // opens the existing shared memory and ignores the size parameter.
[email protected]54e3dfa22010-10-27 18:16:06119 // If open_existing is false, shared memory must not exist.
120 // size is the size of the block to be created.
initial.commitd7cae122008-07-26 21:49:38121 // Returns true on success, false on failure.
[email protected]b05df6b2011-12-01 23:19:31122 bool CreateNamed(const std::string& name, bool open_existing, uint32 size) {
123 SharedMemoryCreateOptions options;
124 options.name = &name;
125 options.open_existing = open_existing;
126 options.size = size;
127 return Create(options);
128 }
initial.commitd7cae122008-07-26 21:49:38129
[email protected]9e51af92009-02-04 00:58:39130 // Deletes resources associated with a shared memory segment based on name.
131 // Not all platforms require this call.
[email protected]b6413b49b2010-09-29 20:32:22132 bool Delete(const std::string& name);
[email protected]9e51af92009-02-04 00:58:39133
initial.commitd7cae122008-07-26 21:49:38134 // Opens a shared memory segment based on a name.
135 // If read_only is true, opens for read-only access.
136 // Returns true on success, false on failure.
[email protected]b6413b49b2010-09-29 20:32:22137 bool Open(const std::string& name, bool read_only);
initial.commitd7cae122008-07-26 21:49:38138
139 // Maps the shared memory into the caller's address space.
140 // Returns true on success, false otherwise. The memory address
141 // is accessed via the memory() accessor.
[email protected]b5ab3982010-02-16 23:58:27142 bool Map(uint32 bytes);
initial.commitd7cae122008-07-26 21:49:38143
144 // Unmaps the shared memory from the caller's address space.
145 // Returns true if successful; returns false on error or if the
146 // memory is not mapped.
147 bool Unmap();
148
[email protected]54e3dfa22010-10-27 18:16:06149 // Get the size of the shared memory backing file.
initial.commitd7cae122008-07-26 21:49:38150 // Note: This size is only available to the creator of the
151 // shared memory, and not to those that opened shared memory
152 // created externally.
[email protected]54e3dfa22010-10-27 18:16:06153 // Returns 0 if not created or unknown.
154 // Deprecated method, please keep track of the size yourself if you created
155 // it.
156 // http://crbug.com/60821
157 uint32 created_size() const { return created_size_; }
initial.commitd7cae122008-07-26 21:49:38158
159 // Gets a pointer to the opened memory space if it has been
160 // Mapped via Map(). Returns NULL if it is not mapped.
161 void *memory() const { return memory_; }
162
[email protected]b6128aa2010-04-29 17:44:42163 // Returns the underlying OS handle for this segment.
initial.commitd7cae122008-07-26 21:49:38164 // Use of this handle for anything other than an opaque
165 // identifier is not portable.
[email protected]5fe733de2009-02-11 18:59:20166 SharedMemoryHandle handle() const;
initial.commitd7cae122008-07-26 21:49:38167
[email protected]e68e62fa2009-02-20 02:00:04168#if defined(OS_POSIX)
[email protected]b6128aa2010-04-29 17:44:42169 // Returns a unique identifier for this shared memory segment. Inode numbers
[email protected]e68e62fa2009-02-20 02:00:04170 // are technically only unique to a single filesystem. However, we always
171 // allocate shared memory backing files from the same directory, so will end
172 // up on the same filesystem.
173 SharedMemoryId id() const { return inode_; }
174#endif
175
initial.commitd7cae122008-07-26 21:49:38176 // Closes the open shared memory segment.
177 // It is safe to call Close repeatedly.
178 void Close();
179
[email protected]b6128aa2010-04-29 17:44:42180 // Shares the shared memory to another process. Attempts
initial.commitd7cae122008-07-26 21:49:38181 // to create a platform-specific new_handle which can be
182 // used in a remote process to access the shared memory
183 // file. new_handle is an ouput parameter to receive
184 // the handle for use in the remote process.
185 // Returns true on success, false otherwise.
[email protected]b6128aa2010-04-29 17:44:42186 bool ShareToProcess(ProcessHandle process,
[email protected]de5abb92008-10-22 21:33:27187 SharedMemoryHandle* new_handle) {
initial.commitd7cae122008-07-26 21:49:38188 return ShareToProcessCommon(process, new_handle, false);
189 }
190
191 // Logically equivalent to:
192 // bool ok = ShareToProcess(process, new_handle);
193 // Close();
194 // return ok;
[email protected]ed1f53e2009-02-11 01:32:58195 // Note that the memory is unmapped by calling this method, regardless of the
196 // return value.
initial.commitd7cae122008-07-26 21:49:38197 bool GiveToProcess(ProcessHandle process,
[email protected]de5abb92008-10-22 21:33:27198 SharedMemoryHandle* new_handle) {
initial.commitd7cae122008-07-26 21:49:38199 return ShareToProcessCommon(process, new_handle, true);
200 }
201
[email protected]b6128aa2010-04-29 17:44:42202 // Locks the shared memory.
initial.commitd7cae122008-07-26 21:49:38203 // This is a cross-process lock which may be recursively
204 // locked by the same thread.
[email protected]ec031eb2009-02-05 19:04:34205 // TODO(port):
206 // WARNING: on POSIX the lock only works across processes, not
207 // across threads. 2 threads in the same process can both grab the
208 // lock at the same time. There are several solutions for this
209 // (futex, lockf+anon_semaphore) but none are both clean and common
210 // across Mac and Linux.
initial.commitd7cae122008-07-26 21:49:38211 void Lock();
212
[email protected]8cc41942010-11-05 19:16:07213#if defined(OS_WIN)
[email protected]42155162010-11-16 14:25:03214 // A Lock() implementation with a timeout that also allows setting
215 // security attributes on the mutex. sec_attr may be NULL.
216 // Returns true if the Lock() has been acquired, false if the timeout was
217 // reached.
218 bool Lock(uint32 timeout_ms, SECURITY_ATTRIBUTES* sec_attr);
[email protected]8cc41942010-11-05 19:16:07219#endif
220
[email protected]b6128aa2010-04-29 17:44:42221 // Releases the shared memory lock.
initial.commitd7cae122008-07-26 21:49:38222 void Unlock();
223
224 private:
[email protected]cba5d982008-08-13 19:59:07225#if defined(OS_POSIX)
[email protected]54e3dfa22010-10-27 18:16:06226 bool PrepareMapFile(FILE *fp);
[email protected]b6413b49b2010-09-29 20:32:22227 bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
[email protected]ec031eb2009-02-05 19:04:34228 void LockOrUnlockCommon(int function);
[email protected]cba5d982008-08-13 19:59:07229#endif
initial.commitd7cae122008-07-26 21:49:38230 bool ShareToProcessCommon(ProcessHandle process,
[email protected]de5abb92008-10-22 21:33:27231 SharedMemoryHandle* new_handle,
232 bool close_self);
initial.commitd7cae122008-07-26 21:49:38233
[email protected]5fe733de2009-02-11 18:59:20234#if defined(OS_WIN)
[email protected]f25810a2009-04-04 00:44:22235 std::wstring name_;
[email protected]e68e62fa2009-02-20 02:00:04236 HANDLE mapped_file_;
[email protected]5fe733de2009-02-11 18:59:20237#elif defined(OS_POSIX)
[email protected]e68e62fa2009-02-20 02:00:04238 int mapped_file_;
[email protected]54e3dfa22010-10-27 18:16:06239 uint32 mapped_size_;
[email protected]e68e62fa2009-02-20 02:00:04240 ino_t inode_;
[email protected]5fe733de2009-02-11 18:59:20241#endif
initial.commitd7cae122008-07-26 21:49:38242 void* memory_;
243 bool read_only_;
[email protected]54e3dfa22010-10-27 18:16:06244 uint32 created_size_;
[email protected]ec031eb2009-02-05 19:04:34245#if !defined(OS_POSIX)
initial.commitd7cae122008-07-26 21:49:38246 SharedMemoryLock lock_;
[email protected]9e51af92009-02-04 00:58:39247#endif
initial.commitd7cae122008-07-26 21:49:38248
[email protected]fc29bc702010-06-04 16:13:51249 DISALLOW_COPY_AND_ASSIGN(SharedMemory);
initial.commitd7cae122008-07-26 21:49:38250};
251
252// A helper class that acquires the shared memory lock while
253// the SharedMemoryAutoLock is in scope.
254class SharedMemoryAutoLock {
255 public:
256 explicit SharedMemoryAutoLock(SharedMemory* shared_memory)
257 : shared_memory_(shared_memory) {
258 shared_memory_->Lock();
259 }
260
261 ~SharedMemoryAutoLock() {
262 shared_memory_->Unlock();
263 }
264
265 private:
266 SharedMemory* shared_memory_;
[email protected]fc29bc702010-06-04 16:13:51267 DISALLOW_COPY_AND_ASSIGN(SharedMemoryAutoLock);
initial.commitd7cae122008-07-26 21:49:38268};
269
[email protected]176aa482008-11-14 03:25:15270} // namespace base
initial.commitd7cae122008-07-26 21:49:38271
[email protected]39be4242008-08-07 18:31:40272#endif // BASE_SHARED_MEMORY_H_