1 // Copyright (C) 2001-2003
2 // William E. Kempf
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #undef BOOST_THREAD_VERSION
8 #define BOOST_THREAD_VERSION 2
9
10 #include <boost/thread/mutex.hpp>
11 #include <boost/thread/condition.hpp>
12 #include <boost/thread/thread_only.hpp>
13 #include <boost/thread/xtime.hpp>
14 #include <iostream>
15
16 #if defined(BOOST_HAS_WINTHREADS)
17 # include <windows.h>
18 # include <process.h>
19 #endif
20
21 enum game_state
22 {
23 START,
24 PLAYER_A,
25 PLAYER_B,
26 GAME_OVER,
27 ONE_PLAYER_GONE,
28 BOTH_PLAYERS_GONE
29 };
30
31 int state;
32 boost::mutex mutex;
33 boost::condition cond;
34
player_name(int state)35 const char* player_name(int state)
36 {
37 if (state == PLAYER_A)
38 return "PLAYER-A";
39 if (state == PLAYER_B)
40 return "PLAYER-B";
41 throw "bad player";
42 //return 0;
43 }
44
player(int active)45 void player(int active)
46 {
47 boost::unique_lock<boost::mutex> lock(mutex);
48
49 int other = active == PLAYER_A ? PLAYER_B : PLAYER_A;
50
51 while (state < GAME_OVER)
52 {
53 //std::cout << player_name(active) << ": Play." << std::endl;
54 state = other;
55 cond.notify_all();
56 do
57 {
58 cond.wait(lock);
59 if (state == other)
60 {
61 std::cout << "---" << player_name(active)
62 << ": Spurious wakeup!" << std::endl;
63 }
64 } while (state == other);
65 }
66
67 ++state;
68 std::cout << player_name(active) << ": Gone." << std::endl;
69 cond.notify_all();
70 }
71
72 struct thread_adapt
73 {
thread_adaptthread_adapt74 thread_adapt(void (*func)(void*), void* param)
75 : _func(func), _param(param)
76 {
77 }
operator ()thread_adapt78 int operator()() const
79 {
80 _func(_param);
81 return 0;
82 }
83
84 void (*_func)(void*);
85 void* _param;
86 };
87
88 class thread_adapter
89 {
90 public:
thread_adapter(void (* func)(void *),void * param)91 thread_adapter(void (*func)(void*), void* param)
92 : _func(func), _param(param)
93 {
94 }
operator ()() const95 void operator()() const { _func(_param); }
96 private:
97 void (*_func)(void*);
98 void* _param;
99 };
100
main()101 int main()
102 {
103 state = START;
104
105 boost::thread thrda(&player, PLAYER_A);
106 boost::thread thrdb(&player, PLAYER_B);
107
108 boost::xtime xt;
109 boost::xtime_get(&xt, boost::TIME_UTC_);
110 xt.sec += 1;
111 boost::thread::sleep(xt);
112 {
113 boost::unique_lock<boost::mutex> lock(mutex);
114 std::cout << "---Noise ON..." << std::endl;
115 }
116
117 for (int i = 0; i < 10; ++i)
118 cond.notify_all();
119
120 {
121 boost::unique_lock<boost::mutex> lock(mutex);
122 std::cout << "---Noise OFF..." << std::endl;
123 state = GAME_OVER;
124 cond.notify_all();
125 do
126 {
127 cond.wait(lock);
128 } while (state != BOTH_PLAYERS_GONE);
129 }
130
131 std::cout << "GAME OVER" << std::endl;
132
133 thrda.join();
134 thrdb.join();
135
136 return 0;
137 }
138