ovr_sdk

annotate LibOVR/Src/Kernel/OVR_SharedMemory.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
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