• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
6 #define BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
7 
8 #include <stddef.h>
9 
10 #include "build/build_config.h"
11 
12 #if defined(OS_WIN)
13 #include <windows.h>
14 #include "base/process/process_handle.h"
15 #elif defined(OS_MACOSX) && !defined(OS_IOS)
16 #include <mach/mach.h>
17 #include "base/base_export.h"
18 #include "base/file_descriptor_posix.h"
19 #include "base/macros.h"
20 #include "base/process/process_handle.h"
21 #elif defined(OS_POSIX)
22 #include <sys/types.h>
23 #include "base/file_descriptor_posix.h"
24 #endif
25 
26 namespace base {
27 
28 // SharedMemoryHandle is a platform specific type which represents
29 // the underlying OS handle to a shared memory segment.
30 #if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS))
31 typedef FileDescriptor SharedMemoryHandle;
32 #elif defined(OS_WIN)
33 class BASE_EXPORT SharedMemoryHandle {
34  public:
35   // The default constructor returns an invalid SharedMemoryHandle.
36   SharedMemoryHandle();
37   SharedMemoryHandle(HANDLE h, base::ProcessId pid);
38 
39   // Standard copy constructor. The new instance shares the underlying OS
40   // primitives.
41   SharedMemoryHandle(const SharedMemoryHandle& handle);
42 
43   // Standard assignment operator. The updated instance shares the underlying
44   // OS primitives.
45   SharedMemoryHandle& operator=(const SharedMemoryHandle& handle);
46 
47   // Comparison operators.
48   bool operator==(const SharedMemoryHandle& handle) const;
49   bool operator!=(const SharedMemoryHandle& handle) const;
50 
51   // Closes the underlying OS resources.
52   void Close() const;
53 
54   // Whether the underlying OS primitive is valid.
55   bool IsValid() const;
56 
57   // Whether |pid_| is the same as the current process's id.
58   bool BelongsToCurrentProcess() const;
59 
60   // Whether handle_ needs to be duplicated into the destination process when
61   // an instance of this class is passed over a Chrome IPC channel.
62   bool NeedsBrokering() const;
63 
64   void SetOwnershipPassesToIPC(bool ownership_passes);
65   bool OwnershipPassesToIPC() const;
66 
67   HANDLE GetHandle() const;
68   base::ProcessId GetPID() const;
69 
70  private:
71   HANDLE handle_;
72 
73   // The process in which |handle_| is valid and can be used. If |handle_| is
74   // invalid, this will be kNullProcessId.
75   base::ProcessId pid_;
76 
77   // Whether passing this object as a parameter to an IPC message passes
78   // ownership of |handle_| to the IPC stack. This is meant to mimic the
79   // behavior of the |auto_close| parameter of FileDescriptor. This member only
80   // affects attachment-brokered SharedMemoryHandles.
81   // Defaults to |false|.
82   bool ownership_passes_to_ipc_;
83 };
84 #else
85 class BASE_EXPORT SharedMemoryHandle {
86  public:
87   enum Type {
88     // The SharedMemoryHandle is backed by a POSIX fd.
89     POSIX,
90     // The SharedMemoryHandle is backed by the Mach primitive "memory object".
91     MACH,
92   };
93 
94   // The default constructor returns an invalid SharedMemoryHandle.
95   SharedMemoryHandle();
96 
97   // Constructs a SharedMemoryHandle backed by the components of a
98   // FileDescriptor. The newly created instance has the same ownership semantics
99   // as base::FileDescriptor. This typically means that the SharedMemoryHandle
100   // takes ownership of the |fd| if |auto_close| is true. Unfortunately, it's
101   // common for existing code to make shallow copies of SharedMemoryHandle, and
102   // the one that is finally passed into a base::SharedMemory is the one that
103   // "consumes" the fd.
104   explicit SharedMemoryHandle(const base::FileDescriptor& file_descriptor);
105 
106   // Makes a Mach-based SharedMemoryHandle of the given size. On error,
107   // subsequent calls to IsValid() return false.
108   explicit SharedMemoryHandle(mach_vm_size_t size);
109 
110   // Makes a Mach-based SharedMemoryHandle from |memory_object|, a named entry
111   // in the task with process id |pid|. The memory region has size |size|.
112   SharedMemoryHandle(mach_port_t memory_object,
113                      mach_vm_size_t size,
114                      base::ProcessId pid);
115 
116   // Standard copy constructor. The new instance shares the underlying OS
117   // primitives.
118   SharedMemoryHandle(const SharedMemoryHandle& handle);
119 
120   // Standard assignment operator. The updated instance shares the underlying
121   // OS primitives.
122   SharedMemoryHandle& operator=(const SharedMemoryHandle& handle);
123 
124   // Duplicates the underlying OS resources.
125   SharedMemoryHandle Duplicate() const;
126 
127   // Comparison operators.
128   bool operator==(const SharedMemoryHandle& handle) const;
129   bool operator!=(const SharedMemoryHandle& handle) const;
130 
131   // Whether the underlying OS primitive is valid. Once the SharedMemoryHandle
132   // is backed by a valid OS primitive, it becomes immutable.
133   bool IsValid() const;
134 
135   // Exposed so that the SharedMemoryHandle can be transported between
136   // processes.
137   mach_port_t GetMemoryObject() const;
138 
139   // Returns false on a failure to determine the size. On success, populates the
140   // output variable |size|.
141   bool GetSize(size_t* size) const;
142 
143   // The SharedMemoryHandle must be valid.
144   // Returns whether the SharedMemoryHandle was successfully mapped into memory.
145   // On success, |memory| is an output variable that contains the start of the
146   // mapped memory.
147   bool MapAt(off_t offset, size_t bytes, void** memory, bool read_only);
148 
149   // Closes the underlying OS primitive.
150   void Close() const;
151 
152   void SetOwnershipPassesToIPC(bool ownership_passes);
153   bool OwnershipPassesToIPC() const;
154 
155  private:
156   friend class SharedMemory;
157 
158   // Shared code between copy constructor and operator=.
159   void CopyRelevantData(const SharedMemoryHandle& handle);
160 
161   Type type_;
162 
163   // Each instance of a SharedMemoryHandle is backed either by a POSIX fd or a
164   // mach port. |type_| determines the backing member.
165   union {
166     FileDescriptor file_descriptor_;
167 
168     struct {
169       mach_port_t memory_object_;
170 
171       // The size of the shared memory region when |type_| is MACH. Only
172       // relevant if |memory_object_| is not |MACH_PORT_NULL|.
173       mach_vm_size_t size_;
174 
175       // The pid of the process in which |memory_object_| is usable. Only
176       // relevant if |memory_object_| is not |MACH_PORT_NULL|.
177       base::ProcessId pid_;
178 
179       // Whether passing this object as a parameter to an IPC message passes
180       // ownership of |memory_object_| to the IPC stack. This is meant to mimic
181       // the behavior of the |auto_close| parameter of FileDescriptor.
182       // Defaults to |false|.
183       bool ownership_passes_to_ipc_;
184     };
185   };
186 };
187 #endif
188 
189 }  // namespace base
190 
191 #endif  // BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
192