#include <shared_memory.h>
Note: under Linux, an option could be added to prevent a segment to be swapped out.
Nevrax France
Definition at line 68 of file shared_memory.h.
Static Public Member Functions | |
void * | accessSharedMemory (TSharedMemId sharedMemId) |
bool | closeSharedMemory (void *accessAddress) |
void * | createSharedMemory (TSharedMemId sharedMemId, uint32 size) |
void | destroySharedMemory (TSharedMemId sharedMemId, bool force=false) |
|
Get access to an existing shared memory segment. The id must be used.
Definition at line 100 of file shared_memory.cpp. References NLMISC::TSharedMemId.
00101 { 00102 #ifdef NL_OS_WINDOWS 00103 00104 // Open the existing file mapping by name 00105 HANDLE hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, false, sharedMemId ); 00106 if ( hMapFile == NULL ) 00107 return NULL; 00108 //nldebug( "SHDMEM: Opening smid %s --> mapFile %p", sharedMemId, hMapFile ); 00109 00110 // Map the file into memory address space 00111 void *accessAddress = MapViewOfFile( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0 ); 00112 AccessAddressesToHandles.insert( make_pair( accessAddress, hMapFile ) ); 00113 return accessAddress; 00114 00115 #else 00116 00117 // Open an existing shared memory segment 00118 int shmid = shmget( sharedMemId, 0, 0666 ); 00119 if ( shmid == -1 ) 00120 return NULL; 00121 00122 // Map the segment into memory address space 00123 void *accessAddress = (void*)shmat( shmid, 0, 0 ); 00124 if ( accessAddress == (void*)-1 ) 00125 return NULL; 00126 else 00127 return accessAddress; 00128 00129 #endif 00130 } |
|
Close a shared memory segment, given the address returned by createSharedMemory() or accessSharedMemory(). Must be called by each process that called createSharedMemory() or accessSharedMemory(). Definition at line 136 of file shared_memory.cpp. References nlwarning.
00137 { 00138 #ifdef NL_OS_WINDOWS 00139 00140 bool result = true; 00141 00142 // Unmap the file from memory address space 00143 if ( UnmapViewOfFile( accessAddress ) == 0 ) 00144 { 00145 nlwarning( "SHDMEM: UnmapViewOfFile failed: error %u", GetLastError() ); 00146 result = false; 00147 } 00148 00149 // Close the corresponding handle 00150 map<void*,HANDLE>::iterator im = AccessAddressesToHandles.find( accessAddress ); 00151 if ( im != AccessAddressesToHandles.end() ) 00152 { 00153 //nldebug( "SHDMEM: CloseHandle mapFile %u", (*im).second ); 00154 if ( ! CloseHandle( (*im).second ) ) 00155 nlwarning( "SHDMEM: CloseHandle failed: error %u, mapFile %u", GetLastError(), (*im).second ); 00156 AccessAddressesToHandles.erase( im ); 00157 return result; 00158 } 00159 else 00160 { 00161 return false; 00162 } 00163 00164 #else 00165 00166 // Detach the shared memory segment 00167 return ( shmdt( accessAddress ) != -1 ); 00168 00169 #endif 00170 } |
|
Create a shared memory segment and get access to it. The id must not be used. The id 0x3a732235 is used by the NeL memory manager.
Definition at line 55 of file shared_memory.cpp. References nlwarning, NLMISC::SharedMemIdsToShmids, size, NLMISC::TSharedMemId, and uint32.
00056 { 00057 #ifdef NL_OS_WINDOWS 00058 00059 // Create a file mapping backed by the virtual memory swap file (not a data file) 00060 HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, sharedMemId ); 00061 if ( (hMapFile == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS) ) 00062 { 00063 nlwarning( "SHDMEM: Cannot create file mapping: error %u, mapFile %p", GetLastError(), hMapFile ); 00064 return NULL; 00065 } 00066 //else 00067 // nldebug( "SHDMEM: Creating smid %s --> mapFile %p", sharedMemId, hMapFile ); 00068 00069 00070 // Map the file into memory address space 00071 void *accessAddress = MapViewOfFile( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0 ); 00072 AccessAddressesToHandles.insert( make_pair( accessAddress, hMapFile ) ); 00073 /*if ( accessAddress == NULL ) 00074 { 00075 nlwarning( "SHDMEM: Cannot map view of file: error %u", GetLastError() ); 00076 }*/ 00077 return accessAddress; 00078 00079 #else 00080 00081 // Create a shared memory segment 00082 int shmid = shmget( sharedMemId, size, IPC_CREAT | IPC_EXCL | 0666 ); 00083 if ( shmid == -1 ) 00084 return NULL; 00085 SharedMemIdsToShmids.insert( make_pair( sharedMemId, shmid ) ); 00086 00087 // Map the segment into memory address space 00088 void *accessAddress = (void*)shmat( shmid, 0, 0 ); 00089 if ( accessAddress == (void*)-1 ) 00090 return NULL; 00091 else 00092 return accessAddress; 00093 #endif 00094 } |
|
Destroy a shared memory segment (must be called by the process that created the segment, not by the accessors). "Rescue feature": set "force" to true if a segment was created and left out of control (meaning a new createSharedMemory() with the same sharedMemId fails), but before, make sure the segment really belongs to you! Note: this method does nothing under Windows, destroying is automatic. Definition at line 177 of file shared_memory.cpp. References NLMISC::SharedMemIdsToShmids, and NLMISC::TSharedMemId.
00178 { 00179 #ifndef NL_OS_WINDOWS 00180 // Set the segment to auto-destroying (when the last process detaches) 00181 map<TSharedMemId,int>::iterator im = SharedMemIdsToShmids.find( sharedMemId ); 00182 if ( im != SharedMemIdsToShmids.end() ) 00183 { 00184 // Destroy the segment created before 00185 shmctl( (*im).second, IPC_RMID, 0 ); 00186 SharedMemIdsToShmids.erase( im ); 00187 } 00188 else if ( force ) 00189 { 00190 // Open and destroy the segment 00191 int shmid = shmget( sharedMemId, 0, 0666 ); 00192 if ( shmid != -1 ) 00193 { 00194 // Destroy the segment 00195 shmctl( shmid, IPC_RMID, 0 ); 00196 } 00197 } 00198 #endif 00199 } |