NLMISC::CSharedMemory Class Reference

#include <shared_memory.h>


Detailed Description

Encapsulation of shared memory APIs. Using file mapping under Windows, System V shared memory (shm) under Linux.

Note: under Linux, an option could be added to prevent a segment to be swapped out.

Author:
Olivier Cado

Nevrax France

Date:
2002

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)


Member Function Documentation

void * NLMISC::CSharedMemory::accessSharedMemory TSharedMemId  sharedMemId  )  [static]
 

Get access to an existing shared memory segment. The id must be used.

Returns:
Access address of the segment. Its size was determined at the creation.

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 }

bool NLMISC::CSharedMemory::closeSharedMemory void *  accessAddress  )  [static]
 

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 }

void * NLMISC::CSharedMemory::createSharedMemory TSharedMemId  sharedMemId,
uint32  size
[static]
 

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.

Returns:
Access address of the segment of the choosen size

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 }

void NLMISC::CSharedMemory::destroySharedMemory TSharedMemId  sharedMemId,
bool  force = false
[static]
 

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 }


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 13:32:41 2004 for NeL by doxygen 1.3.6