Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Mem_Map.cpp

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

Generated on Mon Jun 16 11:20:18 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002