rev |
line source |
nuclear@0
|
1 /************************************************************************************
|
nuclear@0
|
2
|
nuclear@0
|
3 PublicHeader: OVR
|
nuclear@0
|
4 Filename : OVR_SharedMemory.h
|
nuclear@0
|
5 Content : Inter-process shared memory subsystem
|
nuclear@0
|
6 Created : June 1, 2014
|
nuclear@0
|
7 Notes :
|
nuclear@0
|
8
|
nuclear@0
|
9 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
|
nuclear@0
|
10
|
nuclear@0
|
11 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
|
nuclear@0
|
12 you may not use the Oculus VR Rift SDK except in compliance with the License,
|
nuclear@0
|
13 which is provided at the time of installation or download, or which
|
nuclear@0
|
14 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@0
|
15
|
nuclear@0
|
16 You may obtain a copy of the License at
|
nuclear@0
|
17
|
nuclear@0
|
18 http://www.oculusvr.com/licenses/LICENSE-3.2
|
nuclear@0
|
19
|
nuclear@0
|
20 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
nuclear@0
|
21 distributed under the License is distributed on an "AS IS" BASIS,
|
nuclear@0
|
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
nuclear@0
|
23 See the License for the specific language governing permissions and
|
nuclear@0
|
24 limitations under the License.
|
nuclear@0
|
25
|
nuclear@0
|
26 ************************************************************************************/
|
nuclear@0
|
27
|
nuclear@0
|
28 #ifndef OVR_SharedMemory_h
|
nuclear@0
|
29 #define OVR_SharedMemory_h
|
nuclear@0
|
30
|
nuclear@0
|
31 #include "OVR_Types.h"
|
nuclear@0
|
32 #include "OVR_RefCount.h"
|
nuclear@0
|
33 #include "OVR_Allocator.h"
|
nuclear@0
|
34 #include "OVR_System.h"
|
nuclear@0
|
35
|
nuclear@0
|
36 #ifdef OVR_SINGLE_PROCESS /* Everything running in one process usually for debugging */
|
nuclear@0
|
37 #define OVR_FAKE_SHAREDMEMORY /* Single-process version to avoid admin privs */
|
nuclear@0
|
38 #endif
|
nuclear@0
|
39
|
nuclear@0
|
40 namespace OVR {
|
nuclear@0
|
41
|
nuclear@0
|
42 class SharedMemoryInternal; // Opaque
|
nuclear@0
|
43
|
nuclear@0
|
44
|
nuclear@0
|
45 // SharedMemory
|
nuclear@0
|
46 // Note: Safe when used between 32-bit and 64-bit processes
|
nuclear@0
|
47 class SharedMemory : public RefCountBase<SharedMemory>
|
nuclear@0
|
48 {
|
nuclear@0
|
49 friend class SharedMemoryFactory;
|
nuclear@0
|
50
|
nuclear@0
|
51 OVR_NON_COPYABLE(SharedMemory);
|
nuclear@0
|
52
|
nuclear@0
|
53 public:
|
nuclear@0
|
54 // Only constructed by the SharedMemory Factory
|
nuclear@0
|
55 SharedMemory(int size, void* data, SharedMemoryInternal* pInternal);
|
nuclear@0
|
56 // Call close when it goes out of scope
|
nuclear@0
|
57 ~SharedMemory();
|
nuclear@0
|
58
|
nuclear@0
|
59 // Modes for opening a new shared memory region
|
nuclear@0
|
60 enum OpenMode
|
nuclear@0
|
61 {
|
nuclear@0
|
62 // Note: On Windows, Create* requires Administrator priviledges or running as a Service.
|
nuclear@0
|
63 OpenMode_CreateOnly, // Must not already exist
|
nuclear@0
|
64 OpenMode_OpenOnly, // Must already exist
|
nuclear@0
|
65 OpenMode_CreateOrOpen // May exist or not
|
nuclear@0
|
66 };
|
nuclear@0
|
67
|
nuclear@0
|
68 // Local access restrictions
|
nuclear@0
|
69 enum AccessMode
|
nuclear@0
|
70 {
|
nuclear@0
|
71 AccessMode_ReadOnly, // Acquire read-only access
|
nuclear@0
|
72 AccessMode_ReadWrite, // Acquire read or write access
|
nuclear@0
|
73 };
|
nuclear@0
|
74
|
nuclear@0
|
75 // Remote access restrictions
|
nuclear@0
|
76 enum RemoteMode
|
nuclear@0
|
77 {
|
nuclear@0
|
78 RemoteMode_ReadOnly, // Other processes will need to open in read-only mode
|
nuclear@0
|
79 RemoteMode_ReadWrite // Other processes can open in read-write mode
|
nuclear@0
|
80 };
|
nuclear@0
|
81
|
nuclear@0
|
82 // Modes for opening a new shared memory region
|
nuclear@0
|
83 struct OpenParameters
|
nuclear@0
|
84 {
|
nuclear@0
|
85 OpenParameters() :
|
nuclear@0
|
86 globalName(NULL),
|
nuclear@0
|
87 minSizeBytes(0),
|
nuclear@0
|
88 openMode(SharedMemory::OpenMode_CreateOrOpen),
|
nuclear@0
|
89 remoteMode(SharedMemory::RemoteMode_ReadWrite),
|
nuclear@0
|
90 accessMode(SharedMemory::AccessMode_ReadWrite)
|
nuclear@0
|
91 {
|
nuclear@0
|
92 }
|
nuclear@0
|
93
|
nuclear@0
|
94 // Creation parameters
|
nuclear@0
|
95 const char* globalName; // Name of the shared memory region
|
nuclear@0
|
96 int minSizeBytes; // Minimum number of bytes to request
|
nuclear@0
|
97 SharedMemory::OpenMode openMode; // Creating the file or opening the file?
|
nuclear@0
|
98 SharedMemory::RemoteMode remoteMode; // When creating, what access should other processes get?
|
nuclear@0
|
99 SharedMemory::AccessMode accessMode; // When opening/creating, what access should this process get?
|
nuclear@0
|
100 };
|
nuclear@0
|
101
|
nuclear@0
|
102 public:
|
nuclear@0
|
103 // Returns the size of the shared memory region
|
nuclear@0
|
104 int GetSizeI() const
|
nuclear@0
|
105 {
|
nuclear@0
|
106 return Size;
|
nuclear@0
|
107 }
|
nuclear@0
|
108
|
nuclear@0
|
109 // Returns the process-local pointer to the shared memory region
|
nuclear@0
|
110 // Note: This may be different on different processes
|
nuclear@0
|
111 void* GetData() const
|
nuclear@0
|
112 {
|
nuclear@0
|
113 return Data;
|
nuclear@0
|
114 }
|
nuclear@0
|
115
|
nuclear@0
|
116 protected:
|
nuclear@0
|
117 int Size; // How many shared bytes are shared at the pointer address?
|
nuclear@0
|
118 void* Data; // Pointer to the shared memory region.
|
nuclear@0
|
119
|
nuclear@0
|
120 // Hidden implementation class for OS-specific behavior
|
nuclear@0
|
121 SharedMemoryInternal* Internal;
|
nuclear@0
|
122
|
nuclear@0
|
123 // Close and cleanup the shared memory region
|
nuclear@0
|
124 // Note: This is called on destruction
|
nuclear@0
|
125 void Close();
|
nuclear@0
|
126 };
|
nuclear@0
|
127
|
nuclear@0
|
128
|
nuclear@0
|
129 // SharedMemoryFactory
|
nuclear@0
|
130 class SharedMemoryFactory : public NewOverrideBase, public SystemSingletonBase<SharedMemoryFactory>
|
nuclear@0
|
131 {
|
nuclear@0
|
132 OVR_DECLARE_SINGLETON(SharedMemoryFactory);
|
nuclear@0
|
133
|
nuclear@0
|
134 public:
|
nuclear@0
|
135 // Construct a SharedMemory object.
|
nuclear@0
|
136 // Note: The new object is reference-counted so it should be stored with Ptr<>. Initial reference count is 1.
|
nuclear@0
|
137 Ptr<SharedMemory> Open(const SharedMemory::OpenParameters&);
|
nuclear@0
|
138 };
|
nuclear@0
|
139
|
nuclear@0
|
140
|
nuclear@0
|
141 // A shared object
|
nuclear@0
|
142 // Its constructor will be called when creating a writer
|
nuclear@0
|
143 // Its destructor will not be called
|
nuclear@0
|
144 template<class SharedType>
|
nuclear@0
|
145 class ISharedObject : public NewOverrideBase
|
nuclear@0
|
146 {
|
nuclear@0
|
147 public:
|
nuclear@0
|
148 static const int RegionSize = (int)sizeof(SharedType);
|
nuclear@0
|
149
|
nuclear@0
|
150 protected:
|
nuclear@0
|
151 Ptr<SharedMemory> pSharedMemory;
|
nuclear@0
|
152
|
nuclear@0
|
153 bool Open(const char* name, bool readOnly)
|
nuclear@0
|
154 {
|
nuclear@0
|
155 // Configure open parameters based on read-only mode
|
nuclear@0
|
156 SharedMemory::OpenParameters params;
|
nuclear@0
|
157
|
nuclear@0
|
158 // FIXME: This is a hack. We currently need to allow clients to open this for read-write even
|
nuclear@0
|
159 // though they only need read-only access. This is because in the first 0.4 release the
|
nuclear@0
|
160 // LocklessUpdater class technically writes to it (increments by 0) to read from the space.
|
nuclear@0
|
161 // This was quickly corrected in 0.4.1 and we are waiting for the right time to disallow write
|
nuclear@0
|
162 // access when everyone upgrades to 0.4.1+.
|
nuclear@0
|
163 //params.remoteMode = SharedMemory::RemoteMode_ReadOnly;
|
nuclear@0
|
164 params.remoteMode = SharedMemory::RemoteMode_ReadWrite;
|
nuclear@0
|
165
|
nuclear@0
|
166 params.globalName = name;
|
nuclear@0
|
167 params.accessMode = readOnly ? SharedMemory::AccessMode_ReadOnly : SharedMemory::AccessMode_ReadWrite;
|
nuclear@0
|
168 params.minSizeBytes = RegionSize;
|
nuclear@0
|
169 params.openMode = readOnly ? SharedMemory::OpenMode_OpenOnly : SharedMemory::OpenMode_CreateOrOpen;
|
nuclear@0
|
170
|
nuclear@0
|
171 // Attempt to open the shared memory file
|
nuclear@0
|
172 pSharedMemory = SharedMemoryFactory::GetInstance()->Open(params);
|
nuclear@0
|
173
|
nuclear@0
|
174 // If it was not able to be opened,
|
nuclear@0
|
175 if (pSharedMemory && pSharedMemory->GetSizeI() >= RegionSize && pSharedMemory->GetData())
|
nuclear@0
|
176 {
|
nuclear@0
|
177 // If writing,
|
nuclear@0
|
178 if (!readOnly)
|
nuclear@0
|
179 {
|
nuclear@0
|
180 // Construct the object also
|
nuclear@0
|
181 Construct<SharedType>(pSharedMemory->GetData());
|
nuclear@0
|
182 }
|
nuclear@0
|
183
|
nuclear@0
|
184 return true;
|
nuclear@0
|
185 }
|
nuclear@0
|
186
|
nuclear@0
|
187 return false;
|
nuclear@0
|
188 }
|
nuclear@0
|
189
|
nuclear@0
|
190 SharedType* Get() const
|
nuclear@0
|
191 {
|
nuclear@0
|
192 if (!pSharedMemory)
|
nuclear@0
|
193 {
|
nuclear@0
|
194 return NULL;
|
nuclear@0
|
195 }
|
nuclear@0
|
196
|
nuclear@0
|
197 void* data = pSharedMemory->GetData();
|
nuclear@0
|
198 if (!data)
|
nuclear@0
|
199 {
|
nuclear@0
|
200 return NULL;
|
nuclear@0
|
201 }
|
nuclear@0
|
202
|
nuclear@0
|
203 return reinterpret_cast<SharedType*>(data);
|
nuclear@0
|
204 }
|
nuclear@0
|
205 };
|
nuclear@0
|
206
|
nuclear@0
|
207 // Writer specialized shared object: Ctor will be called on Open()
|
nuclear@0
|
208 template<class SharedType>
|
nuclear@0
|
209 class SharedObjectWriter : public ISharedObject<SharedType>
|
nuclear@0
|
210 {
|
nuclear@0
|
211 public:
|
nuclear@0
|
212 OVR_FORCE_INLINE bool Open(const char* name)
|
nuclear@0
|
213 {
|
nuclear@0
|
214 return ISharedObject<SharedType>::Open(name, false);
|
nuclear@0
|
215 }
|
nuclear@0
|
216 OVR_FORCE_INLINE SharedType* Get()
|
nuclear@0
|
217 {
|
nuclear@0
|
218 return ISharedObject<SharedType>::Get();
|
nuclear@0
|
219 }
|
nuclear@0
|
220 };
|
nuclear@0
|
221
|
nuclear@0
|
222 // Reader specialized shared object: Ctor will not be called
|
nuclear@0
|
223 template<class SharedType>
|
nuclear@0
|
224 class SharedObjectReader : public ISharedObject<SharedType>
|
nuclear@0
|
225 {
|
nuclear@0
|
226 public:
|
nuclear@0
|
227 OVR_FORCE_INLINE bool Open(const char* name)
|
nuclear@0
|
228 {
|
nuclear@0
|
229 return ISharedObject<SharedType>::Open(name, true);
|
nuclear@0
|
230 }
|
nuclear@0
|
231 OVR_FORCE_INLINE const SharedType* Get() const
|
nuclear@0
|
232 {
|
nuclear@0
|
233 return ISharedObject<SharedType>::Get();
|
nuclear@0
|
234 }
|
nuclear@0
|
235 };
|
nuclear@0
|
236
|
nuclear@0
|
237
|
nuclear@0
|
238 } // namespace OVR
|
nuclear@0
|
239
|
nuclear@0
|
240 #endif // OVR_SharedMemory_h
|