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
21enum game_state
22{
23 START,
24 PLAYER_A,
25 PLAYER_B,
26 GAME_OVER,
27 ONE_PLAYER_GONE,
28 BOTH_PLAYERS_GONE
29};
30
31int state;
32boost::mutex mutex;
33boost::condition cond;
34
35const 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
45void 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(m&: lock);
59 if (state == other)
60 {
61 std::cout << "---" << player_name(state: active)
62 << ": Spurious wakeup!" << std::endl;
63 }
64 } while (state == other);
65 }
66
67 ++state;
68 std::cout << player_name(state: active) << ": Gone." << std::endl;
69 cond.notify_all();
70}
71
72struct thread_adapt
73{
74 thread_adapt(void (*func)(void*), void* param)
75 : _func(func), _param(param)
76 {
77 }
78 int operator()() const
79 {
80 _func(_param);
81 return 0;
82 }
83
84 void (*_func)(void*);
85 void* _param;
86};
87
88class thread_adapter
89{
90public:
91 thread_adapter(void (*func)(void*), void* param)
92 : _func(func), _param(param)
93 {
94 }
95 void operator()() const { _func(_param); }
96private:
97 void (*_func)(void*);
98 void* _param;
99};
100
101int 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(xtp: &xt, clock_type: 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(m&: 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

source code of boost/libs/thread/example/tennis.cpp