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) {
19 bool MemoryMappedFile::MapFileRegionToMemory(
20 const MemoryMappedFile::Region
& region
) {
21 ThreadRestrictions::AssertIOAllowed();
25 int32 data_offset
= 0;
27 if (region
== MemoryMappedFile::Region::kWholeFile
) {
28 int64 file_len
= file_
.GetLength();
30 DPLOG(ERROR
) << "fstat " << file_
.GetPlatformFile();
33 map_size
= static_cast<size_t>(file_len
);
36 // The region can be arbitrarily aligned. mmap, instead, requires both the
37 // start and size to be page-aligned. Hence, we map here the page-aligned
38 // outer region [|aligned_start|, |aligned_start| + |size|] which contains
39 // |region| and then add up the |data_offset| displacement.
40 int64 aligned_start
= 0;
41 int64 aligned_size
= 0;
42 CalculateVMAlignedBoundaries(region
.offset
,
48 // Ensure that the casts in the mmap call below are sane.
49 if (aligned_start
< 0 || aligned_size
< 0 ||
50 aligned_start
> std::numeric_limits
<off_t
>::max() ||
51 static_cast<uint64
>(aligned_size
) >
52 std::numeric_limits
<size_t>::max() ||
53 static_cast<uint64
>(region
.size
) > std::numeric_limits
<size_t>::max()) {
54 DLOG(ERROR
) << "Region bounds are not valid for mmap";
58 map_start
= static_cast<off_t
>(aligned_start
);
59 map_size
= static_cast<size_t>(aligned_size
);
60 length_
= static_cast<size_t>(region
.size
);
63 data_
= static_cast<uint8
*>(mmap(NULL
,
67 file_
.GetPlatformFile(),
69 if (data_
== MAP_FAILED
) {
70 DPLOG(ERROR
) << "mmap " << file_
.GetPlatformFile();
78 void MemoryMappedFile::CloseHandles() {
79 ThreadRestrictions::AssertIOAllowed();
82 munmap(data_
, length_
);