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 
11 #include <boost/interprocess/detail/config_begin.hpp>
12 #include <boost/interprocess/detail/workaround.hpp>
13 #include <boost/interprocess/sync/named_mutex.hpp>
14 #include <boost/interprocess/sync/named_condition.hpp>
15 #include <boost/interprocess/sync/detail/locks.hpp>
16 #include "condition_test_template.hpp"
17 #include "named_creation_template.hpp"
18 #include <string>
19 #include <sstream>
20 #include "get_process_id_name.hpp"
21 
22 using namespace boost::interprocess;
23 
24 struct condition_deleter
25 {
26    std::string name;
27 
~condition_deletercondition_deleter28    ~condition_deleter()
29    {
30       if(name.empty())
31          named_condition::remove(test::add_to_process_id_name("named_condition"));
32       else
33          named_condition::remove(name.c_str());
34    }
35 };
36 
num_to_string(int n)37 inline std::string num_to_string(int n)
38 {  std::stringstream s; s << n; return s.str(); }
39 
40 //This wrapper is necessary to have a default constructor
41 //in generic mutex_test_template functions
42 class named_condition_test_wrapper
43    : public condition_deleter, public named_condition
44 {
45    public:
46 
named_condition_test_wrapper()47    named_condition_test_wrapper()
48       :  named_condition(open_or_create,
49              (test::add_to_process_id_name("test_cond") + num_to_string(count)).c_str())
50    {
51       condition_deleter::name += test::add_to_process_id_name("test_cond");
52       condition_deleter::name += num_to_string(count);
53       ++count;
54    }
55 
~named_condition_test_wrapper()56    ~named_condition_test_wrapper()
57    {  --count; }
58 
59 
60    template <typename L>
wait(L & lock)61    void wait(L& lock)
62    {
63       ipcdetail::internal_mutex_lock<L> internal_lock(lock);
64       named_condition::wait(internal_lock);
65    }
66 
67    template <typename L, typename Pr>
wait(L & lock,Pr pred)68    void wait(L& lock, Pr pred)
69    {
70       ipcdetail::internal_mutex_lock<L> internal_lock(lock);
71       named_condition::wait(internal_lock, pred);
72    }
73 
74    template <typename L>
timed_wait(L & lock,const boost::posix_time::ptime & abs_time)75    bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
76    {
77       ipcdetail::internal_mutex_lock<L> internal_lock(lock);
78       return named_condition::timed_wait(internal_lock, abs_time);
79    }
80 
81    template <typename L, typename Pr>
timed_wait(L & lock,const boost::posix_time::ptime & abs_time,Pr pred)82    bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
83    {
84       ipcdetail::internal_mutex_lock<L> internal_lock(lock);
85       return named_condition::timed_wait(internal_lock, abs_time, pred);
86    }
87 
88    static int count;
89 };
90 
91 int named_condition_test_wrapper::count = 0;
92 
93 //This wrapper is necessary to have a common constructor
94 //in generic named_creation_template functions
95 class named_condition_creation_test_wrapper
96    : public condition_deleter, public named_condition
97 {
98    public:
named_condition_creation_test_wrapper(create_only_t)99    named_condition_creation_test_wrapper(create_only_t)
100       :  named_condition(create_only, test::add_to_process_id_name("named_condition"))
101    {  ++count_;   }
102 
named_condition_creation_test_wrapper(open_only_t)103    named_condition_creation_test_wrapper(open_only_t)
104       :  named_condition(open_only, test::add_to_process_id_name("named_condition"))
105    {  ++count_;   }
106 
named_condition_creation_test_wrapper(open_or_create_t)107    named_condition_creation_test_wrapper(open_or_create_t)
108       :  named_condition(open_or_create, test::add_to_process_id_name("named_condition"))
109    {  ++count_;   }
110 
~named_condition_creation_test_wrapper()111    ~named_condition_creation_test_wrapper()   {
112       if(--count_){
113          ipcdetail::interprocess_tester::
114             dont_close_on_destruction(static_cast<named_condition&>(*this));
115       }
116    }
117    static int count_;
118 };
119 
120 int named_condition_creation_test_wrapper::count_ = 0;
121 
122 struct mutex_deleter
123 {
124    std::string name;
125 
~mutex_deletermutex_deleter126    ~mutex_deleter()
127    {
128       if(name.empty())
129          named_mutex::remove(test::add_to_process_id_name("named_mutex"));
130       else
131          named_mutex::remove(name.c_str());
132    }
133 };
134 
135 //This wrapper is necessary to have a default constructor
136 //in generic mutex_test_template functions
137 class named_mutex_test_wrapper
138    : public mutex_deleter, public named_mutex
139 {
140    public:
named_mutex_test_wrapper()141    named_mutex_test_wrapper()
142       :  named_mutex(open_or_create,
143              (test::add_to_process_id_name("test_mutex") + num_to_string(count)).c_str())
144    {
145       mutex_deleter::name += test::add_to_process_id_name("test_mutex");
146       mutex_deleter::name += num_to_string(count);
147       ++count;
148    }
149 
150    typedef named_mutex internal_mutex_type;
151 
internal_mutex()152    internal_mutex_type &internal_mutex()
153    {  return *this;  }
154 
~named_mutex_test_wrapper()155    ~named_mutex_test_wrapper()
156    {  --count; }
157 
158    static int count;
159 };
160 
161 int named_mutex_test_wrapper::count = 0;
162 
main()163 int main ()
164 {
165    try{
166       //Remove previous mutexes and conditions
167       named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
168       named_condition::remove(test::add_to_process_id_name("test_cond0"));
169       named_condition::remove(test::add_to_process_id_name("test_cond1"));
170       named_condition::remove(test::add_to_process_id_name("named_condition"));
171       named_mutex::remove(test::add_to_process_id_name("named_mutex"));
172 
173       test::test_named_creation<named_condition_creation_test_wrapper>();
174       test::do_test_condition<named_condition_test_wrapper
175                              ,named_mutex_test_wrapper>();
176    }
177    catch(std::exception &ex){
178       std::cout << ex.what() << std::endl;
179       return 1;
180    }
181    named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
182    named_condition::remove(test::add_to_process_id_name("test_cond0"));
183    named_condition::remove(test::add_to_process_id_name("test_cond1"));
184    named_condition::remove(test::add_to_process_id_name("named_condition"));
185    named_mutex::remove(test::add_to_process_id_name("named_mutex"));
186    return 0;
187 }
188 
189 #include <boost/interprocess/detail/config_end.hpp>
190