Line data Source code
1 : //
2 : // Author: Vladimir Migashko <migashko@gmail.com>, (C) 2012
3 : //
4 : // Copyright: See COPYING file that comes with this distribution
5 : //
6 :
7 : #ifndef VSET_VSET_BUFFER_PERSISTENT_MMAP_AD_OPEN_HPP
8 : #define VSET_VSET_BUFFER_PERSISTENT_MMAP_AD_OPEN_HPP
9 :
10 : #include <fas/system/nullptr.hpp>
11 : #include <vset/buffer/tags.hpp>
12 : #include <vset/buffer/persistent/tags.hpp>
13 : #include <vset/buffer/persistent/mmap/tags.hpp>
14 : #include <string.h>
15 : #include <string>
16 : #include <stdexcept>
17 :
18 : #include <unistd.h>
19 : #include <sys/mman.h>
20 :
21 :
22 : namespace vset { namespace buffer { namespace persistent{ namespace mmap{
23 :
24 : struct ad_open
25 : {
26 9 : ad_open(){}
27 :
28 : template<typename T>
29 : void operator()( T& t)
30 : {
31 : std::string file_name = t.get_aspect().template get<_file_name_>();
32 : this->operator()(t, file_name );
33 : }
34 :
35 : template<typename T>
36 12 : void operator()( T& t, const std::string& file_name)
37 : {
38 12 : t.get_aspect().template get<_close_>()(t);
39 12 : t.get_aspect().template get<_file_name_>() = file_name;
40 12 : t.get_aspect().template get<_open_file_>()(t);
41 :
42 12 : size_t file_size = t.get_aspect().template get<_file_size_>()(t);
43 : typedef typename T::aspect::template advice_cast<_head_type_>::type head_type;
44 :
45 12 : bool is_created = file_size < sizeof(head_type);
46 12 : if ( is_created )
47 : {
48 7 : file_size = sizeof(head_type);
49 7 : t.get_aspect().template get<_resize_file_>()(t, file_size);
50 : }
51 :
52 : char* data = static_cast<char*>( ::mmap(
53 : fas_nullptr,
54 : file_size,
55 : PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE | MAP_POPULATE,
56 : t.get_aspect().template get<_descriptor_>(),
57 : 0
58 12 : ) );
59 :
60 12 : if ( data == MAP_FAILED)
61 0 : throw std::runtime_error(strerror(errno));
62 :
63 12 : if ( is_created )
64 7 : ::memset(data, 0, file_size);
65 :
66 12 : t.get_aspect().template get<_buffer_size_>() = file_size;
67 12 : t.get_aspect().template get<_buffer_>() = data;
68 12 : head_type* head = t.get_aspect().template get<_head_>()(t);
69 :
70 12 : if ( is_created )
71 7 : *head = head_type();
72 :
73 12 : t.get_aspect().template get<_size_value_>() = head->size();
74 12 : t.get_aspect().template get<_capacity_value_>() = head->capacity();
75 12 : }
76 : };
77 :
78 : }}}}
79 :
80 : #endif
|