1 | /** |
2 | * Copyright (c) 2006-2023 LOVE Development Team |
3 | * |
4 | * This software is provided 'as-is', without any express or implied |
5 | * warranty. In no event will the authors be held liable for any damages |
6 | * arising from the use of this software. |
7 | * |
8 | * Permission is granted to anyone to use this software for any purpose, |
9 | * including commercial applications, and to alter it and redistribute it |
10 | * freely, subject to the following restrictions: |
11 | * |
12 | * 1. The origin of this software must not be misrepresented; you must not |
13 | * claim that you wrote the original software. If you use this software |
14 | * in a product, an acknowledgment in the product documentation would be |
15 | * appreciated but is not required. |
16 | * 2. Altered source versions must be plainly marked as such, and must not be |
17 | * misrepresented as being the original software. |
18 | * 3. This notice may not be removed or altered from any source distribution. |
19 | **/ |
20 | |
21 | #include "Channel.h" |
22 | |
23 | #include <timer/Timer.h> |
24 | |
25 | namespace love |
26 | { |
27 | namespace thread |
28 | { |
29 | |
30 | love::Type Channel::type("Channel" , &Object::type); |
31 | |
32 | Channel::Channel() |
33 | : sent(0) |
34 | , received(0) |
35 | { |
36 | } |
37 | |
38 | Channel::~Channel() |
39 | { |
40 | } |
41 | |
42 | uint64 Channel::push(const Variant &var) |
43 | { |
44 | Lock l(mutex); |
45 | |
46 | queue.push(var); |
47 | cond->broadcast(); |
48 | |
49 | return ++sent; |
50 | } |
51 | |
52 | bool Channel::supply(const Variant &var) |
53 | { |
54 | Lock l(mutex); |
55 | uint64 id = push(var); |
56 | |
57 | while (received < id) |
58 | cond->wait(mutex); |
59 | |
60 | return true; |
61 | } |
62 | |
63 | bool Channel::supply(const Variant &var, double timeout) |
64 | { |
65 | Lock l(mutex); |
66 | uint64 id = push(var); |
67 | |
68 | while (timeout >= 0) |
69 | { |
70 | if (received >= id) |
71 | return true; |
72 | |
73 | double start = love::timer::Timer::getTime(); |
74 | cond->wait(mutex, timeout*1000); |
75 | double stop = love::timer::Timer::getTime(); |
76 | |
77 | timeout -= (stop-start); |
78 | } |
79 | |
80 | return false; |
81 | } |
82 | |
83 | bool Channel::pop(Variant *var) |
84 | { |
85 | Lock l(mutex); |
86 | |
87 | if (queue.empty()) |
88 | return false; |
89 | |
90 | *var = queue.front(); |
91 | queue.pop(); |
92 | |
93 | received++; |
94 | cond->broadcast(); |
95 | |
96 | return true; |
97 | } |
98 | |
99 | bool Channel::demand(Variant *var) |
100 | { |
101 | Lock l(mutex); |
102 | |
103 | while (!pop(var)) |
104 | cond->wait(mutex); |
105 | |
106 | return true; |
107 | } |
108 | |
109 | bool Channel::demand(Variant *var, double timeout) |
110 | { |
111 | Lock l(mutex); |
112 | |
113 | while (timeout >= 0) |
114 | { |
115 | if (pop(var)) |
116 | return true; |
117 | |
118 | double start = love::timer::Timer::getTime(); |
119 | cond->wait(mutex, timeout*1000); |
120 | double stop = love::timer::Timer::getTime(); |
121 | |
122 | timeout -= (stop-start); |
123 | } |
124 | |
125 | return false; |
126 | } |
127 | |
128 | bool Channel::peek(Variant *var) |
129 | { |
130 | Lock l(mutex); |
131 | |
132 | if (queue.empty()) |
133 | return false; |
134 | |
135 | *var = queue.front(); |
136 | return true; |
137 | } |
138 | |
139 | int Channel::getCount() const |
140 | { |
141 | Lock l(mutex); |
142 | return (int) queue.size(); |
143 | } |
144 | |
145 | bool Channel::hasRead(uint64 id) const |
146 | { |
147 | Lock l(mutex); |
148 | return received >= id; |
149 | } |
150 | |
151 | void Channel::clear() |
152 | { |
153 | Lock l(mutex); |
154 | |
155 | // We're already empty. |
156 | if (queue.empty()) |
157 | return; |
158 | |
159 | while (!queue.empty()) |
160 | queue.pop(); |
161 | |
162 | // Finish all the supply waits |
163 | received = sent; |
164 | cond->broadcast(); |
165 | } |
166 | |
167 | void Channel::lockMutex() |
168 | { |
169 | mutex->lock(); |
170 | } |
171 | |
172 | void Channel::unlockMutex() |
173 | { |
174 | mutex->unlock(); |
175 | } |
176 | |
177 | } // thread |
178 | } // love |
179 | |