Mem_Map.cpp

Go to the documentation of this file.
00001 // Mem_Map.cpp,v 4.55 2006/06/09 08:00:16 jwillemsen Exp
00002 
00003 // Defines the member functions for the memory mapping facility.
00004 
00005 #include "ace/Mem_Map.h"
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/Mem_Map.inl"
00008 #endif /* __ACE_INLINE__ */
00009 
00010 #include "ace/OS_NS_sys_stat.h"
00011 #include "ace/OS_NS_fcntl.h"
00012 #include "ace/OS_NS_string.h"
00013 #include "ace/Log_Msg.h"
00014 
00015 #if defined (ACE_WIN32) \
00016     && (!defined(ACE_HAS_WINNT4) || (ACE_HAS_WINNT4 == 0))
00017 # define ACE_USE_MAPPING_NAME 1
00018 #endif /* ACE_WIN32 */
00019 
00020 #if defined (ACE_USE_MAPPING_NAME)
00021 #include "ace/SString.h"
00022 #endif /* ACE_USE_MAPPING_NAME */
00023 
00024 ACE_RCSID(ace, Mem_Map, "Mem_Map.cpp,v 4.39 2003/11/01 11:15:13 dhinton Exp")
00025 
00026 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00027 
00028 ACE_ALLOC_HOOK_DEFINE(ACE_Mem_Map)
00029 
00030 #if defined (ACE_USE_MAPPING_NAME)
00031 // Gets a mapping object name from a file name.  TODO: The file name
00032 // is used as the key to the mapping. We should try to avoid mapping
00033 // the same object name to different files (there is a mapping object
00034 // name length limitation).
00035 
00036 static void
00037 to_mapping_name (ACE_TCHAR *mapobjname,
00038     const ACE_TCHAR *filename,
00039     size_t len)
00040 {
00041   --len;
00042   size_t i = 0;
00043 
00044   while (*filename && i < len)
00045     {
00046       if (*filename == ACE_LIB_TEXT ('\\'))
00047         // Can't use backslash in mapping object name.
00048         mapobjname[i] = ACE_LIB_TEXT ('.');
00049       else
00050         mapobjname[i] = *filename;
00051       ++filename;
00052       ++i;
00053     }
00054 
00055   mapobjname[i] = 0;
00056 }
00057 #endif /* ACE_USE_MAPPING_NAME */
00058 
00059 void
00060 ACE_Mem_Map::dump (void) const
00061 {
00062 #if defined (ACE_HAS_DUMP)
00063   ACE_TRACE ("ACE_Mem_Map::dump");
00064 
00065   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00066   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base_addr_ = %x"), this->base_addr_));
00067   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nfilename_ = %s"), this->filename_));
00068   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nlength_ = %d"), this->length_));
00069   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nhandle_ = %d"), this->handle_));
00070   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nfile_mapping_ = %d"), this->file_mapping_));
00071   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nclose_handle_ = %d"), this->close_handle_));
00072   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00073 #endif /* ACE_HAS_DUMP */
00074 }
00075 
00076 int
00077 ACE_Mem_Map::close (void)
00078 {
00079   ACE_TRACE ("ACE_Mem_Map::close");
00080 
00081   this->unmap ();
00082 
00083   return this->close_handle ();
00084 }
00085 
00086 ACE_Mem_Map::~ACE_Mem_Map (void)
00087 {
00088   ACE_TRACE ("ACE_Mem_Map::~ACE_Mem_Map");
00089 
00090   this->close ();
00091 }
00092 
00093 // This function does the dirty work of actually calling ACE_OS::mmap
00094 // to map the file into memory.
00095 
00096 int
00097 ACE_Mem_Map::map_it (ACE_HANDLE handle,
00098                      ssize_t length_request,
00099                      int prot,
00100                      int share,
00101                      void *addr,
00102                      off_t offset,
00103                      LPSECURITY_ATTRIBUTES sa)
00104 {
00105   ACE_TRACE ("ACE_Mem_Map::map_it");
00106 
00107 #if defined (ACE_LACKS_AUTO_MMAP_REPLACEMENT)
00108   // If the system does not replace any previous mappings, then
00109   // unmap() before (potentially) mapping to the same location.
00110   int const unmap_result = this->unmap ();
00111   if (unmap_result != 0)
00112     return unmap_result;
00113 #endif /* ACE_LACKS_AUTO_MMAP_REPLACEMENT */
00114 
00115   this->base_addr_ = addr;
00116   this->handle_ = handle;
00117 
00118   ACE_LOFF_T const result = ACE_OS::filesize (this->handle_);
00119 
00120   // At this point we know <result> is not negative...
00121   size_t const current_file_length = static_cast<size_t> (result);
00122 
00123   // Flag to indicate if we need to extend the back store
00124   bool extend_backing_store = false;
00125 
00126   // File length requested by user
00127   size_t requested_file_length = 0;
00128 
00129   // Check <length_request>
00130   if (length_request == -1)
00131     // Set length to file_request.
00132     this->length_ = current_file_length - offset;
00133   else
00134     {
00135       // File length implicitly requested by user
00136       requested_file_length = length_request + offset;
00137 
00138       // Check to see if we need to extend the backing store
00139       if (requested_file_length > current_file_length)
00140         {
00141           // If the length of the mapped region is less than the
00142           // length of the file then we force a complete new remapping
00143           // by setting the descriptor to ACE_INVALID_HANDLE (closing
00144           // down the descriptor if necessary).
00145           this->close_filemapping_handle ();
00146 
00147           // Remember to extend the backing store
00148           extend_backing_store = true;
00149         }
00150 
00151       // Set length to length_request
00152       this->length_ = length_request;
00153     }
00154 
00155   // Check if we need to extend the backing store.
00156   if (extend_backing_store)
00157     {
00158       // Remember than write increases the size by one.
00159       off_t null_byte_position;
00160       if (requested_file_length > 0)
00161         // This will make the file size <requested_file_length>
00162         null_byte_position =
00163           static_cast<off_t> (requested_file_length - 1);
00164       else
00165         // This will make the file size 1
00166         null_byte_position = 0;
00167 
00168       if (ACE_OS::pwrite (this->handle_,
00169                           "",
00170                           1,
00171                           null_byte_position) == -1)
00172         return -1;
00173     }
00174 
00175 #if defined (ACE_HAS_LYNXOS_BROKEN_MMAP)
00176   // Set flag that indicates whether PROT_WRITE has been enabled.
00177   write_enabled_ = ACE_BIT_ENABLED (prot, PROT_WRITE);
00178 #endif /* ACE_HAS_LYNXOS_BROKEN_MMAP */
00179 
00180 #if defined (ACE_USE_MAPPING_NAME)
00181   if (ACE_BIT_ENABLED (share, MAP_SHARED))
00182     {
00183 # if defined(__MINGW32__)
00184       const int max_mapping_name_length = 32;
00185 # else
00186       const int max_mapping_name_length = 31;
00187 # endif /* __MINGW32__ */
00188       ACE_TCHAR file_mapping_name[max_mapping_name_length + 1];
00189       to_mapping_name (file_mapping_name,
00190                        filename_,
00191                        max_mapping_name_length + 1);
00192 
00193       this->base_addr_ = ACE_OS::mmap (this->base_addr_,
00194                                        this->length_,
00195                                        prot,
00196                                        share,
00197                                        this->handle_,
00198                                        offset,
00199                                        &this->file_mapping_,
00200                                        sa,
00201                                        file_mapping_name);
00202     }
00203   else
00204 #endif /* ACE_USE_MAPPING_NAME */
00205     this->base_addr_ = ACE_OS::mmap (this->base_addr_,
00206                                      this->length_,
00207                                      prot,
00208                                      share,
00209                                      this->handle_,
00210                                      offset,
00211                                      &this->file_mapping_,
00212                                      sa);
00213 
00214   return this->base_addr_ == MAP_FAILED ? -1 : 0;
00215 }
00216 
00217 int
00218 ACE_Mem_Map::open (const ACE_TCHAR *file_name,
00219                    int flags,
00220                    int mode,
00221                    LPSECURITY_ATTRIBUTES sa)
00222 {
00223   ACE_TRACE ("ACE_Mem_Map::open");
00224 
00225 #if defined(INTEGRITY)  || defined (__QNXNTO__)
00226   this->handle_ = ACE_OS::shm_open (file_name, flags, mode, sa);
00227 #elif defined (ACE_OPENVMS)
00228   ACE_OSCALL (::open (file_name, flags, mode, "shr=get,put,upd"), ACE_HANDLE, -1, this->handle_);
00229 #else
00230   this->handle_ = ACE_OS::open (file_name, flags, mode, sa);
00231 #endif /* INTEGRITY */
00232 
00233   if (this->handle_ == ACE_INVALID_HANDLE)
00234     return -1;
00235   else
00236     {
00237       ACE_OS::strsncpy (this->filename_,
00238                         file_name,
00239                         MAXPATHLEN);
00240 
00241       this->close_handle_ = true;
00242       return 0;
00243     }
00244 }
00245 
00246 int
00247 ACE_Mem_Map::map (const ACE_TCHAR *file_name,
00248                   ssize_t len,
00249                   int flags,
00250                   int mode,
00251                   int prot,
00252                   int share,
00253                   void *addr,
00254                   off_t offset,
00255                   LPSECURITY_ATTRIBUTES sa)
00256 {
00257   ACE_TRACE ("ACE_Mem_Map::map");
00258   this->length_ = 0;
00259 
00260   if (this->open (file_name,
00261                   flags,
00262                   mode,
00263                   sa) == -1)
00264     return -1;
00265   else
00266     return this->map_it (this->handle (),
00267                          len,
00268                          prot,
00269                          share,
00270                          addr,
00271                          offset,
00272                          sa);
00273 }
00274 
00275 ACE_Mem_Map::ACE_Mem_Map (void)
00276   : base_addr_ (MAP_FAILED),
00277     length_ (0),
00278     handle_ (ACE_INVALID_HANDLE),
00279     file_mapping_ (ACE_INVALID_HANDLE),
00280     close_handle_ (false)
00281 {
00282   ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
00283   ACE_OS::memset (this->filename_, 0, sizeof this->filename_);
00284 }
00285 
00286 // Map a file specified by FILE_NAME.
00287 
00288 ACE_Mem_Map::ACE_Mem_Map (const ACE_TCHAR *file_name,
00289                           ssize_t len,
00290                           int flags,
00291                           int mode,
00292                           int prot,
00293                           int share,
00294                           void *addr,
00295                           off_t offset,
00296                           LPSECURITY_ATTRIBUTES sa)
00297   : base_addr_ (MAP_FAILED),
00298     length_ (0),
00299     handle_ (ACE_INVALID_HANDLE),
00300     file_mapping_ (ACE_INVALID_HANDLE),
00301     close_handle_ (false)
00302 {
00303   ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
00304   if (this->map (file_name,
00305                  len,
00306                  flags,
00307                  mode,
00308                  prot,
00309                  share,
00310                  addr,
00311                  offset,
00312                  sa) < 0)
00313     ACE_ERROR ((LM_ERROR,
00314                 ACE_LIB_TEXT ("%p\n"),
00315                 ACE_LIB_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
00316 }
00317 
00318 // Map a file from an open file descriptor HANDLE.  This function will
00319 // lookup the length of the file if it is not given.
00320 
00321 ACE_Mem_Map::ACE_Mem_Map (ACE_HANDLE handle,
00322                           ssize_t len,
00323                           int prot,
00324                           int share,
00325                           void *addr,
00326                           off_t offset,
00327                           LPSECURITY_ATTRIBUTES sa)
00328   : base_addr_ (MAP_FAILED),
00329     length_ (0),
00330     handle_ (ACE_INVALID_HANDLE),
00331     file_mapping_ (ACE_INVALID_HANDLE),
00332     close_handle_ (false)
00333 {
00334   ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
00335 
00336   ACE_OS::memset (this->filename_,
00337                   0,
00338                   sizeof this->filename_);
00339   if (this->map (handle,
00340                  len,
00341                  prot,
00342                  share,
00343                  addr,
00344                  offset,
00345                  sa) < 0)
00346     ACE_ERROR ((LM_ERROR,
00347                 ACE_LIB_TEXT ("%p\n"),
00348                 ACE_LIB_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
00349 }
00350 
00351 // Close down and remove the file from the file system.
00352 
00353 int
00354 ACE_Mem_Map::remove (void)
00355 {
00356   ACE_TRACE ("ACE_Mem_Map::remove");
00357 
00358   ACE_OS::ftruncate (this->handle_, 0);
00359   this->close ();
00360 
00361   if (this->filename_[0] != '\0')
00362 #if defined (__QNXNTO__)
00363   return ACE_OS::shm_unlink (this->filename_);
00364 #else
00365   return ACE_OS::unlink (this->filename_);
00366 #endif /* __QNXNTO__ */
00367 
00368   else
00369     return 0;
00370 }
00371 
00372 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:55 2006 for ACE by doxygen 1.3.6