From 5044feb835653ba98ee48cf243fe5d3ab184fa3c Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 3 Jun 2014 18:07:13 +0200 Subject: Implementing MMap for Linux, and fixing a few details. --- src/MMap.cc | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) (limited to 'src/MMap.cc') diff --git a/src/MMap.cc b/src/MMap.cc index 18187b4..a984f00 100644 --- a/src/MMap.cc +++ b/src/MMap.cc @@ -2,6 +2,12 @@ #ifdef _WIN32 #include +#else +#include +#include +#include +#include +#include #endif namespace Balau { @@ -28,7 +34,7 @@ class MMapPlatform { if (m_handle == INVALID_HANDLE_VALUE) return std::tie(result, m_ptr, s); - ScopedLambda hc([&]() { if (!result) CloseHandle(m_handle); }); + ScopedLambda hc([&]() { if (!result) CloseHandle(m_handle); m_handle = INVALID_HANDLE_VALUE; }); LARGE_INTEGER fsize; if (!GetFileSizeEx(m_handle, (PLARGE_INTEGER) &fsize)) @@ -42,7 +48,7 @@ class MMapPlatform { return std::tie(result, m_ptr, s); // than getting the usual INVALID_HANDLE_VALUE (which is -1), // in order to make a sane and uniform API... { - ScopedLambda mc([&]() { if (!result) CloseHandle(m_mapObject); }); + ScopedLambda mc([&]() { if (!result) CloseHandle(m_mapObject); m_mapObject = (HANDLE) NULL; }); // and of course, CreateFileMapping takes the 64 bits size in high / low format, // whereas MapViewOfFile takes the 64 bits size in a single 64 bits size_t. Sure. Makes sense. @@ -69,17 +75,56 @@ class MMapPlatform { const uint8_t * m_ptr = NULL; }; +#else + +class MMapPlatform { + public: + std::tuple open(const String & fname) { + bool result = false; + m_size = 0; + m_fd = ::open(fname.to_charp(), O_RDONLY); + + if (m_fd < 0) + return std::tie(result, m_ptr, m_size); + + ScopedLambda hc([&]() { if (!result) ::close(m_fd); m_fd = -1; }); + + m_size = lseek(m_fd, 0, SEEK_END); + lseek(m_fd, 0, SEEK_SET); + + if (m_size < 0) + return std::tie(result, m_ptr, m_size); + + m_ptr = (uint8_t *) mmap(NULL, m_size, PROT_READ, MAP_PRIVATE, m_fd, 0); + + result = !!m_ptr; + + return std::tie(result, m_ptr, m_size); + } + void close() { + if (m_ptr) + munmap(m_ptr, m_size); + if (m_fd >= 0) + ::close(m_fd); + m_ptr = NULL; + m_fd = -1; + } + int m_fd = -1; + uint8_t * m_ptr = NULL; + ssize_t m_size; +}; + #endif }; Balau::MMap::MMap(const char * fname) { m_fname = fname; - m_name.set("mmap of %s", m_fname); + m_name.set("mmap of %s", m_fname.to_charp()); m_platform = new MMapPlatform(); } -void Balau::MMap::open() { +void Balau::MMap::open() throw (GeneralException) { bool result; const uint8_t * ptr; size_t s; @@ -90,11 +135,12 @@ void Balau::MMap::open() { borrow(ptr, s); } -void Balau::MMap::close() { +void Balau::MMap::close() throw (GeneralException) { m_platform->close(); Buffer::close(); } Balau::MMap::~MMap() { + m_platform->close(); delete m_platform; } -- cgit v1.2.3