ovr_sdk
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/LibOVR/Src/Kernel/OVR_SharedMemory.h Wed Jan 14 06:51:16 2015 +0200 1.3 @@ -0,0 +1,240 @@ 1.4 +/************************************************************************************ 1.5 + 1.6 +PublicHeader: OVR 1.7 +Filename : OVR_SharedMemory.h 1.8 +Content : Inter-process shared memory subsystem 1.9 +Created : June 1, 2014 1.10 +Notes : 1.11 + 1.12 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. 1.13 + 1.14 +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 1.15 +you may not use the Oculus VR Rift SDK except in compliance with the License, 1.16 +which is provided at the time of installation or download, or which 1.17 +otherwise accompanies this software in either electronic or hard copy form. 1.18 + 1.19 +You may obtain a copy of the License at 1.20 + 1.21 +http://www.oculusvr.com/licenses/LICENSE-3.2 1.22 + 1.23 +Unless required by applicable law or agreed to in writing, the Oculus VR SDK 1.24 +distributed under the License is distributed on an "AS IS" BASIS, 1.25 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.26 +See the License for the specific language governing permissions and 1.27 +limitations under the License. 1.28 + 1.29 +************************************************************************************/ 1.30 + 1.31 +#ifndef OVR_SharedMemory_h 1.32 +#define OVR_SharedMemory_h 1.33 + 1.34 +#include "OVR_Types.h" 1.35 +#include "OVR_RefCount.h" 1.36 +#include "OVR_Allocator.h" 1.37 +#include "OVR_System.h" 1.38 + 1.39 +#ifdef OVR_SINGLE_PROCESS /* Everything running in one process usually for debugging */ 1.40 +#define OVR_FAKE_SHAREDMEMORY /* Single-process version to avoid admin privs */ 1.41 +#endif 1.42 + 1.43 +namespace OVR { 1.44 + 1.45 +class SharedMemoryInternal; // Opaque 1.46 + 1.47 + 1.48 +// SharedMemory 1.49 +// Note: Safe when used between 32-bit and 64-bit processes 1.50 +class SharedMemory : public RefCountBase<SharedMemory> 1.51 +{ 1.52 + friend class SharedMemoryFactory; 1.53 + 1.54 + OVR_NON_COPYABLE(SharedMemory); 1.55 + 1.56 +public: 1.57 + // Only constructed by the SharedMemory Factory 1.58 + SharedMemory(int size, void* data, SharedMemoryInternal* pInternal); 1.59 + // Call close when it goes out of scope 1.60 + ~SharedMemory(); 1.61 + 1.62 + // Modes for opening a new shared memory region 1.63 + enum OpenMode 1.64 + { 1.65 + // Note: On Windows, Create* requires Administrator priviledges or running as a Service. 1.66 + OpenMode_CreateOnly, // Must not already exist 1.67 + OpenMode_OpenOnly, // Must already exist 1.68 + OpenMode_CreateOrOpen // May exist or not 1.69 + }; 1.70 + 1.71 + // Local access restrictions 1.72 + enum AccessMode 1.73 + { 1.74 + AccessMode_ReadOnly, // Acquire read-only access 1.75 + AccessMode_ReadWrite, // Acquire read or write access 1.76 + }; 1.77 + 1.78 + // Remote access restrictions 1.79 + enum RemoteMode 1.80 + { 1.81 + RemoteMode_ReadOnly, // Other processes will need to open in read-only mode 1.82 + RemoteMode_ReadWrite // Other processes can open in read-write mode 1.83 + }; 1.84 + 1.85 + // Modes for opening a new shared memory region 1.86 + struct OpenParameters 1.87 + { 1.88 + OpenParameters() : 1.89 + globalName(NULL), 1.90 + minSizeBytes(0), 1.91 + openMode(SharedMemory::OpenMode_CreateOrOpen), 1.92 + remoteMode(SharedMemory::RemoteMode_ReadWrite), 1.93 + accessMode(SharedMemory::AccessMode_ReadWrite) 1.94 + { 1.95 + } 1.96 + 1.97 + // Creation parameters 1.98 + const char* globalName; // Name of the shared memory region 1.99 + int minSizeBytes; // Minimum number of bytes to request 1.100 + SharedMemory::OpenMode openMode; // Creating the file or opening the file? 1.101 + SharedMemory::RemoteMode remoteMode; // When creating, what access should other processes get? 1.102 + SharedMemory::AccessMode accessMode; // When opening/creating, what access should this process get? 1.103 + }; 1.104 + 1.105 +public: 1.106 + // Returns the size of the shared memory region 1.107 + int GetSizeI() const 1.108 + { 1.109 + return Size; 1.110 + } 1.111 + 1.112 + // Returns the process-local pointer to the shared memory region 1.113 + // Note: This may be different on different processes 1.114 + void* GetData() const 1.115 + { 1.116 + return Data; 1.117 + } 1.118 + 1.119 +protected: 1.120 + int Size; // How many shared bytes are shared at the pointer address? 1.121 + void* Data; // Pointer to the shared memory region. 1.122 + 1.123 + // Hidden implementation class for OS-specific behavior 1.124 + SharedMemoryInternal* Internal; 1.125 + 1.126 + // Close and cleanup the shared memory region 1.127 + // Note: This is called on destruction 1.128 + void Close(); 1.129 +}; 1.130 + 1.131 + 1.132 +// SharedMemoryFactory 1.133 +class SharedMemoryFactory : public NewOverrideBase, public SystemSingletonBase<SharedMemoryFactory> 1.134 +{ 1.135 + OVR_DECLARE_SINGLETON(SharedMemoryFactory); 1.136 + 1.137 +public: 1.138 + // Construct a SharedMemory object. 1.139 + // Note: The new object is reference-counted so it should be stored with Ptr<>. Initial reference count is 1. 1.140 + Ptr<SharedMemory> Open(const SharedMemory::OpenParameters&); 1.141 +}; 1.142 + 1.143 + 1.144 +// A shared object 1.145 +// Its constructor will be called when creating a writer 1.146 +// Its destructor will not be called 1.147 +template<class SharedType> 1.148 +class ISharedObject : public NewOverrideBase 1.149 +{ 1.150 +public: 1.151 + static const int RegionSize = (int)sizeof(SharedType); 1.152 + 1.153 +protected: 1.154 + Ptr<SharedMemory> pSharedMemory; 1.155 + 1.156 + bool Open(const char* name, bool readOnly) 1.157 + { 1.158 + // Configure open parameters based on read-only mode 1.159 + SharedMemory::OpenParameters params; 1.160 + 1.161 + // FIXME: This is a hack. We currently need to allow clients to open this for read-write even 1.162 + // though they only need read-only access. This is because in the first 0.4 release the 1.163 + // LocklessUpdater class technically writes to it (increments by 0) to read from the space. 1.164 + // This was quickly corrected in 0.4.1 and we are waiting for the right time to disallow write 1.165 + // access when everyone upgrades to 0.4.1+. 1.166 + //params.remoteMode = SharedMemory::RemoteMode_ReadOnly; 1.167 + params.remoteMode = SharedMemory::RemoteMode_ReadWrite; 1.168 + 1.169 + params.globalName = name; 1.170 + params.accessMode = readOnly ? SharedMemory::AccessMode_ReadOnly : SharedMemory::AccessMode_ReadWrite; 1.171 + params.minSizeBytes = RegionSize; 1.172 + params.openMode = readOnly ? SharedMemory::OpenMode_OpenOnly : SharedMemory::OpenMode_CreateOrOpen; 1.173 + 1.174 + // Attempt to open the shared memory file 1.175 + pSharedMemory = SharedMemoryFactory::GetInstance()->Open(params); 1.176 + 1.177 + // If it was not able to be opened, 1.178 + if (pSharedMemory && pSharedMemory->GetSizeI() >= RegionSize && pSharedMemory->GetData()) 1.179 + { 1.180 + // If writing, 1.181 + if (!readOnly) 1.182 + { 1.183 + // Construct the object also 1.184 + Construct<SharedType>(pSharedMemory->GetData()); 1.185 + } 1.186 + 1.187 + return true; 1.188 + } 1.189 + 1.190 + return false; 1.191 + } 1.192 + 1.193 + SharedType* Get() const 1.194 + { 1.195 + if (!pSharedMemory) 1.196 + { 1.197 + return NULL; 1.198 + } 1.199 + 1.200 + void* data = pSharedMemory->GetData(); 1.201 + if (!data) 1.202 + { 1.203 + return NULL; 1.204 + } 1.205 + 1.206 + return reinterpret_cast<SharedType*>(data); 1.207 + } 1.208 +}; 1.209 + 1.210 +// Writer specialized shared object: Ctor will be called on Open() 1.211 +template<class SharedType> 1.212 +class SharedObjectWriter : public ISharedObject<SharedType> 1.213 +{ 1.214 +public: 1.215 + OVR_FORCE_INLINE bool Open(const char* name) 1.216 + { 1.217 + return ISharedObject<SharedType>::Open(name, false); 1.218 + } 1.219 + OVR_FORCE_INLINE SharedType* Get() 1.220 + { 1.221 + return ISharedObject<SharedType>::Get(); 1.222 + } 1.223 +}; 1.224 + 1.225 +// Reader specialized shared object: Ctor will not be called 1.226 +template<class SharedType> 1.227 +class SharedObjectReader : public ISharedObject<SharedType> 1.228 +{ 1.229 +public: 1.230 + OVR_FORCE_INLINE bool Open(const char* name) 1.231 + { 1.232 + return ISharedObject<SharedType>::Open(name, true); 1.233 + } 1.234 + OVR_FORCE_INLINE const SharedType* Get() const 1.235 + { 1.236 + return ISharedObject<SharedType>::Get(); 1.237 + } 1.238 +}; 1.239 + 1.240 + 1.241 +} // namespace OVR 1.242 + 1.243 +#endif // OVR_SharedMemory_h