1 // Copyright (C) 2010 Vicente Botet
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // bm.cpp
7 
8 //  g++ test.cpp -lboost_thread-mt && ./a.out
9 
10 // the ration of XXX and YYY determines
11 // if this works or deadlocks
12 int XXX = 20;
13 int YYY = 10;
14 
15 #include <boost/thread/thread_only.hpp>
16 #include <boost/thread/shared_mutex.hpp>
17 
18 //#include <unistd.h>
19 #include <iostream>
20 #include <boost/detail/lightweight_test.hpp>
21 
22 using namespace std;
23 
24 //void sleepmillis(useconds_t miliis)
sleepmillis(int miliis)25 void sleepmillis(int miliis)
26 {
27   //usleep(miliis * 1000);
28   boost::this_thread::sleep(boost::posix_time::milliseconds(miliis));
29 }
30 
worker1(boost::shared_mutex * lk,int * x)31 void worker1(boost::shared_mutex * lk, int * x)
32 {
33   (*x)++; // 1
34   cout << "lock b try " << *x << endl;
35   while (1)
36   {
37     if (lk->timed_lock(boost::posix_time::milliseconds(XXX))) break;
38     sleepmillis(YYY);
39   }
40   cout << "lock b got " << *x << endl;
41   (*x)++; // 2
42   lk->unlock();
43 }
44 
worker2(boost::shared_mutex * lk,int * x)45 void worker2(boost::shared_mutex * lk, int * x)
46 {
47   cout << "lock c try" << endl;
48   lk->lock_shared();
49   (*x)++;
50   cout << "lock c got" << endl;
51   lk->unlock_shared();
52   cout << "lock c unlocked" << endl;
53   (*x)++;
54 }
55 
main()56 int main()
57 {
58 
59   // create
60   boost::shared_mutex* lk = new boost::shared_mutex();
61 
62   // read lock
63   cout << "lock a" << endl;
64   lk->lock_shared();
65 
66   int x1 = 0;
67   boost::thread t1(boost::bind(worker1, lk, &x1));
68   while (!x1)
69     ;
70   BOOST_TEST(x1 == 1);
71   sleepmillis(500);
72   BOOST_TEST(x1 == 1);
73 
74   int x2 = 0;
75   boost::thread t2(boost::bind(worker2, lk, &x2));
76   t2.join();
77   BOOST_TEST(x2 == 2);
78 
79   lk->unlock_shared();
80   cout << "unlock a" << endl;
81 
82   for (int i = 0; i < 2000; i++)
83   {
84     if (x1 == 2) break;
85     sleepmillis(10);
86   }
87 
88   BOOST_TEST(x1 == 2);
89   t1.join();
90   delete lk;
91 
92   return 0;
93 }
94