1 // Defines the member functions for the memory mapping facility.
3 #include "ace/Mem_Map.h"
5 #if !defined (__ACE_INLINE__)
6 #include "ace/Mem_Map.inl"
7 #endif /* __ACE_INLINE__ */
9 #include "ace/OS_NS_sys_stat.h"
10 #include "ace/OS_NS_fcntl.h"
11 #include "ace/OS_NS_string.h"
12 #include "ace/Log_Category.h"
13 #include "ace/Truncate.h"
14 #if defined (ACE_HAS_ALLOC_HOOKS)
15 # include "ace/Malloc_Base.h"
16 #endif /* ACE_HAS_ALLOC_HOOKS */
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE(ACE_Mem_Map
)
23 ACE_Mem_Map::dump () const
25 #if defined (ACE_HAS_DUMP)
26 ACE_TRACE ("ACE_Mem_Map::dump");
28 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
29 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("base_addr_ = %x"), this->base_addr_
));
30 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nfilename_ = %s"), this->filename_
));
31 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nlength_ = %d"), this->length_
));
32 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhandle_ = %d"), this->handle_
));
33 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nfile_mapping_ = %d"), this->file_mapping_
));
34 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nclose_handle_ = %d"), this->close_handle_
));
35 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
36 #endif /* ACE_HAS_DUMP */
42 ACE_TRACE ("ACE_Mem_Map::close");
46 return this->close_handle ();
49 ACE_Mem_Map::~ACE_Mem_Map ()
51 ACE_TRACE ("ACE_Mem_Map::~ACE_Mem_Map");
56 // This function does the dirty work of actually calling ACE_OS::mmap
57 // to map the file into memory.
60 ACE_Mem_Map::map_it (ACE_HANDLE handle
,
61 size_t length_request
,
66 LPSECURITY_ATTRIBUTES sa
)
68 ACE_TRACE ("ACE_Mem_Map::map_it");
70 #if defined (ACE_LACKS_AUTO_MMAP_REPLACEMENT)
71 // If the system does not replace any previous mappings, then
72 // unmap() before (potentially) mapping to the same location.
73 int const unmap_result
= this->unmap ();
74 if (unmap_result
!= 0)
76 #endif /* ACE_LACKS_AUTO_MMAP_REPLACEMENT */
78 this->base_addr_
= addr
;
79 this->handle_
= handle
;
81 // mmap through character device doens't care about it's size
82 // So map with /dev/* is done with a special case.
83 ACE_stat current_file_type
;
84 int result
= ACE_OS::fstat (this->handle_
, ¤t_file_type
);
88 // Something wrong found, bail out.
91 else if ((current_file_type
.st_mode
& S_IFMT
) == S_IFCHR
)
93 // Set length to length_request
94 this->length_
= length_request
;
96 else if ((current_file_type
.st_mode
& S_IFMT
) == S_IFREG
)
98 // Get the current filesize
99 ACE_OFF_T
const current_file_length
= ACE_OS::filesize (this->handle_
);
101 // Flag to indicate if we need to extend the back store
102 bool extend_backing_store
= false;
104 // File length requested by user
105 ACE_OFF_T requested_file_length
= 0;
107 // Check <length_request>
108 if (length_request
== static_cast<size_t> (-1))
110 // Set length to file_request or size_t max.
111 this->length_
= ACE_Utils::truncate_cast
<size_t> (current_file_length
- offset
);
112 #if defined (ACE_MMAP_NO_ZERO)
113 if (this->length_
== 0)
115 this->length_
= ACE_OS::getpagesize ();
117 #endif /* ACE_MMAP_NO_ZERO */
121 // Make sure that we have not been asked to do the impossible.
122 if (static_cast<ACE_UINT64
> (length_request
)
123 + static_cast<ACE_UINT64
> (offset
)
124 > static_cast<ACE_UINT64
> (ACE_Numeric_Limits
<ACE_OFF_T
>::max ()))
127 // File length implicitly requested by user
128 requested_file_length
= static_cast<ACE_OFF_T
> (length_request
) + offset
;
130 // Check to see if we need to extend the backing store
131 if (requested_file_length
> current_file_length
)
133 // If the length of the mapped region is less than the
134 // length of the file then we force a complete new remapping
135 // by setting the descriptor to ACE_INVALID_HANDLE (closing
136 // down the descriptor if necessary).
137 this->close_filemapping_handle ();
139 // Remember to extend the backing store
140 extend_backing_store
= true;
143 // Set length to length_request
144 this->length_
= length_request
;
147 // Check if we need to extend the backing store.
148 if (extend_backing_store
)
150 // Remember than write increases the size by one.
151 ACE_OFF_T null_byte_position
= 0;
152 if (requested_file_length
> 0)
154 // This will make the file size <requested_file_length>
155 null_byte_position
= requested_file_length
- 1;
158 if (ACE_OS::pwrite (this->handle_
,
161 null_byte_position
) == -1)
166 // Unmappable file type.
169 this->base_addr_
= ACE_OS::mmap (this->base_addr_
,
175 &this->file_mapping_
,
178 return this->base_addr_
== MAP_FAILED
? -1 : 0;
182 ACE_Mem_Map::open (const ACE_TCHAR
*file_name
,
185 LPSECURITY_ATTRIBUTES sa
)
187 ACE_TRACE ("ACE_Mem_Map::open");
189 #if defined (INTEGRITY) || defined (__QNXNTO__) || defined (ACE_VXWORKS)
190 this->handle_
= ACE_OS::shm_open (file_name
, flags
, perms
, sa
);
192 this->handle_
= ACE_OS::open (file_name
, flags
, perms
, sa
);
193 #endif /* INTEGRITY */
195 if (this->handle_
== ACE_INVALID_HANDLE
)
199 ACE_OS::strsncpy (this->filename_
,
203 this->close_handle_
= true;
209 ACE_Mem_Map::map (const ACE_TCHAR
*file_name
,
217 LPSECURITY_ATTRIBUTES sa
)
219 ACE_TRACE ("ACE_Mem_Map::map");
222 if (this->open (file_name
,
228 return this->map_it (this->handle (),
237 ACE_Mem_Map::ACE_Mem_Map ()
238 : base_addr_ (MAP_FAILED
),
240 handle_ (ACE_INVALID_HANDLE
),
241 file_mapping_ (ACE_INVALID_HANDLE
),
242 close_handle_ (false)
244 ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
245 ACE_OS::memset (this->filename_
, 0, sizeof this->filename_
);
248 // Map a file specified by FILE_NAME.
249 ACE_Mem_Map::ACE_Mem_Map (const ACE_TCHAR
*file_name
,
257 LPSECURITY_ATTRIBUTES sa
)
258 : base_addr_ (MAP_FAILED
),
260 handle_ (ACE_INVALID_HANDLE
),
261 file_mapping_ (ACE_INVALID_HANDLE
),
262 close_handle_ (false)
264 ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
265 if (this->map (file_name
,
274 ACELIB_ERROR ((LM_ERROR
,
276 ACE_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
279 // Map a file from an open file descriptor HANDLE. This function will
280 // lookup the length of the file if it is not given.
281 ACE_Mem_Map::ACE_Mem_Map (ACE_HANDLE handle
,
287 LPSECURITY_ATTRIBUTES sa
)
288 : base_addr_ (MAP_FAILED
),
290 handle_ (ACE_INVALID_HANDLE
),
291 file_mapping_ (ACE_INVALID_HANDLE
),
292 close_handle_ (false)
294 ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
296 ACE_OS::memset (this->filename_
,
298 sizeof this->filename_
);
299 if (this->map (handle
,
306 ACELIB_ERROR ((LM_ERROR
,
308 ACE_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
311 // Close down and remove the file from the file system.
314 ACE_Mem_Map::remove ()
316 ACE_TRACE ("ACE_Mem_Map::remove");
318 ACE_OS::ftruncate (this->handle_
, 0);
321 if (this->filename_
[0] != '\0')
322 #if defined (INTEGRITY) || defined (__QNXNTO__) || defined (ACE_VXWORKS)
323 return ACE_OS::shm_unlink (this->filename_
);
325 return ACE_OS::unlink (this->filename_
);
326 #endif /* __QNXNTO__ */
332 ACE_END_VERSIONED_NAMESPACE_DECL