| 1 | #include <boost/filesystem/operations.hpp>
|
|---|
| 2 | namespace fs = boost::filesystem;
|
|---|
| 3 |
|
|---|
| 4 | #include <boost/interprocess/containers/string.hpp>
|
|---|
| 5 | #include <boost/interprocess/managed_mapped_file.hpp>
|
|---|
| 6 | #include <boost/interprocess/indexes/flat_map_index.hpp>
|
|---|
| 7 | #include <boost/interprocess/containers/vector.hpp>
|
|---|
| 8 | namespace ip = boost::interprocess;
|
|---|
| 9 |
|
|---|
| 10 | typedef ip::basic_managed_mapped_file<char, ip::rbtree_best_fit<ip::null_mutex_family>, ip::flat_map_index> mfile_object;
|
|---|
| 11 | typedef mfile_object::segment_manager SegmentManager;
|
|---|
| 12 |
|
|---|
| 13 | class Node
|
|---|
| 14 | {
|
|---|
| 15 | public:
|
|---|
| 16 | typedef ip::allocator<Node, SegmentManager> NodeAllocator;
|
|---|
| 17 | typedef ip::vector<Node, NodeAllocator> NodeVector;
|
|---|
| 18 |
|
|---|
| 19 | explicit Node(const NodeAllocator& allocator) : nodes_(allocator) {}
|
|---|
| 20 |
|
|---|
| 21 | NodeVector nodes_;
|
|---|
| 22 | };
|
|---|
| 23 |
|
|---|
| 24 | // Create a chunk of shared memory on disk (memory mapped file) consisting of multiple nodes in a tree-like structure.
|
|---|
| 25 | // Test shared memory file creation on Windows 7, VS2010 and VS2013, Boost 1.55.0 vs Boost 1.56.0, x64
|
|---|
| 26 | // Test works fine on Boost 1.55.0 (and presumably before since this example is based on our existing code), crashes on Boost 1.56.0.
|
|---|
| 27 | // Using vector reserve(SIZE) fixes the crash for this example.
|
|---|
| 28 | // Error reported: Assertion failed: ptr != 0, file D:\boost64\include\boost-1_56\boost/interprocess/allocators/allocator.hpp, line 268
|
|---|
| 29 | int main(int argc, char* argv[])
|
|---|
| 30 | {
|
|---|
| 31 | const std::string filePath = "test.mmf";
|
|---|
| 32 | if (fs::exists(filePath))
|
|---|
| 33 | fs::remove(filePath);
|
|---|
| 34 |
|
|---|
| 35 | const unsigned int size = 256 * 1024;
|
|---|
| 36 | mfile_object* mmf = new mfile_object(ip::open_or_create, filePath.c_str(), size);
|
|---|
| 37 |
|
|---|
| 38 | Node::NodeAllocator allocator(mmf->get_segment_manager());
|
|---|
| 39 | Node *rootNode = mmf->construct<Node>(ip::unique_instance)(allocator);
|
|---|
| 40 |
|
|---|
| 41 | // Breaks at 43 during testing (42 and below is fine for this example).
|
|---|
| 42 | const int MaxItems = 43;
|
|---|
| 43 |
|
|---|
| 44 | // [NOTE: reserving required space prevents crash in this case] rootNode->nodes_.reserve(MaxItems);
|
|---|
| 45 | for (int i = 0; i < MaxItems; ++i)
|
|---|
| 46 | {
|
|---|
| 47 | rootNode->nodes_.push_back(Node(allocator));
|
|---|
| 48 | for (int j = 0; j < MaxItems; ++j)
|
|---|
| 49 | rootNode->nodes_.back().nodes_.push_back(Node(allocator));
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | mmf->flush();
|
|---|
| 53 | delete mmf;
|
|---|
| 54 | mfile_object::shrink_to_fit(filePath.c_str());
|
|---|
| 55 | return 0;
|
|---|
| 56 | }
|
|---|