1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/files/memory_mapped_file.h"
11 #include "base/logging.h"
12 #include "base/threading/thread_restrictions.h"
16 MemoryMappedFile::MemoryMappedFile() : data_(NULL
), length_(0) {
20 bool MemoryMappedFile::MapFileRegionToMemory(
21 const MemoryMappedFile::Region
& region
) {
22 ThreadRestrictions::AssertIOAllowed();
26 int32 data_offset
= 0;
28 if (region
== MemoryMappedFile::Region::kWholeFile
) {
29 int64 file_len
= file_
.GetLength();
31 DPLOG(ERROR
) << "fstat " << file_
.GetPlatformFile();
34 map_size
= static_cast<size_t>(file_len
);
37 // The region can be arbitrarily aligned. mmap, instead, requires both the
38 // start and size to be page-aligned. Hence, we map here the page-aligned
39 // outer region [|aligned_start|, |aligned_start| + |size|] which contains
40 // |region| and then add up the |data_offset| displacement.
41 int64 aligned_start
= 0;
42 int64 aligned_size
= 0;
43 CalculateVMAlignedBoundaries(region
.offset
,
49 // Ensure that the casts in the mmap call below are sane.
50 if (aligned_start
< 0 || aligned_size
< 0 ||
51 aligned_start
> std::numeric_limits
<off_t
>::max() ||
52 static_cast<uint64
>(aligned_size
) >
53 std::numeric_limits
<size_t>::max() ||
54 static_cast<uint64
>(region
.size
) > std::numeric_limits
<size_t>::max()) {
55 DLOG(ERROR
) << "Region bounds are not valid for mmap";
59 map_start
= static_cast<off_t
>(aligned_start
);
60 map_size
= static_cast<size_t>(aligned_size
);
61 length_
= static_cast<size_t>(region
.size
);
64 data_
= static_cast<uint8
*>(mmap(NULL
,
68 file_
.GetPlatformFile(),
70 if (data_
== MAP_FAILED
) {
71 DPLOG(ERROR
) << "mmap " << file_
.GetPlatformFile();
80 void MemoryMappedFile::CloseHandles() {
81 ThreadRestrictions::AssertIOAllowed();
84 munmap(data_
, length_
);