1010#include < memory>
1111#include < ctime>
1212
13+ class concurrency_test_runnable : public pthread ::abstract_thread {
14+ public:
15+
16+ void run () noexcept override {
17+ pthread::lock_guard<pthread::mutex> lock{*_mutex};
18+ pthread::this_thread::sleep_for (2 * 1000 );
19+ }
20+
21+ concurrency_test_runnable (pthread::mutex *mutex) : _something{0 }, _mutex{mutex} {
22+ // intentional
23+ }
24+
25+ void set_something (const int something){
26+ pthread::lock_guard<pthread::write_lock> lock (_properties_accessor_lock);
27+ _something = something;
28+ }
29+
30+ const int something (){
31+ pthread::lock_guard<pthread::read_lock> lock (_properties_accessor_lock);
32+ return _something;
33+ }
34+
35+ private:
36+
37+ int _something;
38+ pthread::mutex *_mutex;
39+ pthread::read_write_lock _properties_accessor_lock;
40+ };
41+
1342TEST (concurrency, mutex) {
1443
15- bool success = false ;
44+ bool success = false ;
1645
17- pthread::mutex mutex;
18- try {
19- pthread::lock_guard<pthread::mutex> lock (mutex);
20- success = true ;
21- } catch ( std::exception &err) {
22- std::cerr << " something went wrong: " << err.what () << std::endl;
23- }catch ( ... ){
24- std::cerr << " something went wrong, unexpected exception catched." << std::endl;
25- }
46+ pthread::mutex mutex;
47+ concurrency_test_runnable mtr{&mutex};
48+ mtr.start ();
2649
27- EXPECT_TRUE (success);
50+ pthread::this_thread::sleep_for (500 ); // just to let time to startup the thread.
51+
52+ EXPECT_FALSE (mutex.try_lock ()); // return false, because the test thread has already locked the mutex
53+ EXPECT_NO_THROW (pthread::lock_guard<pthread::mutex> lock (mutex));
54+ EXPECT_TRUE (mutex.try_lock ()); // the test thread has ended and the lock can be aquired again
55+
56+ mtr.join ();
2857}
2958
3059TEST (concurrency, read_write_lock) {
31- bool success = false ;
60+ bool success = false ;
61+
62+ try {
63+ pthread::mutex mutex;
3264
33- try {
65+ concurrency_test_runnable thread{&mutex};
66+ thread.start ();
3467
35- pthread::read_write_lock _rwlock;
68+ thread.set_something (1000 );
69+ EXPECT_EQ (1000 , thread.something ());
3670
37- {
38- pthread::lock_guard<pthread::read_lock> lock (_rwlock);
71+ pthread::read_write_lock _rwlock;
3972
40- // std::cout << "read locked" << std::endl;
41- }
73+ {
74+ pthread::lock_guard<pthread::read_lock> lock (_rwlock);
4275
43- {
44- pthread::lock_guard<pthread::write_lock> lock (_rwlock);
45- // std::cout << "write locked" << std::endl;
46- }
76+ }
4777
48- success = true ;
78+ {
79+ pthread::lock_guard<pthread::write_lock> lock (_rwlock);
80+ }
4981
50- }catch (std::exception &err ){
51- std::cerr << __FILE__ << " (at:" << __LINE__ << " )" << err.what () << std::endl;
52- }
82+ thread.join ();
5383
54- EXPECT_TRUE (success);
84+ success = true ;
85+
86+ } catch (std::exception &err) {
87+ std::cerr << __FILE__ << " (at:" << __LINE__ << " )" << err.what () << std::endl;
88+ }
89+
90+ EXPECT_TRUE (success);
5591}
5692
5793TEST (concurrency, try_read_write_lock) {
58- bool success = false ;
94+ bool success = false ;
5995
6096 try {
6197
@@ -66,50 +102,54 @@ TEST(concurrency, try_read_write_lock) {
66102
67103 success = true ;
68104
69- }catch ( const std::exception &err ) {
105+ } catch (const std::exception &err) {
70106 std::cerr << err.what () << std::endl << std::flush;
71107 }
72108
73109 EXPECT_TRUE (success);
74110}
75111
76- TEST (concurrency, condition_variable_wait_for){
112+ TEST (concurrency, condition_variable_wait_for) {
77113 pthread::condition_variable condition;
78- pthread::mutex mutex;
79- bool stop_waiting = true ;
114+ pthread::mutex mutex;
115+ bool stop_waiting = true ;
80116
81117 /* wait 1s for condition to be signaled. When returning from the wait_for method call, the mutex is locked.
82118 *
83119 * Therefore we expect, try_lock to throw an exception to signal that the mutex is already locked.
84120 */
85- EXPECT_EQ (pthread::cv_status::timedout, condition.wait_for (mutex, 1 * 1000 ));
86- EXPECT_THROW (mutex.try_lock (), pthread::pthread_exception );
121+ EXPECT_EQ (pthread::cv_status::timedout, condition.wait_for (mutex, 1 * 1000 ));
122+ EXPECT_FALSE (mutex.try_lock ());
87123 mutex.unlock (); // free to lock
88124
125+ EXPECT_NO_THROW (condition.notify_all ());
126+ EXPECT_NO_THROW (condition.notify_one ());
127+
89128 {
90129 pthread::lock_guard<pthread::mutex> lock{mutex};
91130 EXPECT_EQ (pthread::cv_status::timedout, condition.wait_for (lock, 1 * 1000 ));
92131 }
93132
94133 {
95134 pthread::lock_guard<pthread::mutex> lock{mutex};
96- EXPECT_EQ (true , condition.wait_for (lock, 1 * 1000 , [stop_waiting]{
97- std::cout << " running lambda, stop_waiting : " << stop_waiting << std::endl ;
98- return stop_waiting;
99- }
100- )
135+ EXPECT_EQ (true , condition.wait_for (lock, 1 * 1000 , [stop_waiting] {
136+ std::cout << " running lambda, stop_waiting : " << stop_waiting << std::endl;
137+ return stop_waiting;
138+ }
139+ )
101140 );
102141 }
103142
104143
105144 {
106145 pthread::lock_guard<pthread::mutex> lock{mutex};
107- EXPECT_EQ (false , condition. wait_for (lock, 1 * 1000 , [stop_waiting]{
108- std::cout << " running lambda, stop_waiting : " << stop_waiting << std::endl ;
109- return ! stop_waiting;
110- }
111- )
146+ EXPECT_EQ (false ,
147+ condition. wait_for (lock, 1 * 1000 , [ stop_waiting] {
148+ std::cout << " running lambda, stop_waiting : " << stop_waiting << std::endl ;
149+ return !stop_waiting;
150+ } )
112151 );
152+
113153 }
114154}
115155
0 commit comments