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 | }
|
---|