noexcept mapped_file constructors.

This commit is contained in:
Kelvin Sherlock 2016-08-09 14:40:27 -04:00
parent f3db9b7cc0
commit 34a4f431c0
3 changed files with 68 additions and 54 deletions

View File

@ -23,17 +23,12 @@ namespace {
FX _fx; FX _fx;
}; };
void throw_error(int error) {
throw std::system_error(error, std::system_category()); void set_or_throw_error(std::error_code *ec, int error, const std::string &what) {
if (ec) *ec = std::error_code(error, std::system_category());
else throw std::system_error(error, std::system_category(), what);
} }
void throw_error(int error, const std::string &what) {
throw std::system_error(error, std::system_category(), what);
}
} }
#ifdef _WIN32 #ifdef _WIN32
@ -41,12 +36,8 @@ namespace {
namespace { namespace {
void throw_error() { void set_or_throw_error(std::error_code *ec, const std::string &what) {
throw_error(GetLastError()); set_or_throw_error(ec, GetLastError(), what);
}
void throw_error(const std::string &what) {
throw_error(GetLastError(), what);
} }
} }
@ -61,7 +52,7 @@ void mapped_file_base::close() {
} }
} }
void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, size_t offset) { void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
HANDLE fh; HANDLE fh;
@ -70,9 +61,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
// length of 0 in CreateFileMapping / MapViewOfFile // length of 0 in CreateFileMapping / MapViewOfFile
// means map the entire file. // means map the entire file.
if (is_open()) { if (is_open()) close();
throw std::runtime_error("mapped_file_base::open - file already open");
}
fh = CreateFile(p.c_str(), fh = CreateFile(p.c_str(),
flags == readonly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, flags == readonly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
@ -83,7 +72,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
nullptr nullptr
); );
if (fh == INVALID_HANDLE_VALUE) { if (fh == INVALID_HANDLE_VALUE) {
throw_error(); return set_or_throw_error(ec, "CreateFile");
} }
auto fh_close = make_unique_resource(fh, CloseHandle); auto fh_close = make_unique_resource(fh, CloseHandle);
@ -116,7 +105,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
mh = CreateFileMapping(fh, nullptr, protect, 0, 0, 0); mh = CreateFileMapping(fh, nullptr, protect, 0, 0, 0);
if (mh == INVALID_HANDLE_VALUE) { if (mh == INVALID_HANDLE_VALUE) {
throw_error(); return set_or_throw_error(ec, "CreateFileMapping");
} }
auto mh_close = make_unique_resource(mh, CloseHandle); auto mh_close = make_unique_resource(mh, CloseHandle);
@ -129,7 +118,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
length, length,
nullptr); nullptr);
if (!_data) { if (!_data) {
throw_error(); return set_or_throw_error(ec, "MapViewOfFileEx");
} }
@ -152,10 +141,7 @@ void mapped_file_base::create(const path_type& p, size_t length) {
const DWORD access = FILE_MAP_WRITE; const DWORD access = FILE_MAP_WRITE;
if (is_open()) { if (is_open()) close();
throw std::runtime_error("mapped_file_base::create - file already open");
}
fh = CreateFile(p.c_str(), fh = CreateFile(p.c_str(),
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
@ -166,7 +152,7 @@ void mapped_file_base::create(const path_type& p, size_t length) {
nullptr nullptr
); );
if (fh == INVALID_HANDLE_VALUE) { if (fh == INVALID_HANDLE_VALUE) {
throw_error(); return set_or_throw_error(nullptr, "CreateFile");
} }
auto fh_close = make_unique_resource(fh, CloseHandle); auto fh_close = make_unique_resource(fh, CloseHandle);
@ -174,11 +160,11 @@ void mapped_file_base::create(const path_type& p, size_t length) {
file_size.QuadPart = length; file_size.QuadPart = length;
if (!SetFilePointerEx(fh, file_size, nullptr, FILE_BEGIN)); if (!SetFilePointerEx(fh, file_size, nullptr, FILE_BEGIN));
if (!SetEndOfFile(fh)) throw_error(); if (!SetEndOfFile(fh)) return set_or_throw_error(nullptr, "SetEndOfFile");
mh = CreateFileMapping(fh, nullptr, protect, 0, 0, 0); mh = CreateFileMapping(fh, nullptr, protect, 0, 0, 0);
if (mh == INVALID_HANDLE_VALUE) { if (mh == INVALID_HANDLE_VALUE) {
throw_error(); return set_or_throw_error(nullptr, "CreateFileMapping");
} }
auto mh_close = make_unique_resource(mh, CloseHandle); auto mh_close = make_unique_resource(mh, CloseHandle);
@ -191,7 +177,7 @@ void mapped_file_base::create(const path_type& p, size_t length) {
nullptr); nullptr);
if (!_data) { if (!_data) {
throw_error(); return set_or_throw_error(nullptr, "MapViewOfFileEx");
} }
_file_handle = fh_close.release(); _file_handle = fh_close.release();
@ -213,13 +199,10 @@ void mapped_file_base::create(const path_type& p, size_t length) {
namespace { namespace {
void throw_error() { void set_or_throw_error(std::error_code *ec, const std::string &what) {
throw_error(errno); set_or_throw_error(ec, errno, what);
} }
void throw_error(const std::string &what) {
throw_error(errno, what);
}
} }
@ -232,15 +215,15 @@ void mapped_file_base::close() {
} }
void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, size_t offset) { void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, size_t offset, std::error_code *ec) {
if (ec) ec->clear();
int fd; int fd;
int oflags = 0; int oflags = 0;
if (is_open()) { if (is_open()) close();
throw std::runtime_error("mapped_file_base::open - file already open");
}
switch (flags) { switch (flags) {
case readonly: case readonly:
@ -253,7 +236,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
fd = ::open(p.c_str(), oflags); fd = ::open(p.c_str(), oflags);
if (fd < 0) { if (fd < 0) {
throw_error(errno); return set_or_throw_error(ec, "open");
} }
//defer([fd](){::close(fd); }); //defer([fd](){::close(fd); });
@ -265,7 +248,8 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
struct stat st; struct stat st;
if (::fstat(fd, &st) < 0) { if (::fstat(fd, &st) < 0) {
throw_error(errno); set_or_throw_error(ec, "stat");
return;
} }
length = st.st_size; length = st.st_size;
} }
@ -279,7 +263,7 @@ void mapped_file_base::open(const path_type& p, mapmode flags, size_t length, si
if (_data == MAP_FAILED) { if (_data == MAP_FAILED) {
_data = nullptr; _data = nullptr;
throw_error(errno); return set_or_throw_error(ec, "mmap");
} }
_fd = close_fd.release(); _fd = close_fd.release();
@ -292,15 +276,11 @@ void mapped_file_base::create(const path_type& p, size_t length) {
int fd; int fd;
const size_t offset = 0; const size_t offset = 0;
if (is_open()) { if (is_open()) close();
throw std::runtime_error("mapped_file_base::create - file already open");
}
fd = ::open(p.c_str(), O_RDWR | O_CREAT | O_TRUNC); fd = ::open(p.c_str(), O_RDWR | O_CREAT | O_TRUNC);
if (fd < 0) { if (fd < 0) {
throw_error(errno); return set_or_throw_error(nullptr, "open");
} }
//defer([fd](){::close(fd); }); //defer([fd](){::close(fd); });
@ -309,7 +289,7 @@ void mapped_file_base::create(const path_type& p, size_t length) {
if (::ftruncate(fd, length) < 0) { if (::ftruncate(fd, length) < 0) {
throw_error(errno); return set_or_throw_error(nullptr, "ftruncate");
} }
@ -320,7 +300,7 @@ void mapped_file_base::create(const path_type& p, size_t length) {
if (_data == MAP_FAILED) { if (_data == MAP_FAILED) {
_data = nullptr; _data = nullptr;
throw_error(errno); return set_or_throw_error(nullptr, "mmap");
} }
_fd = close_fd.release(); _fd = close_fd.release();

View File

@ -8,7 +8,7 @@
#endif #endif
#include <cstddef> #include <cstddef>
#include <system_error>
class mapped_file_base { class mapped_file_base {
public: public:
@ -40,7 +40,7 @@ protected:
void swap(mapped_file_base &rhs); void swap(mapped_file_base &rhs);
void open(const path_type& p, mapmode flags, size_t length, size_t offset); void open(const path_type& p, mapmode flags, size_t length, size_t offset, std::error_code *ec);
void create(const path_type &p, size_t new_size); // always creates readwrite. void create(const path_type &p, size_t new_size); // always creates readwrite.
void reset(); void reset();
@ -79,6 +79,22 @@ public:
open(p, flags, length, offset); open(p, flags, length, offset);
} }
mapped_file(const path_type &p, std::error_code &ec) noexcept {
open(p, readonly, -1, 0, ec);
}
mapped_file(const path_type &p, mapmode flags, std::error_code &ec) noexcept {
open(p, flags, -1, 0, ec);
}
mapped_file(const path_type &p, mapmode flags, size_t length, std::error_code &ec) noexcept {
open(p, flags, length, 0, ec);
}
mapped_file(const path_type &p, mapmode flags, size_t length, size_t offset, std::error_code &ec) noexcept {
open(p, flags, length, offset, ec);
}
mapped_file(mapped_file &&); mapped_file(mapped_file &&);
mapped_file(const mapped_file &) = delete; mapped_file(const mapped_file &) = delete;
@ -87,7 +103,20 @@ public:
void open(const path_type& p, mapmode flags, size_t length = -1, size_t offset = 0) { void open(const path_type& p, mapmode flags, size_t length = -1, size_t offset = 0) {
base::open(p, flags, length, offset); base::open(p, flags, length, offset, nullptr);
}
void open(const path_type &p, std::error_code &ec) noexcept {
base::open(p, readonly, -1, 0, &ec);
}
void open(const path_type &p, mapmode flags, std::error_code &ec) noexcept {
base::open(p, flags, -1, 0, &ec);
}
void open(const path_type &p, mapmode flags, size_t length, std::error_code &ec) noexcept {
base::open(p, flags, length, 0, &ec);
}
void open(const path_type &p, mapmode flags, size_t length, size_t offset, std::error_code &ec) noexcept {
base::open(p, flags, length, offset, &ec);
} }

View File

@ -81,7 +81,12 @@ void init(Environment &env) {
int read_file(phase1 &p, const std::string &file) { int read_file(phase1 &p, const std::string &file) {
const mapped_file mf(file, mapped_file::readonly); std::error_code ec;
const mapped_file mf(file, mapped_file::readonly, ec);
if (ec) {
fprintf(stderr, "# Error reading %s: %s\n", file.c_str(), ec.message().c_str());
return 0;
}
p.process(mf.begin(), mf.end(), false); p.process(mf.begin(), mf.end(), false);
p.finish(); p.finish();