00001 #include "ace_pch.h"
00002
00003
00004
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
00013
00014 #if defined (ACE_USE_MAPPING_NAME)
00015 #include "ace/SString.h"
00016 #endif
00017
00018 #if !defined (__ACE_INLINE__)
00019 #include "ace/Mem_Map.i"
00020 #endif
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
00028
00029
00030
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
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
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
00088
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
00103
00104 int unmap_result = this->unmap ();
00105 if (unmap_result != 0)
00106 return unmap_result;
00107 #endif
00108
00109 this->base_addr_ = addr;
00110 this->handle_ = handle;
00111
00112 #if defined (CHORUS)
00113
00114
00115
00116
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
00124
00125
00126 size_t current_file_length = ACE_static_cast (size_t, result);
00127
00128
00129 int extend_backing_store = 0;
00130
00131
00132 size_t requested_file_length = 0;
00133
00134
00135 if (length_request == -1)
00136
00137 this->length_ = current_file_length - offset;
00138 else
00139 {
00140
00141 requested_file_length = length_request + offset;
00142
00143
00144 if (requested_file_length > current_file_length)
00145 {
00146
00147
00148
00149
00150 this->close_filemapping_handle ();
00151
00152
00153 extend_backing_store = 1;
00154 }
00155
00156
00157 this->length_ = length_request;
00158 }
00159
00160
00161 if (extend_backing_store)
00162 {
00163 #if !defined (CHORUS)
00164
00165 off_t null_byte_position;
00166 if (requested_file_length > 0)
00167
00168 null_byte_position =
00169 ACE_static_cast (off_t, requested_file_length - 1);
00170 else
00171
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
00181 size_t actual_file_length;
00182 if (requested_file_length > 0)
00183
00184 actual_file_length = requested_file_length;
00185 else
00186
00187 actual_file_length = 1;
00188
00189 if (ACE_OS::ftruncate (this->handle_,
00190 actual_file_length) == -1)
00191 return -1;
00192 #endif
00193 }
00194
00195 #if defined (__Lynx__)
00196
00197 write_enabled_ = ACE_BIT_ENABLED (prot, PROT_WRITE);
00198 #endif
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
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
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
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
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
00337
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
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
00385
00386 else
00387 return 0;
00388 }