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