shared_memory_pos.cpp
Go to the documentation of this file.
00001 
00017 /*****************************************************************************
00018 ** Includes
00019 *****************************************************************************/
00020 
00021 
00022 #include "../../include/ecl/ipc/shared_memory_pos.hpp"
00023 
00024 #ifdef ECL_HAS_POSIX_SHARED_MEMORY
00025 
00026 #include <string>
00027 #include <sys/mman.h>        /* For shm_open() */
00028 #include <fcntl.h>           /* For O_* constants */
00029 #include <errno.h>
00030 #include <ecl/exceptions/macros.hpp>
00031 #include <iostream>
00032 /*****************************************************************************
00033 ** Namespaces
00034 *****************************************************************************/
00035 
00036 namespace ecl {
00037 namespace ipc {
00038 
00039 void SharedMemoryBase::unlink() {
00040         shm_unlink(name.c_str());
00041 }
00042 
00043 int SharedMemoryBase::open() {
00044     /*********************
00045      * Open Flags
00046      *********************/
00047     /*
00048      * O_CREAT    : it will try and create some memory or just open if it already exists
00049      *              if the shared memory object already exists.
00050      * O_EXCL     : when used with O_CREAT fails to open if the message queue already exists.
00051      *            : if neither, then it will only open an existing memory.
00052      * O_WRONLY   : write only.
00053      * O_RDONLY   : read only.
00054      * O_RDWR     : read-write.
00055      * O_NONBLOCK : normally it will block if sending to a full queue. Disable this.
00056      */
00057     static const int open_flags = O_RDWR;
00058     static const int create_flags = O_CREAT|O_RDWR|O_EXCL;
00059     /*********************
00060      * Permissions
00061      *********************/
00062     /*
00063      * Permissions. Must be specified when O_CRELOC is used, otherwise it is ignored. It
00064      * is combined with the process umask (permissions & ~umask).
00065      * S_IRWXU [00700] - read, write & exec by user
00066      * S_IRUSR [00400] - read by the user who owns it
00067      * S_IWUSR [00200] - write by user
00068      * S_IXUSR [00100] - exec by user
00069      * S_IRWXG [00070] - read, write & exec by group
00070      * S_IRGRP [00040] - read by group
00071      * S_IWGRP [00020] - write by group
00072      * S_IXGRP [00010] - exe by group
00073      * S_IRWXG [00007] - read, write & exec by other
00074      * S_IROTH [00004] - read by other
00075      * S_IWOTH [00002] - write by other
00076      * S_IXOTH [00001] - exe by other
00077     */
00078     static const int permissions = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
00079     /*************************************************************************
00080     ** Name
00081     *************************************************************************/
00082     /*
00083      * The name is like a filename. To be compatible on all systems, always
00084      * begin with a leading '/' and include no other '/'s.
00085      * In debug mode, might be worth parsing the name here.
00086      */
00087     /*************************************************************************
00088     ** Open
00089     *************************************************************************/
00090     int shm_descriptor = shm_open(name.c_str(),create_flags,permissions);
00091     if ( ( shm_descriptor == -1 ) && ( errno == EEXIST ) ) {
00092         // Maybe its already open, try opening it normally
00093         shm_descriptor = shm_open(name.c_str(),open_flags,permissions);
00094     } else {
00095         shared_memory_manager = true;
00096     }
00097     if ( shm_descriptor == -1) {
00098     }
00099         return shm_descriptor;
00100 }
00101 
00102 
00103 /*****************************************************************************
00104 ** Exception Handlers
00105 *****************************************************************************/
00106 
00107 #ifdef ECL_HAS_EXCEPTIONS
00108 
00109 ecl::StandardException openSharedSectionException(const char* loc) {
00110         int error_result = errno;
00111         switch (error_result) {
00112                 case ( EACCES ) : {
00113                         throw StandardException(LOC,PermissionsError,"Opening shared memory failed - permission denied.");
00114                         break;
00115                 }
00116         //            case ( EEXIST ) : { // If using O_EXCL, need this, otherwise no.
00117         //                // pathname exists, assume its a fifo and continue
00118         //                break;
00119         //            }
00120                 case ( EMFILE ) : case ( ENFILE ) : {
00121                         throw StandardException(LOC,OutOfResourcesError,"Opening shared memory failed - too many file connections already open.");
00122                         break;
00123                 }
00124                 case ( ENOENT ) : case ( ENAMETOOLONG ) : case ( EINVAL ) : {
00125                         throw StandardException(LOC,InvalidArgError,"Opening shared memory failed - pathname problem.");
00126                         break;
00127                 }
00128                 case ( ENOSYS ) : {
00129                         throw StandardException(LOC,NotSupportedError,"Opening shared memory failed - kernel system functions are not available (remake the kernel).");
00130                         break;
00131                 }
00132                 default         :
00133                 {
00134                         std::ostringstream ostream;
00135                         ostream << "Posix error " << error_result << ": " << strerror(error_result) << ".";
00136                         return StandardException(loc, UnknownError, ostream.str());
00137                 }
00138         }
00139 }
00140 
00141 ecl::StandardException memoryMapException(const char* loc) {
00142         int error_result = errno;
00143         switch (error_result) {
00144                 case ( EACCES ) : {
00145                         return StandardException(LOC,PermissionsError,"Shared mapping failed - permission problems (see man mmap).");
00146                 }
00147                 case ( EAGAIN ) : {
00148                         return StandardException(LOC,MemoryError,"Shared mapping failed - file locked or too much memory has been locked.");
00149                 }
00150                 case ( EBADF  ) : {
00151                         return StandardException(LOC,InvalidArgError,"Shared mapping failed - not a valid file descriptor (see man mmap).");
00152                 }
00153                 case ( EINVAL ) : {
00154                         return StandardException(LOC,InvalidArgError,"Shared mapping failed - start, length or offset were invalid or MAP_PRIVLOCE and MAP_SHARED were either both present or both obso (see man mmap).");
00155                 }
00156                 case ( ENFILE ) : {
00157                         return StandardException(LOC,OutOfResourcesError,"Shared mapping failed - system limit on the total number of open files has been reached (see man mmap).");
00158                 }
00159                 case ( ENODEV ) : {
00160                         return StandardException(LOC,NotSupportedError,"Shared mapping failed - underlying filesystem of the specified file doesn't support memory mapping (see man mmap).");
00161                 }
00162                 case ( ENOMEM ) : {
00163                         return StandardException(LOC,MemoryError,"Shared mapping failed - no mem available, or max mappings exceeded (see man mmap).");
00164                 }
00165                 case ( EPERM ) : {
00166                         return StandardException(LOC,PermissionsError,"Shared mapping failed - EPERM (see man mmap).");
00167                 }
00168 //              case ( ETXBSY ) : {
00169 //                      return StandardException(LOC,"Shared mapping failed.","ETXBSY (see man mmap).");
00170 //                      break;
00171 //              }
00172                 default         :
00173                 {
00174                         std::ostringstream ostream;
00175                         ostream << "Posix error " << error_result << ": " << strerror(error_result) << ".";
00176                         return StandardException(loc, UnknownError, ostream.str());
00177                 }
00178         }
00179 }
00180 #endif /* ECL_HAS_EXCEPTIONS */
00181 
00182 } // namespace ipc
00183 } // namespace ecl
00184 
00185 #endif /* ECL_HAS_POSIX_SHARED_MEMORY */


ecl_ipc
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:13:04