diff --git a/README.md b/README.md index c3287a0..217ab7f 100644 --- a/README.md +++ b/README.md @@ -113,14 +113,15 @@ int main() const int answer_index = rw_mmap.size() / 2; rw_mmap[answer_index] = 42; - // Don't forget to flush changes to disk, which is NOT done by the destructor for - // more explicit control of this potentially expensive operation. + // Don't forget to flush changes to disk before unmapping. However, if + // `rw_mmap` were to go out of scope at this point, the destructor would also + // automatically invoke `sync` before `unmap`. rw_mmap.sync(error); if (error) { return handle_error(error); } // We can then remove the mapping, after which rw_mmap will be in a default - // constructed state, i.e. this has the same effect as if the destructor had been - // invoked. + // constructed state, i.e. this and the above call to `sync` have the same + // effect as if the destructor had been invoked. rw_mmap.unmap(); // Now create the same mapping, but in read-only mode. diff --git a/include/mio/mmap.hpp b/include/mio/mmap.hpp index 855fefa..91b2f63 100644 --- a/include/mio/mmap.hpp +++ b/include/mio/mmap.hpp @@ -135,7 +135,10 @@ public: basic_mmap& operator=(const basic_mmap&) = delete; basic_mmap& operator=(basic_mmap&&); - /** The destructor invokes unmap. */ + /** + * If this is a read-write mapping, the destructor invokes sync. Regardless + * of the access mode, unmap is invoked as a final step. + */ ~basic_mmap(); /** diff --git a/include/mio/shared_mmap.hpp b/include/mio/shared_mmap.hpp index 7dcf74b..ba7e1e0 100644 --- a/include/mio/shared_mmap.hpp +++ b/include/mio/shared_mmap.hpp @@ -110,6 +110,11 @@ public: if(error) { throw error; } } + /** + * If this is a read-write mapping and the last reference to the mapping, + * the destructor invokes sync. Regardless of the access mode, unmap is + * invoked as a final step. + */ ~basic_shared_mmap() = default; /** Returns the underlying `std::shared_ptr` instance that holds the mmap. */ diff --git a/test/example.cpp b/test/example.cpp index efeb67a..2f08b1b 100644 --- a/test/example.cpp +++ b/test/example.cpp @@ -49,14 +49,15 @@ int main() const int answer_index = rw_mmap.size() / 2; rw_mmap[answer_index] = 42; - // Don't forget to flush changes to disk, which is NOT done by the destructor for - // more explicit control of this potentially expensive operation. + // Don't forget to flush changes to disk before unmapping. However, if + // `rw_mmap` were to go out of scope at this point, the destructor would also + // automatically invoke `sync` before `unmap`. rw_mmap.sync(error); if (error) { return handle_error(error); } // We can then remove the mapping, after which rw_mmap will be in a default - // constructed state, i.e. this has the same effect as if the destructor had been - // invoked. + // constructed state, i.e. this and the above call to `sync` have the same + // effect as if the destructor had been invoked. rw_mmap.unmap(); // Now create the same mapping, but in read-only mode.