Skip to content

Commit 2f26cea

Browse files
committed
Switch dwarfs::mmap implementation to boost::iostreams::mapped_file
1 parent 61fba32 commit 2f26cea

File tree

3 files changed

+44
-69
lines changed

3 files changed

+44
-69
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ else()
160160
find_package(fmt 10.0 REQUIRED CONFIG PATHS "${CMAKE_CURRENT_BINARY_DIR}/fmtlib-install" NO_DEFAULT_PATH)
161161
endif()
162162

163-
list(APPEND DWARFS_BOOST_MODULES chrono date_time filesystem program_options system)
163+
list(APPEND DWARFS_BOOST_MODULES chrono date_time filesystem iostreams program_options system)
164164

165165
if(WITH_PYTHON)
166166
# TODO: would be nicer to be able to support a range of python versions

include/dwarfs/mmap.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <cstddef>
2525
#include <string>
2626

27+
#include <boost/iostreams/device/mapped_file.hpp>
28+
2729
#include "dwarfs/mmif.h"
2830

2931
namespace dwarfs {
@@ -33,8 +35,6 @@ class mmap : public mmif {
3335
explicit mmap(const std::string& path);
3436
mmap(const std::string& path, size_t size);
3537

36-
~mmap() noexcept override;
37-
3838
void const* addr() const override;
3939
size_t size() const override;
4040

@@ -43,9 +43,9 @@ class mmap : public mmif {
4343
std::error_code release_until(off_t offset) override;
4444

4545
private:
46-
int fd_;
47-
size_t size_;
48-
void* addr_;
46+
boost::iostreams::mapped_file mutable mf_;
47+
#ifndef _WIN32
4948
off_t const page_size_;
49+
#endif
5050
};
5151
} // namespace dwarfs

src/dwarfs/mmap.cpp

Lines changed: 38 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,109 +19,84 @@
1919
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
2020
*/
2121

22+
#include <cassert>
2223
#include <cerrno>
2324

24-
#include <fcntl.h>
25+
#ifndef _WIN32
2526
#include <sys/mman.h>
26-
#include <sys/stat.h>
27-
#include <unistd.h>
28-
29-
#include <fmt/format.h>
27+
#endif
3028

3129
#include "dwarfs/error.h"
3230
#include "dwarfs/mmap.h"
3331

3432
namespace dwarfs {
3533

36-
namespace {
37-
38-
int safe_open(const std::string& path) {
39-
int fd = ::open(path.c_str(), O_RDONLY);
40-
41-
if (fd == -1) {
42-
DWARFS_THROW(system_error, fmt::format("open('{}')", path));
43-
}
44-
45-
return fd;
46-
}
47-
48-
size_t safe_size(int fd) {
49-
struct stat st;
50-
if (::fstat(fd, &st) == -1) {
51-
DWARFS_THROW(system_error, "fstat");
52-
}
53-
return st.st_size;
54-
}
55-
56-
void* safe_mmap(int fd, size_t size) {
57-
if (size == 0) {
58-
DWARFS_THROW(runtime_error, "empty file");
59-
}
60-
61-
void* addr = ::mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
62-
63-
if (addr == MAP_FAILED) {
64-
DWARFS_THROW(system_error, "mmap");
65-
}
66-
67-
return addr;
68-
}
69-
70-
} // namespace
71-
72-
std::error_code mmap::lock(off_t offset, size_t size) {
34+
std::error_code
35+
mmap::lock(off_t offset [[maybe_unused]], size_t size [[maybe_unused]]) {
7336
std::error_code ec;
74-
auto addr = reinterpret_cast<uint8_t*>(addr_) + offset;
75-
if (::mlock(addr, size) != 0) {
37+
38+
#ifndef _WIN32
39+
if (::mlock(mf_.const_data() + offset, size) != 0) {
7640
ec.assign(errno, std::generic_category());
7741
}
42+
#endif
43+
7844
return ec;
7945
}
8046

81-
std::error_code mmap::release(off_t offset, size_t size) {
47+
std::error_code
48+
mmap::release(off_t offset [[maybe_unused]], size_t size [[maybe_unused]]) {
8249
std::error_code ec;
50+
51+
#ifndef _WIN32
8352
auto misalign = offset % page_size_;
8453

8554
offset -= misalign;
8655
size += misalign;
8756
size -= size % page_size_;
8857

89-
auto addr = reinterpret_cast<uint8_t*>(addr_) + offset;
90-
if (::madvise(addr, size, MADV_DONTNEED) != 0) {
58+
if (::madvise(mf_.data() + offset, size, MADV_DONTNEED) != 0) {
9159
ec.assign(errno, std::generic_category());
9260
}
61+
#endif
62+
9363
return ec;
9464
}
9565

96-
std::error_code mmap::release_until(off_t offset) {
66+
std::error_code mmap::release_until(off_t offset [[maybe_unused]]) {
9767
std::error_code ec;
9868

69+
#ifndef _WIN32
9970
offset -= offset % page_size_;
10071

101-
if (::madvise(addr_, offset, MADV_DONTNEED) != 0) {
72+
if (::madvise(mf_.data(), offset, MADV_DONTNEED) != 0) {
10273
ec.assign(errno, std::generic_category());
10374
}
75+
#endif
76+
10477
return ec;
10578
}
10679

107-
void const* mmap::addr() const { return addr_; }
80+
void const* mmap::addr() const { return mf_.const_data(); }
10881

109-
size_t mmap::size() const { return size_; }
82+
size_t mmap::size() const { return mf_.size(); }
11083

11184
mmap::mmap(const std::string& path)
112-
: fd_(safe_open(path))
113-
, size_(safe_size(fd_))
114-
, addr_(safe_mmap(fd_, size_))
115-
, page_size_(::sysconf(_SC_PAGESIZE)) {}
85+
: mf_(path, boost::iostreams::mapped_file::readonly)
86+
#ifndef _WIN32
87+
, page_size_(::sysconf(_SC_PAGESIZE))
88+
#endif
89+
{
90+
assert(mf_.is_open());
91+
}
11692

11793
mmap::mmap(const std::string& path, size_t size)
118-
: fd_(safe_open(path))
119-
, size_(size)
120-
, addr_(safe_mmap(fd_, size_))
121-
, page_size_(::sysconf(_SC_PAGESIZE)) {}
122-
123-
mmap::~mmap() noexcept {
124-
::munmap(addr_, size_);
125-
::close(fd_);
94+
: mf_(path, boost::iostreams::mapped_file::readonly, size)
95+
#ifndef _WIN32
96+
, page_size_(::sysconf(_SC_PAGESIZE))
97+
#endif
98+
{
99+
assert(mf_.is_open());
126100
}
101+
127102
} // namespace dwarfs

0 commit comments

Comments
 (0)