Mem_Map.cpp

Go to the documentation of this file.
00001 // $Id: Mem_Map.cpp 80826 2008-03-04 14:51:23Z wotte $
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 #include "ace/Truncate.h"
00015 
00016 ACE_RCSID(ace, Mem_Map, "Mem_Map.cpp,v 4.39 2003/11/01 11:15:13 dhinton Exp")
00017 
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 ACE_ALLOC_HOOK_DEFINE(ACE_Mem_Map)
00021 
00022 
00023 void
00024 ACE_Mem_Map::dump (void) const
00025 {
00026 #if defined (ACE_HAS_DUMP)
00027   ACE_TRACE ("ACE_Mem_Map::dump");
00028 
00029   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00030   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("base_addr_ = %x"), this->base_addr_));
00031   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nfilename_ = %s"), this->filename_));
00032   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nlength_ = %d"), this->length_));
00033   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nhandle_ = %d"), this->handle_));
00034   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nfile_mapping_ = %d"), this->file_mapping_));
00035   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nclose_handle_ = %d"), this->close_handle_));
00036   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00037 #endif /* ACE_HAS_DUMP */
00038 }
00039 
00040 int
00041 ACE_Mem_Map::close (void)
00042 {
00043   ACE_TRACE ("ACE_Mem_Map::close");
00044 
00045   this->unmap ();
00046 
00047   return this->close_handle ();
00048 }
00049 
00050 ACE_Mem_Map::~ACE_Mem_Map (void)
00051 {
00052   ACE_TRACE ("ACE_Mem_Map::~ACE_Mem_Map");
00053 
00054   this->close ();
00055 }
00056 
00057 // This function does the dirty work of actually calling ACE_OS::mmap
00058 // to map the file into memory.
00059 
00060 int
00061 ACE_Mem_Map::map_it (ACE_HANDLE handle,
00062                      size_t length_request,
00063                      int prot,
00064                      int share,
00065                      void *addr,
00066                      ACE_OFF_T offset,
00067                      LPSECURITY_ATTRIBUTES sa)
00068 {
00069   ACE_TRACE ("ACE_Mem_Map::map_it");
00070 
00071 #if defined (ACE_LACKS_AUTO_MMAP_REPLACEMENT)
00072   // If the system does not replace any previous mappings, then
00073   // unmap() before (potentially) mapping to the same location.
00074   int const unmap_result = this->unmap ();
00075   if (unmap_result != 0)
00076     return unmap_result;
00077 #endif /* ACE_LACKS_AUTO_MMAP_REPLACEMENT */
00078 
00079   this->base_addr_ = addr;
00080   this->handle_ = handle;
00081 
00082   // Get the current filesize
00083   ACE_OFF_T const current_file_length = ACE_OS::filesize (this->handle_);
00084 
00085   // Flag to indicate if we need to extend the back store
00086   bool extend_backing_store = false;
00087 
00088   // File length requested by user
00089   ACE_OFF_T requested_file_length = 0;
00090 
00091   // Check <length_request>
00092   if (length_request == static_cast<size_t> (-1))
00093     {
00094       // Set length to file_request or size_t max.
00095       this->length_ = ACE_Utils::truncate_cast<size_t> (current_file_length - offset);
00096     }
00097   else
00098     {
00099       // Make sure that we have not been asked to do the impossible.
00100       if (static_cast<ACE_UINT64> (length_request)
00101           + static_cast<ACE_UINT64> (offset)
00102           > static_cast<ACE_UINT64> (ACE_Numeric_Limits<ACE_OFF_T>::max ()))
00103         return -1;
00104 
00105       // File length implicitly requested by user
00106       requested_file_length = static_cast<ACE_OFF_T> (length_request) + offset;
00107 
00108       // Check to see if we need to extend the backing store
00109       if (requested_file_length > current_file_length)
00110         {
00111           // If the length of the mapped region is less than the
00112           // length of the file then we force a complete new remapping
00113           // by setting the descriptor to ACE_INVALID_HANDLE (closing
00114           // down the descriptor if necessary).
00115           this->close_filemapping_handle ();
00116 
00117           // Remember to extend the backing store
00118           extend_backing_store = true;
00119         }
00120 
00121       // Set length to length_request
00122       this->length_ = length_request;
00123     }
00124 
00125   // Check if we need to extend the backing store.
00126   if (extend_backing_store)
00127     {
00128       // Remember than write increases the size by one.
00129       ACE_OFF_T null_byte_position = 0;
00130       if (requested_file_length > 0)
00131         {
00132           // This will make the file size <requested_file_length>
00133           null_byte_position = requested_file_length - 1;
00134         }
00135 
00136       if (ACE_OS::pwrite (this->handle_,
00137                           "",
00138                           1,
00139                           null_byte_position) == -1)
00140         return -1;
00141     }
00142 
00143     this->base_addr_ = ACE_OS::mmap (this->base_addr_,
00144                                      this->length_,
00145                                      prot,
00146                                      share,
00147                                      this->handle_,
00148                                      offset,
00149                                      &this->file_mapping_,
00150                                      sa);
00151 
00152   return this->base_addr_ == MAP_FAILED ? -1 : 0;
00153 }
00154 
00155 int
00156 ACE_Mem_Map::open (const ACE_TCHAR *file_name,
00157                    int flags,
00158                    mode_t perms,
00159                    LPSECURITY_ATTRIBUTES sa)
00160 {
00161   ACE_TRACE ("ACE_Mem_Map::open");
00162 
00163 #if defined (INTEGRITY)  || defined (__QNXNTO__) || defined (ACE_VXWORKS)
00164   this->handle_ = ACE_OS::shm_open (file_name, flags, perms, sa);
00165 #elif defined (ACE_OPENVMS)
00166   ACE_OSCALL (::open (file_name, flags, perms, "shr=get,put,upd"), ACE_HANDLE, -1, this->handle_);
00167 #else
00168   this->handle_ = ACE_OS::open (file_name, flags, perms, sa);
00169 #endif /* INTEGRITY */
00170 
00171   if (this->handle_ == ACE_INVALID_HANDLE)
00172     return -1;
00173   else
00174     {
00175       ACE_OS::strsncpy (this->filename_,
00176                         file_name,
00177                         MAXPATHLEN);
00178 
00179       this->close_handle_ = true;
00180       return 0;
00181     }
00182 }
00183 
00184 int
00185 ACE_Mem_Map::map (const ACE_TCHAR *file_name,
00186                   size_t len,
00187                   int flags,
00188                   mode_t mode,
00189                   int prot,
00190                   int share,
00191                   void *addr,
00192                   ACE_OFF_T offset,
00193                   LPSECURITY_ATTRIBUTES sa)
00194 {
00195   ACE_TRACE ("ACE_Mem_Map::map");
00196   this->length_ = 0;
00197 
00198   if (this->open (file_name,
00199                   flags,
00200                   mode,
00201                   sa) == -1)
00202     return -1;
00203   else
00204     return this->map_it (this->handle (),
00205                          len,
00206                          prot,
00207                          share,
00208                          addr,
00209                          offset,
00210                          sa);
00211 }
00212 
00213 ACE_Mem_Map::ACE_Mem_Map (void)
00214   : base_addr_ (MAP_FAILED),
00215     length_ (0),
00216     handle_ (ACE_INVALID_HANDLE),
00217     file_mapping_ (ACE_INVALID_HANDLE),
00218     close_handle_ (false)
00219 {
00220   ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
00221   ACE_OS::memset (this->filename_, 0, sizeof this->filename_);
00222 }
00223 
00224 // Map a file specified by FILE_NAME.
00225 
00226 ACE_Mem_Map::ACE_Mem_Map (const ACE_TCHAR *file_name,
00227                           size_t len,
00228                           int flags,
00229                           mode_t mode,
00230                           int prot,
00231                           int share,
00232                           void *addr,
00233                           ACE_OFF_T offset,
00234                           LPSECURITY_ATTRIBUTES sa)
00235   : base_addr_ (MAP_FAILED),
00236     length_ (0),
00237     handle_ (ACE_INVALID_HANDLE),
00238     file_mapping_ (ACE_INVALID_HANDLE),
00239     close_handle_ (false)
00240 {
00241   ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
00242   if (this->map (file_name,
00243                  len,
00244                  flags,
00245                  mode,
00246                  prot,
00247                  share,
00248                  addr,
00249                  offset,
00250                  sa) < 0)
00251     ACE_ERROR ((LM_ERROR,
00252                 ACE_TEXT ("%p\n"),
00253                 ACE_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
00254 }
00255 
00256 // Map a file from an open file descriptor HANDLE.  This function will
00257 // lookup the length of the file if it is not given.
00258 
00259 ACE_Mem_Map::ACE_Mem_Map (ACE_HANDLE handle,
00260                           size_t len,
00261                           int prot,
00262                           int share,
00263                           void *addr,
00264                           ACE_OFF_T offset,
00265                           LPSECURITY_ATTRIBUTES sa)
00266   : base_addr_ (MAP_FAILED),
00267     length_ (0),
00268     handle_ (ACE_INVALID_HANDLE),
00269     file_mapping_ (ACE_INVALID_HANDLE),
00270     close_handle_ (false)
00271 {
00272   ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
00273 
00274   ACE_OS::memset (this->filename_,
00275                   0,
00276                   sizeof this->filename_);
00277   if (this->map (handle,
00278                  len,
00279                  prot,
00280                  share,
00281                  addr,
00282                  offset,
00283                  sa) < 0)
00284     ACE_ERROR ((LM_ERROR,
00285                 ACE_TEXT ("%p\n"),
00286                 ACE_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
00287 }
00288 
00289 // Close down and remove the file from the file system.
00290 
00291 int
00292 ACE_Mem_Map::remove (void)
00293 {
00294   ACE_TRACE ("ACE_Mem_Map::remove");
00295 
00296   ACE_OS::ftruncate (this->handle_, 0);
00297   this->close ();
00298 
00299   if (this->filename_[0] != '\0')
00300 #if defined (INTEGRITY) || defined (__QNXNTO__) || defined (ACE_VXWORKS)
00301   return ACE_OS::shm_unlink (this->filename_);
00302 #else
00303   return ACE_OS::unlink (this->filename_);
00304 #endif /* __QNXNTO__ */
00305 
00306   else
00307     return 0;
00308 }
00309 
00310 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:40 2010 for ACE by  doxygen 1.4.7