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/sync/named_semaphore.hpp>
12 #include <boost/interprocess/detail/interprocess_tester.hpp>
13 #include <boost/interprocess/exceptions.hpp>
14 #include <boost/date_time/posix_time/posix_time_types.hpp>
15 #include "named_creation_template.hpp"
16 #include "mutex_test_template.hpp"
17 #include <string>
18 #include "get_process_id_name.hpp"
19
20 using namespace boost::interprocess;
21
22 static const std::size_t RecSemCount = 100;
23 static const char * SemName = test::get_process_id_name();
24
25 //This wrapper is necessary to plug this class
26 //in lock tests
27 class lock_test_wrapper
28 : public named_semaphore
29 {
30 public:
31
lock_test_wrapper(create_only_t,const char * name,unsigned int count=1)32 lock_test_wrapper(create_only_t, const char *name, unsigned int count = 1)
33 : named_semaphore(create_only, name, count)
34 {}
35
lock_test_wrapper(open_only_t,const char * name)36 lock_test_wrapper(open_only_t, const char *name)
37 : named_semaphore(open_only, name)
38 {}
39
lock_test_wrapper(open_or_create_t,const char * name,unsigned int count=1)40 lock_test_wrapper(open_or_create_t, const char *name, unsigned int count = 1)
41 : named_semaphore(open_or_create, name, count)
42 {}
43
~lock_test_wrapper()44 ~lock_test_wrapper()
45 {}
46
lock()47 void lock()
48 { this->wait(); }
49
try_lock()50 bool try_lock()
51 { return this->try_wait(); }
52
timed_lock(const boost::posix_time::ptime & pt)53 bool timed_lock(const boost::posix_time::ptime &pt)
54 { return this->timed_wait(pt); }
55
unlock()56 void unlock()
57 { this->post(); }
58 };
59
60 //This wrapper is necessary to plug this class
61 //in recursive tests
62 class recursive_test_wrapper
63 : public lock_test_wrapper
64 {
65 public:
recursive_test_wrapper(create_only_t,const char * name)66 recursive_test_wrapper(create_only_t, const char *name)
67 : lock_test_wrapper(create_only, name, RecSemCount)
68 {}
69
recursive_test_wrapper(open_only_t,const char * name)70 recursive_test_wrapper(open_only_t, const char *name)
71 : lock_test_wrapper(open_only, name)
72 {}
73
recursive_test_wrapper(open_or_create_t,const char * name)74 recursive_test_wrapper(open_or_create_t, const char *name)
75 : lock_test_wrapper(open_or_create, name, RecSemCount)
76 {}
77 };
78
test_named_semaphore_specific()79 bool test_named_semaphore_specific()
80 {
81 //Test persistance
82 {
83 named_semaphore sem(create_only, SemName, 3);
84 }
85 {
86 named_semaphore sem(open_only, SemName);
87 BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
88 BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
89 BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
90 BOOST_INTERPROCESS_CHECK(sem.try_wait() == false);
91 sem.post();
92 }
93 {
94 named_semaphore sem(open_only, SemName);
95 BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
96 BOOST_INTERPROCESS_CHECK(sem.try_wait() == false);
97 }
98
99 named_semaphore::remove(SemName);
100 return true;
101 }
102
main()103 int main ()
104 {
105 try{
106 named_semaphore::remove(SemName);
107 test::test_named_creation< test::named_sync_creation_test_wrapper<lock_test_wrapper> >();
108 test::test_all_lock< test::named_sync_wrapper<lock_test_wrapper> >();
109 test::test_all_mutex<test::named_sync_wrapper<lock_test_wrapper> >();
110 test::test_all_recursive_lock<test::named_sync_wrapper<recursive_test_wrapper> >();
111 test_named_semaphore_specific();
112 }
113 catch(std::exception &ex){
114 named_semaphore::remove(SemName);
115 std::cout << ex.what() << std::endl;
116 return 1;
117 }
118 named_semaphore::remove(SemName);
119 return 0;
120 }
121
122