xref: /haiku/src/kits/media/TimeSourceObjectManager.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 /***********************************************************************
2  * Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
3  * This file may be used under the terms of the MIT License.
4  *
5  * This works like a cache for time source objects, to make sure
6  * each team only has one object representation for each time source.
7  *
8  ***********************************************************************/
9 
10 #include <OS.h>
11 #include <stdio.h>
12 #include <MediaRoster.h>
13 #include <Autolock.h>
14 #include "TimeSourceObjectManager.h"
15 #include "TimeSourceObject.h"
16 #include "MediaMisc.h"
17 #include "debug.h"
18 
19 
20 static BPrivate::media::TimeSourceObjectManager manager;
21 BPrivate::media::TimeSourceObjectManager *_TimeSourceObjectManager = &manager;
22 
23 namespace BPrivate {
24 namespace media {
25 
26 TimeSourceObjectManager::TimeSourceObjectManager()
27 // :	fSystemTimeSource(0)
28 {
29 	CALLED();
30 	fLock = new BLocker("timesource object manager locker");
31 	fMap = new Map<media_node_id, BTimeSource *>;
32 }
33 
34 
35 TimeSourceObjectManager::~TimeSourceObjectManager()
36 {
37 	CALLED();
38 	delete fLock;
39 
40 	// force unloading all currently loaded
41 	BTimeSource **pts;
42 	for (fMap->Rewind(); fMap->GetNext(&pts); ) {
43 		PRINT(1, "Forcing release of TimeSource id %ld...\n", (*pts)->ID());
44 		int debugcnt = 0;
45 		while ((*pts)->Release() != NULL)
46 			debugcnt++;
47 		PRINT(1, "Forcing release of TimeSource done, released %d times\n", debugcnt);
48 	}
49 
50 	delete fMap;
51 }
52 
53 /* BMediaRoster::MakeTimeSourceFor does use this function to request
54  * a time source object. If it is already in memory, it will be
55  * Acquired(), if not, a new TimeSourceObject will be created.
56  */
57 BTimeSource *
58 TimeSourceObjectManager::GetTimeSource(const media_node &node)
59 {
60 	CALLED();
61 	BAutolock lock(fLock);
62 
63 //	printf("TimeSourceObjectManager::GetTimeSource, node id %ld\n", node.node);
64 
65 	BTimeSource **pts;
66 	if (fMap->Get(node.node, &pts))
67 		return dynamic_cast<BTimeSource *>((*pts)->Acquire());
68 
69 	// time sources are not accounted in node reference counting
70 	BTimeSource *ts;
71 	ts = new TimeSourceObject(node);
72 	fMap->Insert(node.node, ts);
73 	return ts;
74 }
75 
76 /* This function is called during deletion of the time source object.
77  *
78  * I'm not sure if there is a race condition with the function above.
79  */
80 void
81 TimeSourceObjectManager::ObjectDeleted(BTimeSource *timesource)
82 {
83 	CALLED();
84 	BAutolock lock(fLock);
85 
86 //	printf("TimeSourceObjectManager::ObjectDeleted, node id %ld\n", timesource->ID());
87 
88 	bool b;
89 	b = fMap->Remove(timesource->ID());
90 	if (!b) {
91 		ERROR("TimeSourceObjectManager::ObjectDeleted, Remove failed\n");
92 	}
93 
94 	status_t rv;
95 	rv = BMediaRoster::Roster()->ReleaseNode(timesource->Node());
96 	if (rv != B_OK) {
97 		ERROR("TimeSourceObjectManager::ObjectDeleted, ReleaseNode failed\n");
98 	}
99 }
100 
101 }; // namespace media
102 }; // namespace BPrivate
103