#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 }
|
1.3.6