|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
1 |
/* iris-coordination-arbiter.c |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
2 |
* |
| |
3 |
* Copyright (C) 2009 Christian Hergert <chris@dronelabs.com> |
| |
4 |
* |
| |
5 |
* This library is free software; you can redistribute it and/or |
| |
6 |
* modify it under the terms of the GNU Library General Public |
| |
7 |
* License as published by the Free Software Foundation; either |
| |
8 |
* version 2 of the License, or (at your option) any later version. |
| |
9 |
* |
| |
10 |
* This library is distributed in the hope that it will be useful, |
| |
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| |
13 |
* Library General Public License for more details. |
| |
14 |
* |
| |
15 |
* You should have received a copy of the GNU Library General Public |
| |
16 |
* License along with this library; if not, write to the Free Software |
| |
17 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA |
| |
18 |
* 02110-1301 USA |
| |
19 |
*/ |
| |
20 |
|
| |
21 |
#include "iris-arbiter.h" |
|
42d899f8
»
|
chergert |
2009-09-19 |
Cleanup of the public API a... |
22 |
#include "iris-arbiter-private.h" |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
23 |
#include "iris-coordination-arbiter.h" |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
24 |
#include "iris-coordination-arbiter-private.h" |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
25 |
#include "iris-port.h" |
| |
26 |
#include "iris-receiver.h" |
| |
27 |
#include "iris-receiver-private.h" |
| |
28 |
|
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
29 |
#define ATTACH_ARBITER(r,a) \ |
| |
30 |
G_STMT_START { \ |
| |
31 |
if (r && !r->priv->arbiter) \ |
| |
32 |
r->priv->arbiter = g_object_ref (a); \ |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
33 |
} G_STMT_END |
| |
34 |
|
| |
35 |
/** |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
36 |
* SECTION:iris-coordination-receiver |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
37 |
* @short_description: #IrisArbiter to manage exclusive vs concurrent messages |
| |
38 |
* |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
39 |
* The #IrisCoordinationArbiter provides management over how incoming messages |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
40 |
* can be handled. Its primary purpose is to allow messages to be as |
| |
41 |
* concurrent as possible until an exclusive message is received. When that |
| |
42 |
* happens, it will bleed off the concurrent messages and then run the |
| |
43 |
* exclusive messages. After the exclusive messages have processed, the flood |
| |
44 |
* gates can re-open and throttle back up to full concurrency. |
| |
45 |
*/ |
| |
46 |
|
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
47 |
G_DEFINE_TYPE (IrisCoordinationArbiter, |
| |
48 |
iris_coordination_arbiter, |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
49 |
IRIS_TYPE_ARBITER); |
| |
50 |
|
| |
51 |
static IrisReceiveDecision |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
52 |
can_receive (IrisArbiter *arbiter, |
| |
53 |
IrisReceiver *receiver) |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
54 |
{ |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
55 |
IrisCoordinationArbiter *coord; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
56 |
IrisCoordinationArbiterPrivate *priv; |
|
f411e4bc
»
|
chergert |
2009-04-20 |
Try to resume the concurren... |
57 |
IrisReceiver *resume = NULL; |
| |
58 |
IrisReceiveDecision decision = IRIS_RECEIVE_NEVER; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
59 |
|
| |
60 |
g_return_val_if_fail (IRIS_IS_COORDINATION_ARBITER (arbiter), IRIS_RECEIVE_NEVER); |
| |
61 |
g_return_val_if_fail (IRIS_IS_RECEIVER (receiver), IRIS_RECEIVE_NEVER); |
| |
62 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
63 |
coord = IRIS_COORDINATION_ARBITER (arbiter); |
| |
64 |
priv = coord->priv; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
65 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
66 |
g_static_rec_mutex_lock (&priv->mutex); |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
67 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
68 |
/* Current Receiver: ANY |
| |
69 |
* Request Receiver: ANY |
| |
70 |
* Has Active......: ANY |
| |
71 |
* Pending.........: ANY |
| |
72 |
* Completed.......: YES |
| |
73 |
* Receive.........: NEVER |
| |
74 |
*/ |
| |
75 |
if (priv->flags & IRIS_COORD_COMPLETE) { |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
76 |
decision = IRIS_RECEIVE_NEVER; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
77 |
goto finish; |
| |
78 |
} |
| |
79 |
|
| |
80 |
/* Current Receiver: TEARDOWN |
| |
81 |
* Request Receiver: CONCURRENT or EXCLUSIVE |
| |
82 |
* Has Active......: ANY |
| |
83 |
* Pending.........: ANY |
| |
84 |
* Receive.........: NEVER |
| |
85 |
*/ |
| |
86 |
if (priv->flags & IRIS_COORD_TEARDOWN) { |
| |
87 |
if (receiver == priv->concurrent || receiver == priv->exclusive) { |
| |
88 |
decision = IRIS_RECEIVE_NEVER; |
| |
89 |
goto finish; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
90 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
91 |
} |
| |
92 |
|
| |
93 |
/* Current Receiver: TEARDOWN |
| |
94 |
* Request Receiver: TEARDOWN |
| |
95 |
* Has Active......: 0 |
| |
96 |
* Pending.........: NONE |
| |
97 |
* Completed.......: NO |
| |
98 |
* Receive.........: NOW |
| |
99 |
*/ |
| |
100 |
if (priv->flags & IRIS_COORD_TEARDOWN) { |
| |
101 |
if ((priv->flags & IRIS_COORD_COMPLETE) == 0) { |
| |
102 |
if (receiver == priv->teardown) { |
| |
103 |
if (priv->active == 0) { |
| |
104 |
decision = IRIS_RECEIVE_NOW; |
| |
105 |
priv->flags &= ~IRIS_COORD_NEEDS_TEARDOWN; |
| |
106 |
priv->flags |= IRIS_COORD_COMPLETE; |
| |
107 |
goto finish; |
| |
108 |
} |
|
eaf6c2dc
»
|
chergert |
2009-04-19 |
Make sure we disable the ne... |
109 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
110 |
} |
| |
111 |
} |
| |
112 |
|
|
19a2f54e
»
|
chergert |
2009-04-20 |
Handle a missing branch for... |
113 |
/* Current Receiver: TEARDOWN |
| |
114 |
* Request Receiver: TEARDOWN |
| |
115 |
* Has Active......: YES |
| |
116 |
* Pending.........: NONE |
| |
117 |
* Completed.......: NO |
| |
118 |
* Receive.........: NEVER |
| |
119 |
*/ |
| |
120 |
if (priv->flags & IRIS_COORD_TEARDOWN) { |
| |
121 |
if (receiver == priv->teardown) { |
| |
122 |
if (priv->active > 0) { |
| |
123 |
if ((priv->flags & IRIS_COORD_COMPLETE) == 0) { |
| |
124 |
decision = IRIS_RECEIVE_NEVER; |
| |
125 |
goto finish; |
| |
126 |
} |
| |
127 |
} |
| |
128 |
} |
| |
129 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
130 |
|
| |
131 |
/* Current Receiver: ANY |
| |
132 |
* Request Receiver: CONCURRENT or EXCUSIVE |
| |
133 |
* Has Active......: ANY |
| |
134 |
* Pending.........: TEARDOWN |
| |
135 |
* Receive.........: NEVER |
| |
136 |
*/ |
| |
137 |
if (receiver == priv->concurrent || receiver == priv->exclusive) { |
| |
138 |
if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) { |
| |
139 |
decision = IRIS_RECEIVE_NEVER; |
| |
140 |
goto finish; |
| |
141 |
} |
| |
142 |
} |
| |
143 |
|
| |
144 |
/* Current Receiver: CONCURRENT |
| |
145 |
* Request Receiver: CONCURRENT |
| |
146 |
* Has Active......: * |
| |
147 |
* Pending.........: NONE or CONCURRENT |
| |
148 |
* Receive.........: NOW |
| |
149 |
*/ |
| |
150 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
| |
151 |
if (receiver == priv->concurrent) { |
| |
152 |
if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_CONCURRENT) == IRIS_COORD_NEEDS_CONCURRENT) { |
| |
153 |
decision = IRIS_RECEIVE_NOW; |
| |
154 |
priv->flags &= ~IRIS_COORD_NEEDS_CONCURRENT; |
|
f411e4bc
»
|
chergert |
2009-04-20 |
Try to resume the concurren... |
155 |
resume = priv->concurrent; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
156 |
goto finish; |
|
eaf6c2dc
»
|
chergert |
2009-04-19 |
Make sure we disable the ne... |
157 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
158 |
} |
| |
159 |
} |
| |
160 |
|
| |
161 |
/* Current Receiver: CONCURRENT |
| |
162 |
* Request Receiver: CONCURRENT |
| |
163 |
* Has Active......: * |
| |
164 |
* Pending.........: ANY |
| |
165 |
* Receive.........: LATER |
| |
166 |
*/ |
| |
167 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
| |
168 |
if (receiver == priv->concurrent) { |
| |
169 |
if ((priv->flags & IRIS_COORD_NEEDS_ANY) != 0) { |
| |
170 |
decision = IRIS_RECEIVE_LATER; |
| |
171 |
priv->flags |= IRIS_COORD_NEEDS_CONCURRENT; |
| |
172 |
goto finish; |
|
eaf6c2dc
»
|
chergert |
2009-04-19 |
Make sure we disable the ne... |
173 |
} |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
174 |
} |
| |
175 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
176 |
|
| |
177 |
/* Current Receiver: CONCURRENT |
| |
178 |
* Request Receiver: EXCLUSIVE |
| |
179 |
* Has Active......: YES |
| |
180 |
* Pending.........: ANY |
| |
181 |
* Receive.........: LATER |
| |
182 |
*/ |
| |
183 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
184 |
if (receiver == priv->exclusive) { |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
185 |
if (priv->active > 0) { |
| |
186 |
decision = IRIS_RECEIVE_LATER; |
| |
187 |
priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE; |
| |
188 |
goto finish; |
| |
189 |
} |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
190 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
191 |
} |
| |
192 |
|
| |
193 |
/* Current Receiver: CONCURRENT |
| |
194 |
* Request Receiver: EXCLUSIVE |
| |
195 |
* Has Active......: NO |
| |
196 |
* Pending.........: NONE or EXCLUSIVE |
| |
197 |
* Receive.........: NOW |
| |
198 |
*/ |
| |
199 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
| |
200 |
if (receiver == priv->exclusive) { |
| |
201 |
if (priv->active == 0) { |
| |
202 |
if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_EXCLUSIVE) == IRIS_COORD_NEEDS_EXCLUSIVE) { |
| |
203 |
decision = IRIS_RECEIVE_NOW; |
|
4014a22d
»
|
chergert |
2009-04-20 |
Swap flags for IRIS_RECEIVE... |
204 |
priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE); |
| |
205 |
priv->flags |= IRIS_COORD_EXCLUSIVE; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
206 |
goto finish; |
| |
207 |
} |
| |
208 |
} |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
209 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
210 |
} |
| |
211 |
|
| |
212 |
/* Current Receiver: CONCURRENT |
| |
213 |
* Request Receiver: EXCLUSIVE |
| |
214 |
* Has Active......: NO |
| |
215 |
* Pending.........: EXCLUSIVE or TEARDOWN |
| |
216 |
* Receive.........: NOW |
| |
217 |
*/ |
| |
218 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
| |
219 |
if (receiver == priv->exclusive) { |
| |
220 |
if (priv->active == 0) { |
| |
221 |
if ((priv->flags & IRIS_COORD_NEEDS_ANY) != IRIS_COORD_NEEDS_CONCURRENT) { |
| |
222 |
decision = IRIS_RECEIVE_NOW; |
|
4014a22d
»
|
chergert |
2009-04-20 |
Swap flags for IRIS_RECEIVE... |
223 |
priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE); |
| |
224 |
priv->flags |= IRIS_COORD_EXCLUSIVE; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
225 |
goto finish; |
| |
226 |
} |
| |
227 |
} |
| |
228 |
} |
| |
229 |
} |
| |
230 |
|
| |
231 |
/* Current Receiver: CONCURRENT |
| |
232 |
* Request Receiver: TEARDOWN |
| |
233 |
* Has Active......: NO |
| |
234 |
* Pending.........: NONE or TEARDOWN |
| |
235 |
* Receive.........: NOW |
| |
236 |
*/ |
| |
237 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
| |
238 |
if (receiver == priv->teardown) { |
| |
239 |
if (priv->active == 0) { |
| |
240 |
if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_TEARDOWN) == IRIS_COORD_NEEDS_TEARDOWN) { |
| |
241 |
decision = IRIS_RECEIVE_NOW; |
|
4014a22d
»
|
chergert |
2009-04-20 |
Swap flags for IRIS_RECEIVE... |
242 |
priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN); |
| |
243 |
priv->flags |= IRIS_COORD_TEARDOWN; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
244 |
goto finish; |
| |
245 |
} |
| |
246 |
} |
| |
247 |
} |
| |
248 |
} |
| |
249 |
|
| |
250 |
/* Current Receiver: CONCURRENT |
| |
251 |
* Request Receiver: TEARDOWN |
| |
252 |
* Has Active......: YES |
| |
253 |
* Pending.........: ANY |
| |
254 |
* Receive.........: LATER |
| |
255 |
*/ |
| |
256 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
| |
257 |
if (receiver == priv->teardown) { |
| |
258 |
if (priv->active > 0) { |
| |
259 |
decision = IRIS_RECEIVE_LATER; |
| |
260 |
priv->flags |= IRIS_COORD_NEEDS_TEARDOWN; |
| |
261 |
goto finish; |
| |
262 |
} |
| |
263 |
} |
| |
264 |
} |
| |
265 |
|
| |
266 |
/* Current Receiver: CONCURRENT |
| |
267 |
* Request Receiver: TEARDOWN |
| |
268 |
* Has Active......: NO |
| |
269 |
* Pending.........: ANY |
| |
270 |
* Receive.........: NOW |
| |
271 |
*/ |
| |
272 |
if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) { |
| |
273 |
if (receiver == priv->teardown) { |
| |
274 |
if (priv->active == 0) { |
| |
275 |
decision = IRIS_RECEIVE_NOW; |
|
4014a22d
»
|
chergert |
2009-04-20 |
Swap flags for IRIS_RECEIVE... |
276 |
priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN); |
| |
277 |
priv->flags |= IRIS_COORD_TEARDOWN; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
278 |
goto finish; |
| |
279 |
} |
| |
280 |
} |
| |
281 |
} |
| |
282 |
|
| |
283 |
/* Current Receiver: EXCLUSIVE |
| |
284 |
* Request Receiver: EXCLUSIVE |
| |
285 |
* Has Active......: YES |
| |
286 |
* Pending.........: ANY |
| |
287 |
* Receive.........: LATER |
| |
288 |
*/ |
| |
289 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
290 |
if (receiver == priv->exclusive) { |
| |
291 |
if (priv->active > 0) { |
| |
292 |
decision = IRIS_RECEIVE_LATER; |
| |
293 |
priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE; |
| |
294 |
goto finish; |
| |
295 |
} |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
296 |
} |
| |
297 |
} |
| |
298 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
299 |
/* Current Receiver: EXCLUSIVE |
| |
300 |
* Request Receiver: EXCLUSIVE |
| |
301 |
* Has Active......: NO |
|
b122d360
»
|
chergert |
2009-04-20 |
Handle a few more common ca... |
302 |
* Pending.........: ANY |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
303 |
* Receive.........: NOW |
|
b122d360
»
|
chergert |
2009-04-20 |
Handle a few more common ca... |
304 |
* Notes...........: This should help us utilize our exclusive mode |
| |
305 |
* better so we don't do so many switches when |
| |
306 |
* already in exclusive mode. |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
307 |
*/ |
| |
308 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
309 |
if (receiver == priv->exclusive) { |
| |
310 |
if (priv->active == 0) { |
|
b122d360
»
|
chergert |
2009-04-20 |
Handle a few more common ca... |
311 |
decision = IRIS_RECEIVE_NOW; |
| |
312 |
priv->flags &= ~IRIS_COORD_NEEDS_EXCLUSIVE; |
| |
313 |
goto finish; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
314 |
} |
| |
315 |
} |
| |
316 |
} |
| |
317 |
|
| |
318 |
/* Current Receiver: EXCLUSIVE |
| |
319 |
* Request Receiver: EXCLUSIVE |
| |
320 |
* Has Active......: NO |
| |
321 |
* Pending.........: CONCURRENT or TEARDOWN |
| |
322 |
* Receive.........: LATER |
| |
323 |
*/ |
| |
324 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
325 |
if (receiver == priv->exclusive) { |
| |
326 |
if (priv->active == 0) { |
| |
327 |
if ((priv->flags & IRIS_COORD_NEEDS_ANY) & ~IRIS_COORD_NEEDS_EXCLUSIVE) { |
| |
328 |
decision = IRIS_RECEIVE_LATER; |
| |
329 |
priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE; |
| |
330 |
goto finish; |
| |
331 |
} |
| |
332 |
} |
| |
333 |
} |
| |
334 |
} |
| |
335 |
|
| |
336 |
/* Current Receiver: EXCLUSIVE |
| |
337 |
* Request Receiver: EXCLUSIVE |
| |
338 |
* Has Active......: YES |
| |
339 |
* Pending.........: ANY |
| |
340 |
* Receive.........: LATER |
| |
341 |
*/ |
| |
342 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
343 |
if (receiver == priv->exclusive) { |
| |
344 |
if (priv->active > 0) { |
| |
345 |
decision = IRIS_RECEIVE_LATER; |
| |
346 |
priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE; |
| |
347 |
goto finish; |
| |
348 |
} |
| |
349 |
} |
| |
350 |
} |
| |
351 |
|
| |
352 |
/* Current Receiver: EXCLUSIVE |
| |
353 |
* Request Receiver: CONCURRENT |
| |
354 |
* Has Active......: NO |
| |
355 |
* Pending.........: NONE or CONCURRENT |
| |
356 |
* Receive.........: NOW |
| |
357 |
*/ |
| |
358 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
359 |
if (receiver == priv->concurrent) { |
| |
360 |
if (priv->active == 0) { |
| |
361 |
if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_CONCURRENT) == IRIS_COORD_NEEDS_CONCURRENT) { |
| |
362 |
decision = IRIS_RECEIVE_NOW; |
|
4014a22d
»
|
chergert |
2009-04-20 |
Swap flags for IRIS_RECEIVE... |
363 |
priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_CONCURRENT); |
| |
364 |
priv->flags |= IRIS_COORD_CONCURRENT; |
|
f411e4bc
»
|
chergert |
2009-04-20 |
Try to resume the concurren... |
365 |
resume = priv->concurrent; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
366 |
goto finish; |
| |
367 |
} |
| |
368 |
} |
| |
369 |
} |
| |
370 |
} |
| |
371 |
|
| |
372 |
/* Current Receiver: EXCLUSIVE |
| |
373 |
* Request Receiver: CONCURRENT |
| |
374 |
* Has Active......: NO |
| |
375 |
* Pending.........: EXCLUSIVE or TEARDOWN |
| |
376 |
* Receive.........: LATER |
| |
377 |
*/ |
| |
378 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
379 |
if (receiver == priv->concurrent) { |
| |
380 |
if (priv->active == 0) { |
| |
381 |
if ((priv->flags & IRIS_COORD_NEEDS_ANY) & ~IRIS_COORD_NEEDS_CONCURRENT) { |
| |
382 |
decision = IRIS_RECEIVE_LATER; |
| |
383 |
priv->flags |= IRIS_COORD_NEEDS_CONCURRENT; |
| |
384 |
goto finish; |
| |
385 |
} |
| |
386 |
} |
| |
387 |
} |
| |
388 |
} |
| |
389 |
|
| |
390 |
/* Current Receiver: EXCLUSIVE |
| |
391 |
* Request Receiver: CONCURRENT |
| |
392 |
* Has Active......: YES |
| |
393 |
* Pending.........: ANY |
| |
394 |
* Receive.........: LATER |
| |
395 |
*/ |
| |
396 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
397 |
if (receiver == priv->concurrent) { |
| |
398 |
if (priv->active > 0) { |
| |
399 |
decision = IRIS_RECEIVE_LATER; |
| |
400 |
priv->flags |= IRIS_COORD_NEEDS_CONCURRENT; |
| |
401 |
goto finish; |
| |
402 |
} |
| |
403 |
} |
| |
404 |
} |
| |
405 |
|
| |
406 |
/* Current Receiver: EXCLUSIVE |
| |
407 |
* Request Receiver: TEARDOWN |
| |
408 |
* Has Active......: NO |
| |
409 |
* Pending.........: NONE or TEARDOWN |
| |
410 |
* Receive.........: NOW |
| |
411 |
*/ |
| |
412 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
413 |
if (receiver == priv->teardown) { |
| |
414 |
if (priv->active == 0) { |
| |
415 |
if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_TEARDOWN) == IRIS_COORD_NEEDS_TEARDOWN) { |
| |
416 |
decision = IRIS_RECEIVE_NOW; |
|
4014a22d
»
|
chergert |
2009-04-20 |
Swap flags for IRIS_RECEIVE... |
417 |
priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_TEARDOWN); |
| |
418 |
priv->flags |= IRIS_COORD_TEARDOWN; |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
419 |
goto finish; |
| |
420 |
} |
| |
421 |
} |
| |
422 |
} |
| |
423 |
} |
| |
424 |
|
| |
425 |
/* Current Receiver: EXCLUSIVE |
| |
426 |
* Request Receiver: TEARDOWN |
| |
427 |
* Has Active......: YES |
| |
428 |
* Pending.........: ANY |
| |
429 |
* Receive.........: LATER |
| |
430 |
*/ |
| |
431 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
432 |
if (receiver == priv->teardown) { |
| |
433 |
if (priv->active > 0) { |
| |
434 |
decision = IRIS_RECEIVE_LATER; |
| |
435 |
priv->flags |= IRIS_COORD_NEEDS_TEARDOWN; |
| |
436 |
goto finish; |
| |
437 |
} |
| |
438 |
} |
| |
439 |
} |
| |
440 |
|
| |
441 |
/* Current Receiver: EXCLUSIVE |
| |
442 |
* Request Receiver: TEARDOWN |
| |
443 |
* Has Active......: NO |
| |
444 |
* Pending.........: ANY |
| |
445 |
* Receive.........: LATER |
| |
446 |
*/ |
| |
447 |
if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) { |
| |
448 |
if (receiver == priv->teardown) { |
|
7d413868
»
|
chergert |
2009-05-26 |
Fix comparison for branch, ... |
449 |
if (priv->active <= 0) { |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
450 |
decision = IRIS_RECEIVE_LATER; |
| |
451 |
priv->flags |= IRIS_COORD_NEEDS_TEARDOWN; |
| |
452 |
goto finish; |
| |
453 |
} |
| |
454 |
} |
| |
455 |
} |
| |
456 |
|
| |
457 |
g_print ("\nMISSING ARBITER BRANCH REPORT\n" |
| |
458 |
"====================================\n" |
| |
459 |
"Current.....: %s\n" |
| |
460 |
"Receiver....: %s\n" |
| |
461 |
"Active......: %lu\n" |
| |
462 |
"Pending.....: %u\n", |
| |
463 |
(priv->flags & IRIS_COORD_EXCLUSIVE) ? "EXCLUSIVE" : (priv->flags & IRIS_COORD_CONCURRENT) ? "CONCURRENT" : "TEARDOWN", |
| |
464 |
(receiver == priv->exclusive) ? "EXCLUSIVE" : (receiver == priv->concurrent) ? "CONCURRENT" : "TEARDOWN", |
| |
465 |
priv->active, |
| |
466 |
priv->flags & IRIS_COORD_NEEDS_ANY); |
| |
467 |
|
| |
468 |
finish: |
|
19a2f54e
»
|
chergert |
2009-04-20 |
Handle a missing branch for... |
469 |
if (decision == IRIS_RECEIVE_NOW) { |
| |
470 |
if (receiver == priv->teardown) |
| |
471 |
priv->flags |= IRIS_COORD_COMPLETE; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
472 |
g_atomic_int_inc ((gint*)&priv->active); |
|
19a2f54e
»
|
chergert |
2009-04-20 |
Handle a missing branch for... |
473 |
} |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
474 |
|
|
582b140f
»
|
chergert |
2009-04-20 |
Fix a deadlock. |
475 |
/* It would be nice to hold on to this lock while we resume to make |
| |
476 |
* sure our resuming receiver gets more in, but it can create a |
| |
477 |
* dead-lock if we are calling resume and try to lock on the receiver |
| |
478 |
* while someone in the receiver thread is trying to lock on us to |
| |
479 |
* try to deliver. */ |
| |
480 |
g_static_rec_mutex_unlock (&priv->mutex); |
| |
481 |
|
|
f411e4bc
»
|
chergert |
2009-04-20 |
Try to resume the concurren... |
482 |
if (resume) |
| |
483 |
iris_receiver_resume (resume); |
| |
484 |
|
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
485 |
return decision; |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
486 |
} |
| |
487 |
|
| |
488 |
static void |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
489 |
receive_completed (IrisArbiter *arbiter, |
| |
490 |
IrisReceiver *receiver) |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
491 |
{ |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
492 |
IrisCoordinationArbiter *coord; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
493 |
IrisCoordinationArbiterPrivate *priv; |
| |
494 |
IrisReceiver *resume = NULL; |
| |
495 |
|
| |
496 |
g_return_if_fail (IRIS_IS_COORDINATION_ARBITER (arbiter)); |
| |
497 |
g_return_if_fail (IRIS_IS_RECEIVER (receiver)); |
| |
498 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
499 |
coord = IRIS_COORDINATION_ARBITER (arbiter); |
| |
500 |
priv = coord->priv; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
501 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
502 |
g_static_rec_mutex_lock (&priv->mutex); |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
503 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
504 |
if (g_atomic_int_dec_and_test ((gint*)&priv->active)) { |
|
582b140f
»
|
chergert |
2009-04-20 |
Fix a deadlock. |
505 |
if (priv->flags & IRIS_COORD_COMPLETE) { |
| |
506 |
} |
| |
507 |
else if (priv->flags & IRIS_COORD_CONCURRENT) { |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
508 |
if (priv->flags & IRIS_COORD_NEEDS_EXCLUSIVE) { |
| |
509 |
priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE); |
| |
510 |
priv->flags |= IRIS_COORD_EXCLUSIVE; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
511 |
resume = priv->exclusive; |
| |
512 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
513 |
else if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) { |
| |
514 |
priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN); |
| |
515 |
priv->flags |= IRIS_COORD_TEARDOWN; |
| |
516 |
resume = priv->teardown; |
| |
517 |
} |
|
e85fdaa4
»
|
chergert |
2009-05-27 |
In case we were paused duri... |
518 |
else if (!priv->concurrent->priv->active) { |
| |
519 |
resume = priv->concurrent; |
| |
520 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
521 |
} |
| |
522 |
else if (priv->flags & IRIS_COORD_EXCLUSIVE) { |
|
b122d360
»
|
chergert |
2009-04-20 |
Handle a few more common ca... |
523 |
if (priv->flags & IRIS_COORD_NEEDS_EXCLUSIVE) { |
| |
524 |
/* Try to save mode switches by running exclusive now |
| |
525 |
* regardless of what other modes want to run. */ |
| |
526 |
resume = priv->exclusive; |
| |
527 |
} |
| |
528 |
else if (priv->flags & IRIS_COORD_NEEDS_CONCURRENT) { |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
529 |
priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_CONCURRENT); |
| |
530 |
priv->flags |= IRIS_COORD_CONCURRENT; |
|
eaf6c2dc
»
|
chergert |
2009-04-19 |
Make sure we disable the ne... |
531 |
resume = priv->concurrent; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
532 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
533 |
else if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) { |
| |
534 |
priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_TEARDOWN); |
| |
535 |
priv->flags |= IRIS_COORD_TEARDOWN; |
|
eaf6c2dc
»
|
chergert |
2009-04-19 |
Make sure we disable the ne... |
536 |
resume = priv->teardown; |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
537 |
} |
|
e85fdaa4
»
|
chergert |
2009-05-27 |
In case we were paused duri... |
538 |
else if (!priv->exclusive->priv->active) { |
| |
539 |
resume = priv->exclusive; |
| |
540 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
541 |
} |
| |
542 |
else if (priv->flags & IRIS_COORD_TEARDOWN) { |
|
582b140f
»
|
chergert |
2009-04-20 |
Fix a deadlock. |
543 |
if ((priv->flags & IRIS_COORD_COMPLETE) == 0) { |
| |
544 |
priv->flags &= ~IRIS_COORD_NEEDS_TEARDOWN; |
| |
545 |
resume = priv->teardown; |
| |
546 |
} |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
547 |
} |
| |
548 |
else { |
|
42d899f8
»
|
chergert |
2009-09-19 |
Cleanup of the public API a... |
549 |
g_warn_if_reached (); |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
550 |
} |
| |
551 |
} |
| |
552 |
|
|
582b140f
»
|
chergert |
2009-04-20 |
Fix a deadlock. |
553 |
g_static_rec_mutex_unlock (&priv->mutex); |
| |
554 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
555 |
if (resume) |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
556 |
iris_receiver_resume (resume); |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
557 |
} |
| |
558 |
|
| |
559 |
static void |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
560 |
iris_coordination_arbiter_finalize (GObject *object) |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
561 |
{ |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
562 |
G_OBJECT_CLASS (iris_coordination_arbiter_parent_class)->finalize (object); |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
563 |
} |
| |
564 |
|
| |
565 |
static void |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
566 |
iris_coordination_arbiter_class_init (IrisCoordinationArbiterClass *klass) |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
567 |
{ |
| |
568 |
GObjectClass *object_class = G_OBJECT_CLASS (klass); |
| |
569 |
IrisArbiterClass *arbiter_class = IRIS_ARBITER_CLASS (klass); |
| |
570 |
|
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
571 |
arbiter_class->can_receive = can_receive; |
| |
572 |
arbiter_class->receive_completed = receive_completed; |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
573 |
object_class->finalize = iris_coordination_arbiter_finalize; |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
574 |
|
|
42d899f8
»
|
chergert |
2009-09-19 |
Cleanup of the public API a... |
575 |
g_type_class_add_private (object_class, sizeof (IrisCoordinationArbiterPrivate)); |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
576 |
} |
| |
577 |
|
| |
578 |
static void |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
579 |
iris_coordination_arbiter_init (IrisCoordinationArbiter *arbiter) |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
580 |
{ |
| |
581 |
arbiter->priv = G_TYPE_INSTANCE_GET_PRIVATE (arbiter, |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
582 |
IRIS_TYPE_COORDINATION_ARBITER, |
| |
583 |
IrisCoordinationArbiterPrivate); |
|
1f3bcfea
»
|
chergert |
2009-04-20 |
Implement an easier to mana... |
584 |
g_static_rec_mutex_init (&arbiter->priv->mutex); |
| |
585 |
arbiter->priv->flags = IRIS_COORD_CONCURRENT; |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
586 |
} |
| |
587 |
|
|
ea49f81c
»
|
chergert |
2009-06-06 |
Add basic debian packaging. |
588 |
static IrisArbiter* |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
589 |
iris_coordination_arbiter_new (IrisReceiver *exclusive, |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
590 |
IrisReceiver *concurrent, |
| |
591 |
IrisReceiver *teardown) |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
592 |
{ |
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
593 |
IrisCoordinationArbiter *arbiter; |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
594 |
|
| |
595 |
g_return_val_if_fail (exclusive == NULL || IRIS_IS_RECEIVER (exclusive), NULL); |
| |
596 |
g_return_val_if_fail (concurrent == NULL || IRIS_IS_RECEIVER (concurrent), NULL); |
| |
597 |
g_return_val_if_fail (teardown == NULL || IRIS_IS_RECEIVER (teardown), NULL); |
|
76ba41c2
»
|
chergert |
2009-04-19 |
Add more guards to iris_coo... |
598 |
|
|
786ad23d
»
|
chergert |
2009-04-19 |
Fix comparison logic. |
599 |
g_return_val_if_fail (!exclusive || exclusive != concurrent, NULL); |
| |
600 |
g_return_val_if_fail (!teardown || exclusive != teardown, NULL); |
| |
601 |
g_return_val_if_fail (!concurrent || concurrent != teardown, NULL); |
| |
602 |
g_return_val_if_fail (exclusive || concurrent || teardown, NULL); |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
603 |
|
|
1d512571
»
|
chergert |
2009-04-17 |
Rename concurrency to coord... |
604 |
arbiter = g_object_new (IRIS_TYPE_COORDINATION_ARBITER, NULL); |
|
65bb9d6f
»
|
chergert |
2009-04-17 |
Start implementing coordina... |
605 |
arbiter->priv->exclusive = exclusive ? g_object_ref (exclusive) : NULL; |
| |
606 |
arbiter->priv->concurrent = concurrent ? g_object_ref (concurrent) : NULL; |
| |
607 |
arbiter->priv->teardown = teardown ? g_object_ref (teardown) : NULL; |
|
085ceaad
»
|
chergert |
2009-04-17 |
Beginning of large API addi... |
608 |
|
| |
609 |
ATTACH_ARBITER (exclusive, arbiter); |
| |
610 |
ATTACH_ARBITER (concurrent, arbiter); |
| |
611 |
ATTACH_ARBITER (teardown, arbiter); |
| |
612 |
|
| |
613 |
return IRIS_ARBITER (arbiter); |
| |
614 |
} |
|
ea49f81c
»
|
chergert |
2009-06-06 |
Add basic debian packaging. |
615 |
|
|
42d899f8
»
|
chergert |
2009-09-19 |
Cleanup of the public API a... |
616 |
/** |
| |
617 |
* iris_arbiter_coordinate: |
| |
618 |
* @exclusive: An #IrisReceiver |
| |
619 |
* @concurrent: An #IrisReceiver |
| |
620 |
* @teardown: An #IrisReceiver |
| |
621 |
* |
| |
622 |
* Coordinates messages incoming to the receivers. This is used to guarantee |
| |
623 |
* semantics for the receivers. |
| |
624 |
* |
| |
625 |
* Any message received on the @exclusive receiver is guaranteed to be the |
| |
626 |
* only message received at a time. No other exclusive, concurrent, or |
| |
627 |
* teardown messages will be running. |
| |
628 |
* |
| |
629 |
* Messages received on the @concurrent receiver can be received concurrently |
| |
630 |
* meaning more than one message is allowed to be received at a time. |
| |
631 |
* |
| |
632 |
* Only one message can be recieved on @teardown ever. After a message has |
| |
633 |
* been received on @teardown, no further messages will ever be received |
| |
634 |
* on any receivers. |
| |
635 |
* |
| |
636 |
* Return value: An new #IrisArbiter that will arbitrate messages incoming |
| |
637 |
* to the passed receivers. |
| |
638 |
*/ |
|
ea49f81c
»
|
chergert |
2009-06-06 |
Add basic debian packaging. |
639 |
IrisArbiter* |
| |
640 |
iris_arbiter_coordinate (IrisReceiver *exclusive, |
| |
641 |
IrisReceiver *concurrent, |
| |
642 |
IrisReceiver *teardown) |
| |
643 |
{ |
| |
644 |
return iris_coordination_arbiter_new (exclusive, concurrent, teardown); |
| |
645 |
} |