]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/test-lock_hh.cc
Merge pull request #9069 from omoerbeek/test-destroy-with-waiters
[thirdparty/pdns.git] / pdns / test-lock_hh.cc
1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 #include <boost/test/unit_test.hpp>
7 #include "lock.hh"
8 #include <thread>
9
10 using namespace boost;
11
12 BOOST_AUTO_TEST_SUITE(test_lock_hh)
13
14 static std::vector<std::unique_ptr<pthread_rwlock_t> > g_locks;
15
16 static void lthread()
17 {
18 std::vector<ReadLock> rlocks;
19 for(auto& pp : g_locks)
20 rlocks.emplace_back(&*pp);
21 }
22
23 BOOST_AUTO_TEST_CASE(test_pdns_lock)
24 {
25 for(unsigned int n=0; n < 1000; ++n) {
26 auto p = make_unique<pthread_rwlock_t>();
27 pthread_rwlock_init(p.get(), 0);
28 g_locks.emplace_back(std::move(p));
29 }
30
31 std::vector<ReadLock> rlocks;
32 for(auto& pp : g_locks)
33 rlocks.emplace_back(&*pp);
34
35 std::thread thr(lthread);
36 thr.join();
37 rlocks.clear();
38
39 std::vector<WriteLock> wlocks;
40 for(auto& pp : g_locks)
41 wlocks.emplace_back(&*pp);
42
43 // on macOS, this TryReadLock throws (EDEADLK) instead of simply failing
44 // so we catch the exception and consider that success for this test
45 bool gotit = false;
46 try {
47 TryReadLock trl(&*g_locks[0]);
48 gotit = trl.gotIt();
49 }
50 catch(const PDNSException &e) {
51 gotit = false;
52 }
53 BOOST_CHECK(!gotit);
54
55 wlocks.clear();
56
57 {
58 TryReadLock trl2(&*g_locks[0]);
59 BOOST_CHECK(trl2.gotIt());
60 }
61
62 for(auto& pp : g_locks) {
63 pthread_rwlock_destroy(pp.get());
64 }
65 }
66
67 BOOST_AUTO_TEST_SUITE_END()