managed_mapped_file_test.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #include <boost/interprocess/detail/config_begin.hpp>
  11. #include <boost/interprocess/detail/workaround.hpp>
  12. #if defined(BOOST_INTERPROCESS_MAPPED_FILES)
  13. #include <boost/interprocess/allocators/allocator.hpp>
  14. #include <boost/interprocess/containers/vector.hpp>
  15. #include <boost/interprocess/managed_mapped_file.hpp>
  16. #include <cstdio>
  17. #include <string>
  18. #include "get_process_id_name.hpp"
  19. using namespace boost::interprocess;
  20. inline std::string get_filename()
  21. {
  22. std::string ret (ipcdetail::get_temporary_path());
  23. ret += "/";
  24. ret += test::get_process_id_name();
  25. return ret;
  26. }
  27. int main ()
  28. {
  29. const int FileSize = 65536*10;
  30. std::string filename(get_filename());
  31. const char *FileName = filename.c_str();
  32. //STL compatible allocator object for memory-mapped file
  33. typedef allocator<int, managed_mapped_file::segment_manager>
  34. allocator_int_t;
  35. //A vector that uses that allocator
  36. typedef boost::interprocess::vector<int, allocator_int_t> MyVect;
  37. {
  38. //Remove the file it is already created
  39. file_mapping::remove(FileName);
  40. const int max = 100;
  41. void *array[max];
  42. //Named allocate capable shared memory allocator
  43. managed_mapped_file mfile(create_only, FileName, FileSize);
  44. int i;
  45. //Let's allocate some memory
  46. for(i = 0; i < max; ++i){
  47. array[i] = mfile.allocate(i+1);
  48. }
  49. //Deallocate allocated memory
  50. for(i = 0; i < max; ++i){
  51. mfile.deallocate(array[i]);
  52. }
  53. }
  54. {
  55. //Remove the file it is already created
  56. file_mapping::remove(FileName);
  57. //Named allocate capable memory mapped file managed memory class
  58. managed_mapped_file mfile(create_only, FileName, FileSize);
  59. //Construct the STL-like allocator with the segment manager
  60. const allocator_int_t myallocator (mfile.get_segment_manager());
  61. //Construct vector
  62. MyVect *mfile_vect = mfile.construct<MyVect> ("MyVector") (myallocator);
  63. //Test that vector can be found via name
  64. if(mfile_vect != mfile.find<MyVect>("MyVector").first)
  65. return -1;
  66. //Destroy and check it is not present
  67. mfile.destroy<MyVect> ("MyVector");
  68. if(0 != mfile.find<MyVect>("MyVector").first)
  69. return -1;
  70. //Construct a vector in the memory-mapped file
  71. mfile_vect = mfile.construct<MyVect> ("MyVector") (myallocator);
  72. //Flush cached data from memory-mapped file to disk
  73. mfile.flush();
  74. }
  75. {
  76. //Map preexisting file again in memory
  77. managed_mapped_file mfile(open_only, FileName);
  78. //Check vector is still there
  79. MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
  80. if(!mfile_vect)
  81. return -1;
  82. }
  83. {
  84. {
  85. //Map preexisting file again in copy-on-write
  86. managed_mapped_file mfile(open_copy_on_write, FileName);
  87. //Check vector is still there
  88. MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
  89. if(!mfile_vect)
  90. return -1;
  91. //Erase vector
  92. mfile.destroy_ptr(mfile_vect);
  93. //Make sure vector is erased
  94. mfile_vect = mfile.find<MyVect>("MyVector").first;
  95. if(mfile_vect)
  96. return -1;
  97. }
  98. //Now check vector is still in the file
  99. {
  100. //Map preexisting file again in copy-on-write
  101. managed_mapped_file mfile(open_copy_on_write, FileName);
  102. //Check vector is still there
  103. MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
  104. if(!mfile_vect)
  105. return -1;
  106. }
  107. }
  108. {
  109. //Map preexisting file again in copy-on-write
  110. managed_mapped_file mfile(open_read_only, FileName);
  111. //Check vector is still there
  112. MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
  113. if(!mfile_vect)
  114. return -1;
  115. }
  116. {
  117. managed_mapped_file::size_type old_free_memory;
  118. {
  119. //Map preexisting file again in memory
  120. managed_mapped_file mfile(open_only, FileName);
  121. old_free_memory = mfile.get_free_memory();
  122. }
  123. //Now grow the file
  124. managed_mapped_file::grow(FileName, FileSize);
  125. //Map preexisting file again in memory
  126. managed_mapped_file mfile(open_only, FileName);
  127. //Check vector is still there
  128. MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
  129. if(!mfile_vect)
  130. return -1;
  131. if(mfile.get_size() != (FileSize*2))
  132. return -1;
  133. if(mfile.get_free_memory() <= old_free_memory)
  134. return -1;
  135. }
  136. {
  137. managed_mapped_file::size_type old_free_memory, next_free_memory,
  138. old_file_size, next_file_size, final_file_size;
  139. {
  140. //Map preexisting file again in memory
  141. managed_mapped_file mfile(open_only, FileName);
  142. old_free_memory = mfile.get_free_memory();
  143. old_file_size = mfile.get_size();
  144. }
  145. //Now shrink the file
  146. managed_mapped_file::shrink_to_fit(FileName);
  147. {
  148. //Map preexisting file again in memory
  149. managed_mapped_file mfile(open_only, FileName);
  150. next_file_size = mfile.get_size();
  151. //Check vector is still there
  152. MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
  153. if(!mfile_vect)
  154. return -1;
  155. next_free_memory = mfile.get_free_memory();
  156. if(next_free_memory >= old_free_memory)
  157. return -1;
  158. if(old_file_size <= next_file_size)
  159. return -1;
  160. }
  161. //Now destroy the vector
  162. {
  163. //Map preexisting file again in memory
  164. managed_mapped_file mfile(open_only, FileName);
  165. //Destroy and check it is not present
  166. mfile.destroy<MyVect>("MyVector");
  167. if(0 != mfile.find<MyVect>("MyVector").first)
  168. return -1;
  169. }
  170. //Now shrink the file
  171. managed_mapped_file::shrink_to_fit(FileName);
  172. {
  173. //Map preexisting file again in memory
  174. managed_mapped_file mfile(open_only, FileName);
  175. final_file_size = mfile.get_size();
  176. if(next_file_size <= final_file_size)
  177. return -1;
  178. }
  179. {
  180. //Now test move semantics
  181. managed_mapped_file original(open_only, FileName);
  182. managed_mapped_file move_ctor(boost::move(original));
  183. managed_mapped_file move_assign;
  184. move_assign = boost::move(move_ctor);
  185. move_assign.swap(original);
  186. }
  187. }
  188. file_mapping::remove(FileName);
  189. return 0;
  190. }
  191. #else //#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
  192. int main()
  193. {
  194. return 0;
  195. }
  196. #endif//#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
  197. #include <boost/interprocess/detail/config_end.hpp>