From dbf6fcaa4f4eb34c6c5516a89a4184c43a4dd762 Mon Sep 17 00:00:00 2001
From: Dario Casalinuovo <b.vitruvio@gmail.com>
Date: Sat, 14 Feb 2015 15:26:05 +0100
Subject: [PATCH] Replace BTimeSource array-based slave nodes management with a
new one based on BObjectList. Solve TODO making SlaveNodes members private.
General cleanup and style fixes to improve readability of code.
---
src/kits/media/TimeSource.cpp | 329 +++++++++++++++++++++++++-----------------
1 file changed, 198 insertions(+), 131 deletions(-)
diff --git a/src/kits/media/TimeSource.cpp b/src/kits/media/TimeSource.cpp
index dae0244..ce302f3 100644
a
|
b
|
|
1 | 1 | /* |
2 | | * Copyright 2002-2012, Haiku. All Rights Reserved. |
3 | | * This file may be used under the terms of the MIT License. |
| 2 | * Copyright 2002-2015 Haiku, Inc. All rights reserved. |
| 3 | * Distributed under the terms of the MIT License. |
4 | 4 | * |
5 | | * Author: Marcus Overhagen |
| 5 | * Authors: |
| 6 | * Marcus Overhagen |
| 7 | * Dario Casalinuovo |
6 | 8 | */ |
7 | 9 | |
8 | 10 | |
9 | | #include <TimeSource.h> |
10 | 11 | #include <Autolock.h> |
| 12 | #include <ObjectList.h> |
| 13 | #include <TimeSource.h> |
| 14 | |
11 | 15 | #include <string.h> |
| 16 | |
12 | 17 | #include "debug.h" |
13 | 18 | #include "DataExchange.h" |
14 | 19 | #include "ServerInterface.h" |
… |
… |
namespace BPrivate { namespace media {
|
26 | 31 | |
27 | 32 | #define _atomic_read(p) atomic_or((p), 0) |
28 | 33 | |
29 | | #define TS_AREA_SIZE B_PAGE_SIZE // must be multiple of page size |
30 | | #define TS_INDEX_COUNT 128 // must be power of two |
| 34 | // must be multiple of page size |
| 35 | #define TS_AREA_SIZE B_PAGE_SIZE |
| 36 | // must be power of two |
| 37 | #define TS_INDEX_COUNT 128 |
31 | 38 | |
32 | | struct TimeSourceTransmit // sizeof(TimeSourceTransmit) must be <= TS_AREA_SIZE |
| 39 | // sizeof(TimeSourceTransmit) must be <= TS_AREA_SIZE |
| 40 | struct TimeSourceTransmit |
33 | 41 | { |
34 | 42 | int32 readindex; |
35 | 43 | int32 writeindex; |
… |
… |
struct TimeSourceTransmit // sizeof(TimeSourceTransmit) must be <= TS_AREA_SIZE
|
39 | 47 | float drift[TS_INDEX_COUNT]; |
40 | 48 | }; |
41 | 49 | |
42 | | #define SLAVE_NODES_COUNT 300 |
| 50 | #define MAX_SLAVE_NODES 300 |
43 | 51 | |
44 | | // XXX TODO: storage for slave nodes uses public data members, this should be changed |
45 | 52 | |
46 | | class SlaveNodes |
47 | | { |
| 53 | class SlaveNode { |
48 | 54 | public: |
49 | | SlaveNodes(); |
50 | | ~SlaveNodes(); |
| 55 | SlaveNode(media_node_id nodeId, port_id nodePort); |
| 56 | |
| 57 | media_node_id NodeId() const; |
| 58 | port_id NodePort() const; |
| 59 | |
| 60 | private: |
| 61 | media_node_id fNodeId; |
| 62 | port_id fNodePort; |
| 63 | }; |
| 64 | |
| 65 | |
| 66 | SlaveNode::SlaveNode(media_node_id nodeId, port_id nodePort) |
| 67 | { |
| 68 | fNodeId = nodeId; |
| 69 | fNodePort = nodePort; |
| 70 | } |
| 71 | |
| 72 | |
| 73 | media_node_id |
| 74 | SlaveNode::NodeId() const |
| 75 | { |
| 76 | return fNodeId; |
| 77 | } |
| 78 | |
| 79 | |
| 80 | port_id |
| 81 | SlaveNode::NodePort() const |
| 82 | { |
| 83 | return fNodePort; |
| 84 | } |
| 85 | |
| 86 | |
| 87 | class SlaveNodes : public BLocker |
| 88 | { |
51 | 89 | public: |
52 | | BLocker * locker; |
53 | | int32 count; |
54 | | media_node_id node_id[SLAVE_NODES_COUNT]; |
55 | | port_id node_port[SLAVE_NODES_COUNT]; |
| 90 | SlaveNodes(); |
| 91 | |
| 92 | int32 CountSlaves() const; |
| 93 | |
| 94 | port_id PortAt(int32 index) const; |
| 95 | SlaveNode* SlaveAt(int32 index) const; |
| 96 | |
| 97 | bool InsertSlave(const media_node& node); |
| 98 | bool RemoveSlave(const media_node& node); |
| 99 | |
| 100 | private: |
| 101 | BObjectList<SlaveNode> fSlaveList; |
56 | 102 | }; |
57 | 103 | |
58 | 104 | |
59 | 105 | SlaveNodes::SlaveNodes() |
60 | 106 | { |
61 | | locker = new BLocker("BTimeSource SlaveNodes"); |
62 | | count = 0; |
63 | | memset(node_id, 0, sizeof(node_id)); |
64 | | memset(node_port, 0, sizeof(node_port)); |
| 107 | fSlaveList = BObjectList<SlaveNode>(true); |
| 108 | } |
| 109 | |
| 110 | |
| 111 | int32 |
| 112 | SlaveNodes::CountSlaves() const |
| 113 | { |
| 114 | return fSlaveList.CountItems(); |
| 115 | } |
| 116 | |
| 117 | |
| 118 | port_id |
| 119 | SlaveNodes::PortAt(int32 index) const |
| 120 | { |
| 121 | return SlaveAt(index)->NodePort(); |
65 | 122 | } |
66 | 123 | |
67 | 124 | |
68 | | SlaveNodes::~SlaveNodes() |
| 125 | SlaveNode* |
| 126 | SlaveNodes::SlaveAt(int32 index) const |
69 | 127 | { |
70 | | delete locker; |
| 128 | return fSlaveList.ItemAt(index); |
71 | 129 | } |
72 | 130 | |
73 | 131 | |
74 | | } } |
| 132 | bool |
| 133 | SlaveNodes::InsertSlave(const media_node& node) |
| 134 | { |
| 135 | return fSlaveList.AddItem(new SlaveNode(node.node, node.port)); |
| 136 | } |
| 137 | |
| 138 | |
| 139 | bool |
| 140 | SlaveNodes::RemoveSlave(const media_node& node) |
| 141 | { |
| 142 | for (int i = 0; i < CountSlaves(); i++) { |
| 143 | SlaveNode* slave = fSlaveList.ItemAt(i); |
| 144 | if (slave->NodeId() == node.node |
| 145 | && slave->NodePort() == node.port) { |
| 146 | return fSlaveList.RemoveItemAt(i); |
| 147 | } |
| 148 | } |
| 149 | return false; |
| 150 | } |
| 151 | |
| 152 | |
| 153 | } } // namespace BPrivate::media |
75 | 154 | |
76 | 155 | |
77 | 156 | /************************************************************* |
… |
… |
BTimeSource::~BTimeSource()
|
92 | 171 | |
93 | 172 | status_t |
94 | 173 | BTimeSource::SnoozeUntil(bigtime_t performance_time, |
95 | | bigtime_t with_latency, |
96 | | bool retry_signals) |
| 174 | bigtime_t with_latency, bool retry_signals) |
97 | 175 | { |
98 | 176 | CALLED(); |
99 | 177 | bigtime_t time; |
… |
… |
BTimeSource::PerformanceTimeFor(bigtime_t real_time)
|
125 | 203 | if (GetTime(&last_perf_time, &last_real_time, &last_drift) != B_OK) |
126 | 204 | debugger("BTimeSource::PerformanceTimeFor: GetTime failed"); |
127 | 205 | |
128 | | return last_perf_time + (bigtime_t)((real_time - last_real_time) * last_drift); |
| 206 | return last_perf_time |
| 207 | + (bigtime_t)((real_time - last_real_time) * last_drift); |
129 | 208 | } |
130 | 209 | |
131 | 210 | |
132 | 211 | bigtime_t |
133 | 212 | BTimeSource::RealTimeFor(bigtime_t performance_time, |
134 | | bigtime_t with_latency) |
| 213 | bigtime_t with_latency) |
135 | 214 | { |
136 | 215 | PRINT(8, "CALLED BTimeSource::RealTimeFor()\n"); |
137 | 216 | |
… |
… |
BTimeSource::RealTimeFor(bigtime_t performance_time,
|
146 | 225 | if (GetTime(&last_perf_time, &last_real_time, &last_drift) != B_OK) |
147 | 226 | debugger("BTimeSource::RealTimeFor: GetTime failed"); |
148 | 227 | |
149 | | return last_real_time - with_latency + (bigtime_t)((performance_time - last_perf_time) / last_drift); |
| 228 | return last_real_time - with_latency |
| 229 | + (bigtime_t)((performance_time - last_perf_time) / last_drift); |
150 | 230 | } |
151 | 231 | |
152 | 232 | |
… |
… |
BTimeSource::IsRunning()
|
157 | 237 | |
158 | 238 | bool isrunning; |
159 | 239 | |
| 240 | // The system time source is always running |
160 | 241 | if (fIsRealtime) |
161 | | isrunning = true; // The system time source is always running :) |
| 242 | isrunning = true; |
162 | 243 | else |
163 | 244 | isrunning = fBuf ? atomic_add(&fBuf->isrunning, 0) : fStarted; |
164 | 245 | |
… |
… |
BTimeSource::IsRunning()
|
169 | 250 | |
170 | 251 | |
171 | 252 | status_t |
172 | | BTimeSource::GetTime(bigtime_t *performance_time, |
173 | | bigtime_t *real_time, |
174 | | float *drift) |
| 253 | BTimeSource::GetTime(bigtime_t* performance_time, |
| 254 | bigtime_t* real_time, float* drift) |
175 | 255 | { |
176 | 256 | PRINT(8, "CALLED BTimeSource::GetTime()\n"); |
177 | 257 | |
… |
… |
BTimeSource::GetTime(bigtime_t *performance_time,
|
180 | 260 | *drift = 1.0f; |
181 | 261 | return B_OK; |
182 | 262 | } |
183 | | // if (fBuf == 0) { |
184 | | // PRINT(1, "BTimeSource::GetTime: fBuf == 0, name %s, id %ld\n",Name(),ID()); |
185 | | // *performance_time = *real_time = system_time(); |
186 | | // *drift = 1.0f; |
187 | | // return B_OK; |
188 | | // } |
189 | 263 | |
190 | 264 | int32 index; |
191 | 265 | index = _atomic_read(&fBuf->readindex); |
… |
… |
BTimeSource::GetTime(bigtime_t *performance_time,
|
194 | 268 | *performance_time = fBuf->perftime[index]; |
195 | 269 | *drift = fBuf->drift[index]; |
196 | 270 | |
197 | | // if (*real_time == 0) { |
198 | | // *performance_time = *real_time = system_time(); |
199 | | // *drift = 1.0f; |
200 | | // return B_OK; |
201 | | // } |
202 | | // printf("BTimeSource::GetTime timesource %ld, index %ld, perf %16Ld, real %16Ld, drift %2.2f\n", ID(), index, *performance_time, *real_time, *drift); |
203 | | |
204 | 271 | TRACE_TIMESOURCE("BTimeSource::GetTime timesource %" B_PRId32 |
205 | 272 | ", perf %16" B_PRId64 ", real %16" B_PRId64 ", drift %2.2f\n", ID(), |
206 | 273 | *performance_time, *real_time, *drift); |
… |
… |
BTimeSource::RealTime()
|
217 | 284 | |
218 | 285 | |
219 | 286 | status_t |
220 | | BTimeSource::GetStartLatency(bigtime_t *out_latency) |
| 287 | BTimeSource::GetStartLatency(bigtime_t* out_latency) |
221 | 288 | { |
222 | 289 | CALLED(); |
223 | 290 | *out_latency = 0; |
… |
… |
BTimeSource::GetStartLatency(bigtime_t *out_latency)
|
229 | 296 | *************************************************************/ |
230 | 297 | |
231 | 298 | |
232 | | BTimeSource::BTimeSource() : |
| 299 | BTimeSource::BTimeSource() |
| 300 | : |
233 | 301 | BMediaNode("This one is never called"), |
234 | 302 | fStarted(false), |
235 | 303 | fArea(-1), |
… |
… |
BTimeSource::BTimeSource() :
|
239 | 307 | { |
240 | 308 | CALLED(); |
241 | 309 | AddNodeKind(B_TIME_SOURCE); |
242 | | // printf("##### BTimeSource::BTimeSource() name %s, id %ld\n", Name(), ID()); |
243 | | |
244 | 310 | // This constructor is only called by real time sources that inherit |
245 | 311 | // BTimeSource. We create the communication area in FinishCreate(), |
246 | 312 | // since we don't have a correct ID() until this node is registered. |
… |
… |
BTimeSource::BTimeSource() :
|
248 | 314 | |
249 | 315 | |
250 | 316 | status_t |
251 | | BTimeSource::HandleMessage(int32 message, |
252 | | const void *rawdata, |
253 | | size_t size) |
| 317 | BTimeSource::HandleMessage(int32 message, const void* rawdata, |
| 318 | size_t size) |
254 | 319 | { |
255 | 320 | PRINT(4, "BTimeSource::HandleMessage %#" B_PRIx32 ", node %" B_PRId32 "\n", |
256 | 321 | message, fNodeID); |
… |
… |
BTimeSource::HandleMessage(int32 message,
|
258 | 323 | switch (message) { |
259 | 324 | case TIMESOURCE_OP: |
260 | 325 | { |
261 | | const time_source_op_info *data = static_cast<const time_source_op_info *>(rawdata); |
| 326 | const time_source_op_info* data |
| 327 | = static_cast<const time_source_op_info*>(rawdata); |
262 | 328 | |
263 | 329 | status_t result; |
264 | 330 | result = TimeSourceOp(*data, NULL); |
… |
… |
BTimeSource::HandleMessage(int32 message,
|
285 | 351 | |
286 | 352 | case TIMESOURCE_ADD_SLAVE_NODE: |
287 | 353 | { |
288 | | const timesource_add_slave_node_command *data = static_cast<const timesource_add_slave_node_command *>(rawdata); |
| 354 | const timesource_add_slave_node_command* data |
| 355 | = static_cast<const timesource_add_slave_node_command*>(rawdata); |
289 | 356 | DirectAddMe(data->node); |
290 | 357 | return B_OK; |
291 | 358 | } |
292 | 359 | |
293 | 360 | case TIMESOURCE_REMOVE_SLAVE_NODE: |
294 | 361 | { |
295 | | const timesource_remove_slave_node_command *data = static_cast<const timesource_remove_slave_node_command *>(rawdata); |
| 362 | const timesource_remove_slave_node_command* data |
| 363 | = static_cast<const timesource_remove_slave_node_command*>(rawdata); |
296 | 364 | DirectRemoveMe(data->node); |
297 | 365 | return B_OK; |
298 | 366 | } |
299 | 367 | |
300 | 368 | case TIMESOURCE_GET_START_LATENCY: |
301 | 369 | { |
302 | | const timesource_get_start_latency_request *request = static_cast<const timesource_get_start_latency_request *>(rawdata); |
| 370 | const timesource_get_start_latency_request* request |
| 371 | = static_cast<const timesource_get_start_latency_request*>(rawdata); |
303 | 372 | timesource_get_start_latency_reply reply; |
304 | 373 | rv = GetStartLatency(&reply.start_latency); |
305 | 374 | request->SendReply(rv, &reply, sizeof(reply)); |
… |
… |
BTimeSource::HandleMessage(int32 message,
|
312 | 381 | |
313 | 382 | void |
314 | 383 | BTimeSource::PublishTime(bigtime_t performance_time, |
315 | | bigtime_t real_time, |
316 | | float drift) |
| 384 | bigtime_t real_time, float drift) |
317 | 385 | { |
318 | 386 | TRACE_TIMESOURCE("BTimeSource::PublishTime timesource %" B_PRId32 |
319 | 387 | ", perf %16" B_PRId64 ", real %16" B_PRId64 ", drift %2.2f\n", ID(), |
… |
… |
BTimeSource::PublishTime(bigtime_t performance_time,
|
332 | 400 | fBuf->perftime[index] = performance_time; |
333 | 401 | fBuf->drift[index] = drift; |
334 | 402 | atomic_add(&fBuf->readindex, 1); |
335 | | |
336 | | // printf("BTimeSource::PublishTime timesource %ld, write index %ld, perf %16Ld, real %16Ld, drift %2.2f\n", ID(), index, performance_time, real_time, drift); |
337 | 403 | } |
338 | 404 | |
339 | 405 | |
340 | 406 | void |
341 | 407 | BTimeSource::BroadcastTimeWarp(bigtime_t at_real_time, |
342 | | bigtime_t new_performance_time) |
| 408 | bigtime_t new_performance_time) |
343 | 409 | { |
344 | 410 | CALLED(); |
345 | 411 | ASSERT(fSlaveNodes != NULL); |
… |
… |
BTimeSource::BroadcastTimeWarp(bigtime_t at_real_time,
|
350 | 416 | ", new_performance_time %" B_PRId64 "\n", at_real_time, |
351 | 417 | new_performance_time); |
352 | 418 | |
353 | | BAutolock lock(fSlaveNodes->locker); |
| 419 | BAutolock lock(fSlaveNodes); |
354 | 420 | |
355 | | for (int i = 0, n = 0; i < SLAVE_NODES_COUNT && n != fSlaveNodes->count; i++) { |
356 | | if (fSlaveNodes->node_id[i] != 0) { |
357 | | node_time_warp_command cmd; |
358 | | cmd.at_real_time = at_real_time; |
359 | | cmd.to_performance_time = new_performance_time; |
360 | | SendToPort(fSlaveNodes->node_port[i], NODE_TIME_WARP, &cmd, sizeof(cmd)); |
361 | | n++; |
362 | | } |
| 421 | for (int i = 0; i < fSlaveNodes->CountSlaves(); i++) { |
| 422 | node_time_warp_command cmd; |
| 423 | cmd.at_real_time = at_real_time; |
| 424 | cmd.to_performance_time = new_performance_time; |
| 425 | SendToPort(fSlaveNodes->PortAt(i), NODE_TIME_WARP, |
| 426 | &cmd, sizeof(cmd)); |
363 | 427 | } |
364 | 428 | } |
365 | 429 | |
… |
… |
BTimeSource::SendRunMode(run_mode mode)
|
372 | 436 | |
373 | 437 | // send the run mode change to all slaved nodes |
374 | 438 | |
375 | | BAutolock lock(fSlaveNodes->locker); |
| 439 | BAutolock lock(fSlaveNodes); |
376 | 440 | |
377 | | for (int i = 0, n = 0; i < SLAVE_NODES_COUNT && n != fSlaveNodes->count; i++) { |
378 | | if (fSlaveNodes->node_id[i] != 0) { |
379 | | node_set_run_mode_command cmd; |
380 | | cmd.mode = mode; |
381 | | SendToPort(fSlaveNodes->node_port[i], NODE_SET_RUN_MODE, &cmd, sizeof(cmd)); |
382 | | n++; |
383 | | } |
| 441 | for (int i = 0; i < fSlaveNodes->CountSlaves(); i++) { |
| 442 | node_set_run_mode_command cmd; |
| 443 | cmd.mode = mode; |
| 444 | SendToPort(fSlaveNodes->PortAt(i), NODE_SET_RUN_MODE, |
| 445 | &cmd, sizeof(cmd)); |
384 | 446 | } |
385 | 447 | } |
386 | 448 | |
… |
… |
status_t BTimeSource::_Reserved_TimeSource_4(void *) { return B_ERROR; }
|
410 | 472 | status_t BTimeSource::_Reserved_TimeSource_5(void *) { return B_ERROR; } |
411 | 473 | |
412 | 474 | /* explicit */ |
413 | | BTimeSource::BTimeSource(media_node_id id) : |
| 475 | BTimeSource::BTimeSource(media_node_id id) |
| 476 | : |
414 | 477 | BMediaNode("This one is never called"), |
415 | 478 | fStarted(false), |
416 | 479 | fArea(-1), |
… |
… |
BTimeSource::BTimeSource(media_node_id id) :
|
421 | 484 | CALLED(); |
422 | 485 | AddNodeKind(B_TIME_SOURCE); |
423 | 486 | ASSERT(id > 0); |
424 | | // printf("###### explicit BTimeSource::BTimeSource() id %ld, name %s\n", id, Name()); |
425 | 487 | |
426 | | // This constructor is only called by the derived BPrivate::media::TimeSourceObject objects |
427 | | // We create a clone of the communication area |
| 488 | // This constructor is only called by the derived |
| 489 | // BPrivate::media::TimeSourceObject objects |
| 490 | // We create a clone of the communication area. |
428 | 491 | char name[32]; |
429 | 492 | area_id area; |
430 | 493 | sprintf(name, "__timesource_buf_%" B_PRId32, id); |
… |
… |
BTimeSource::BTimeSource(media_node_id id) :
|
435 | 498 | return; |
436 | 499 | } |
437 | 500 | sprintf(name, "__cloned_timesource_buf_%" B_PRId32, id); |
438 | | fArea = clone_area(name, reinterpret_cast<void **>(const_cast<BPrivate::media::TimeSourceTransmit **>(&fBuf)), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); |
| 501 | |
| 502 | void** buf = reinterpret_cast<void**> |
| 503 | (const_cast<BPrivate::media::TimeSourceTransmit**>(&fBuf)); |
| 504 | |
| 505 | fArea = clone_area(name, buf, B_ANY_ADDRESS, |
| 506 | B_READ_AREA | B_WRITE_AREA, area); |
| 507 | |
439 | 508 | if (fArea <= 0) { |
440 | 509 | ERROR("BTimeSource::BTimeSource couldn't clone area, node %" B_PRId32 |
441 | 510 | "\n", id); |
… |
… |
void
|
448 | 517 | BTimeSource::FinishCreate() |
449 | 518 | { |
450 | 519 | CALLED(); |
451 | | //printf("BTimeSource::FinishCreate(), id %ld\n", ID()); |
452 | 520 | |
453 | 521 | char name[32]; |
454 | 522 | sprintf(name, "__timesource_buf_%" B_PRId32, ID()); |
455 | | fArea = create_area(name, reinterpret_cast<void **>(const_cast<BPrivate::media::TimeSourceTransmit **>(&fBuf)), B_ANY_ADDRESS, TS_AREA_SIZE, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA); |
| 523 | |
| 524 | void** buf = reinterpret_cast<void**> |
| 525 | (const_cast<BPrivate::media::TimeSourceTransmit**>(&fBuf)); |
| 526 | |
| 527 | fArea = create_area(name, buf, B_ANY_ADDRESS, TS_AREA_SIZE, |
| 528 | B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA); |
| 529 | |
456 | 530 | if (fArea <= 0) { |
457 | 531 | ERROR("BTimeSource::BTimeSource couldn't create area, node %" B_PRId32 |
458 | 532 | "\n", ID()); |
… |
… |
BTimeSource::FinishCreate()
|
469 | 543 | |
470 | 544 | |
471 | 545 | status_t |
472 | | BTimeSource::RemoveMe(BMediaNode *node) |
| 546 | BTimeSource::RemoveMe(BMediaNode* node) |
473 | 547 | { |
474 | 548 | CALLED(); |
475 | 549 | if (fKinds & NODE_KIND_SHADOW_TIMESOURCE) { |
476 | 550 | timesource_remove_slave_node_command cmd; |
477 | 551 | cmd.node = node->Node(); |
478 | | SendToPort(fControlPort, TIMESOURCE_REMOVE_SLAVE_NODE, &cmd, sizeof(cmd)); |
| 552 | SendToPort(fControlPort, TIMESOURCE_REMOVE_SLAVE_NODE, |
| 553 | &cmd, sizeof(cmd)); |
479 | 554 | } else { |
480 | 555 | DirectRemoveMe(node->Node()); |
481 | 556 | } |
… |
… |
BTimeSource::RemoveMe(BMediaNode *node)
|
484 | 559 | |
485 | 560 | |
486 | 561 | status_t |
487 | | BTimeSource::AddMe(BMediaNode *node) |
| 562 | BTimeSource::AddMe(BMediaNode* node) |
488 | 563 | { |
489 | 564 | CALLED(); |
490 | 565 | if (fKinds & NODE_KIND_SHADOW_TIMESOURCE) { |
… |
… |
BTimeSource::AddMe(BMediaNode *node)
|
499 | 574 | |
500 | 575 | |
501 | 576 | void |
502 | | BTimeSource::DirectAddMe(const media_node &node) |
| 577 | BTimeSource::DirectAddMe(const media_node& node) |
503 | 578 | { |
504 | 579 | // XXX this code has race conditions and is pretty dumb, and it |
505 | 580 | // XXX won't detect nodes that crash and don't remove themself. |
506 | 581 | |
507 | 582 | CALLED(); |
508 | 583 | ASSERT(fSlaveNodes != NULL); |
509 | | BAutolock lock(fSlaveNodes->locker); |
| 584 | BAutolock lock(fSlaveNodes); |
510 | 585 | |
511 | | if (fSlaveNodes->count == SLAVE_NODES_COUNT) { |
| 586 | if (fSlaveNodes->CountSlaves() == MAX_SLAVE_NODES) { |
512 | 587 | ERROR("BTimeSource::DirectAddMe out of slave node slots\n"); |
513 | 588 | return; |
514 | 589 | } |
… |
… |
BTimeSource::DirectAddMe(const media_node &node)
|
516 | 591 | ERROR("BTimeSource::DirectAddMe should not add itself to slave nodes\n"); |
517 | 592 | return; |
518 | 593 | } |
519 | | for (int i = 0; i < SLAVE_NODES_COUNT; i++) { |
520 | | if (fSlaveNodes->node_id[i] == 0) { |
521 | | fSlaveNodes->node_id[i] = node.node; |
522 | | fSlaveNodes->node_port[i] = node.port; |
523 | | fSlaveNodes->count += 1; |
524 | | if (fSlaveNodes->count == 1) { |
525 | | // start the time source |
526 | | time_source_op_info msg; |
527 | | msg.op = B_TIMESOURCE_START; |
528 | | msg.real_time = RealTime(); |
529 | | TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID()); |
530 | | write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg)); |
531 | | } |
532 | | return; |
533 | | } |
| 594 | |
| 595 | if (fSlaveNodes->InsertSlave(node) != true) |
| 596 | ERROR("BTimeSource::DirectAddMe failed\n"); |
| 597 | |
| 598 | if (fSlaveNodes->CountSlaves() == 1) { |
| 599 | // start the time source |
| 600 | time_source_op_info msg; |
| 601 | msg.op = B_TIMESOURCE_START; |
| 602 | msg.real_time = RealTime(); |
| 603 | |
| 604 | TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID()); |
| 605 | |
| 606 | write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg)); |
534 | 607 | } |
535 | | ERROR("BTimeSource::DirectAddMe failed\n"); |
536 | 608 | } |
537 | 609 | |
538 | 610 | void |
539 | | BTimeSource::DirectRemoveMe(const media_node &node) |
| 611 | BTimeSource::DirectRemoveMe(const media_node& node) |
540 | 612 | { |
541 | 613 | // XXX this code has race conditions and is pretty dumb, and it |
542 | 614 | // XXX won't detect nodes that crash and don't remove themself. |
543 | 615 | |
544 | 616 | CALLED(); |
545 | 617 | ASSERT(fSlaveNodes != NULL); |
546 | | BAutolock lock(fSlaveNodes->locker); |
| 618 | BAutolock lock(fSlaveNodes); |
547 | 619 | |
548 | | if (fSlaveNodes->count == 0) { |
| 620 | if (fSlaveNodes->CountSlaves() == 0) { |
549 | 621 | ERROR("BTimeSource::DirectRemoveMe no slots used\n"); |
550 | 622 | return; |
551 | 623 | } |
552 | | for (int i = 0; i < SLAVE_NODES_COUNT; i++) { |
553 | | if (fSlaveNodes->node_id[i] == node.node && fSlaveNodes->node_port[i] == node.port) { |
554 | | fSlaveNodes->node_id[i] = 0; |
555 | | fSlaveNodes->node_port[i] = 0; |
556 | | fSlaveNodes->count -= 1; |
557 | | if (fSlaveNodes->count == 0) { |
558 | | // stop the time source |
559 | | time_source_op_info msg; |
560 | | msg.op = B_TIMESOURCE_STOP_IMMEDIATELY; |
561 | | msg.real_time = RealTime(); |
562 | | TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID()); |
563 | | write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg)); |
564 | | } |
565 | | return; |
566 | | } |
| 624 | |
| 625 | if (fSlaveNodes->RemoveSlave(node) != true) |
| 626 | ERROR("BTimeSource::DirectRemoveMe failed\n"); |
| 627 | |
| 628 | if (fSlaveNodes->CountSlaves() == 0) { |
| 629 | // stop the time source |
| 630 | time_source_op_info msg; |
| 631 | msg.op = B_TIMESOURCE_STOP_IMMEDIATELY; |
| 632 | msg.real_time = RealTime(); |
| 633 | |
| 634 | TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID()); |
| 635 | |
| 636 | write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg)); |
567 | 637 | } |
568 | | ERROR("BTimeSource::DirectRemoveMe failed\n"); |
569 | 638 | } |
570 | 639 | |
571 | 640 | void |
… |
… |
BTimeSource::DirectStart(bigtime_t at)
|
580 | 649 | |
581 | 650 | |
582 | 651 | void |
583 | | BTimeSource::DirectStop(bigtime_t at, |
584 | | bool immediate) |
| 652 | BTimeSource::DirectStop(bigtime_t at, bool immediate) |
585 | 653 | { |
586 | 654 | CALLED(); |
587 | 655 | if (fBuf) |
… |
… |
BTimeSource::DirectStop(bigtime_t at,
|
592 | 660 | |
593 | 661 | |
594 | 662 | void |
595 | | BTimeSource::DirectSeek(bigtime_t to, |
596 | | bigtime_t at) |
| 663 | BTimeSource::DirectSeek(bigtime_t to, bigtime_t at) |
597 | 664 | { |
598 | 665 | UNIMPLEMENTED(); |
599 | 666 | } |