diff --git a/headers/os/media/TimeSource.h b/headers/os/media/TimeSource.h index dc847eef1e..aa737d62a4 100644 --- a/headers/os/media/TimeSource.h +++ b/headers/os/media/TimeSource.h @@ -121,7 +121,7 @@ virtual status_t _Reserved_TimeSource_3(void *); virtual status_t _Reserved_TimeSource_4(void *); virtual status_t _Reserved_TimeSource_5(void *); - bool fStopped; + bool fStarted; area_id fArea; volatile BPrivate::media::TimeSourceTransmit *fBuf; _BSlaveNodeStorageP * _mSlaveNodes; diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index f82dbd85b5..b968d5b638 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -15,6 +15,7 @@ #include "DataExchange.h" #include "ServerInterface.h" #include "Notifications.h" +#include "TimeSourceObject.h" // don't rename this one, it's used and exported for binary compatibility int32 BMediaNode::_m_changeTag = 0; @@ -101,12 +102,17 @@ BMediaNode::~BMediaNode() // BeBook: UnregisterNode() unregisters a node from the Media Server. It's called automatically // BeBook: by the BMediaNode destructor, but it might be convenient to call it sometime before // BeBook: you delete your node instance, depending on your implementation and circumstances. - // ATT! We do not unregister TimeSourceObject nodes (identified by fControlPort == -999666) - if (fControlPort != -999666) // must match value in TimeSourceObject::TimeSourceObject() - (BMediaRoster::Roster())->UnregisterNode(this); + + // Attention! We do not unregister TimeSourceObject nodes, + // or delete their control ports, since they are only a + // shadow object, and the real one still exists + if (0 == (fKinds & NODE_KIND_SHADOW_TIMESOURCE)) { + BMediaRoster::Roster()->UnregisterNode(this); - if (fControlPort > 0) - delete_port(fControlPort); + if (fControlPort > 0) + delete_port(fControlPort); + } + if (fTimeSource) fTimeSource->Release(); } @@ -159,7 +165,7 @@ uint64 BMediaNode::Kinds() const { CALLED(); - return fKinds; + return fKinds & NODE_KIND_USER_MASK; } @@ -200,13 +206,14 @@ BMediaNode::TimeSource() const return NULL; } self->fTimeSource = roster->MakeTimeSourceFor(clone); + ASSERT(fTimeSource == self->fTimeSource); if (fTimeSource == 0) { FATAL("BMediaNode::TimeSource: Error, MakeTimeSourceFor failed\n"); } else { fTimeSource->AddMe(self); } rv = roster->ReleaseNode(clone); - if (fTimeSource == 0) { + if (rv != B_OK) { FATAL("BMediaNode::TimeSource: Error, ReleaseNode failed\n"); } @@ -479,6 +486,7 @@ BMediaNode::SetTimeSource(BTimeSource *time_source) newsource->AddMe(this); } fTimeSource = newsource; + //BMediaRoster::Roster()->StartTimeSource(fTimeSource->Node(), fTimeSource->RealTime()); } /************************************************************* @@ -567,6 +575,7 @@ BMediaNode::HandleMessage(int32 message, fTimeSource = newsource; } fTimeSource->AddMe(this); + //roster->StartTimeSource(fTimeSource->Node(), fTimeSource->RealTime()); return B_OK; } @@ -791,7 +800,7 @@ BMediaNode::_InitObject(const char *name, media_node_id id, uint64 kinds) TRACE("BMediaNode::_InitObject: nodeid %ld, this %p\n", id, this); fNodeID = id; - fTimeSource = 0; + fTimeSource = NULL; fRefCount = 1; fName[0] = 0; if (name) { diff --git a/src/kits/media/TimeSource.cpp b/src/kits/media/TimeSource.cpp index 8e139602c0..f95616fe0e 100644 --- a/src/kits/media/TimeSource.cpp +++ b/src/kits/media/TimeSource.cpp @@ -10,11 +10,12 @@ namespace BPrivate { namespace media { -struct TimeSourceTransmit +struct TimeSourceTransmit // sizeof() must be <= 4096 { #define INDEX_COUNT 128 int32 readindex; int32 writeindex; + int32 isrunning; bigtime_t realtime[INDEX_COUNT]; bigtime_t perftime[INDEX_COUNT]; float drift[INDEX_COUNT]; @@ -102,8 +103,11 @@ bool BTimeSource::IsRunning() { CALLED(); - printf("BTimeSource::IsRunning() node %ld, port %ld, %s\n", fNodeID, fControlPort, fStopped ? "no" : "yes"); - return !fStopped; + bool isrunning; + isrunning = fBuf ? atomic_add(&fBuf->isrunning, 0) : fStarted; + + printf("BTimeSource::IsRunning() node %ld, port %ld, %s\n", fNodeID, fControlPort, isrunning ? "yes" : "no"); + return isrunning; } @@ -166,7 +170,7 @@ BTimeSource::GetStartLatency(bigtime_t *out_latency) BTimeSource::BTimeSource() : BMediaNode("This one is never called"), - fStopped(false), + fStarted(false), fArea(-1), fBuf(NULL), fIsRealtime(false) @@ -224,8 +228,11 @@ BTimeSource::PublishTime(bigtime_t performance_time, float drift) { printf("BTimeSource::PublishTime timesource %ld, perf %16Ld, real %16Ld, drift %2.2f\n", ID(), performance_time, real_time, drift); - if (0 == fBuf) + if (0 == fBuf) { + FATAL("BTimeSource::PublishTime timesource %ld, fBuf = NULL\n", ID()); + fStarted = true; return; + } int32 index; index = atomic_add(&fBuf->writeindex, 1) & (INDEX_COUNT - 1); @@ -280,7 +287,7 @@ status_t BTimeSource::_Reserved_TimeSource_5(void *) { return B_ERROR; } /* explicit */ BTimeSource::BTimeSource(media_node_id id) : BMediaNode("This one is never called"), - fStopped(false), + fStarted(false), fArea(-1), fBuf(NULL), fIsRealtime(false) @@ -300,7 +307,8 @@ BTimeSource::BTimeSource(media_node_id id) : FATAL("BTimeSource::BTimeSource couldn't find area, node %ld\n", id); return; } - fArea = clone_area("__some_timesource_buf", reinterpret_cast(const_cast(&fBuf)), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); + sprintf(name, "__cloned_timesource_buf_%ld", id); + fArea = clone_area(name, reinterpret_cast(const_cast(&fBuf)), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); if (fArea <= 0) { FATAL("BTimeSource::BTimeSource couldn't clone area, node %ld\n", id); return; @@ -327,6 +335,7 @@ BTimeSource::FinishCreate() fBuf->realtime[0] = 0; fBuf->perftime[0] = 0; fBuf->drift[0] = 1.0f; + fBuf->isrunning = fStarted; } @@ -352,7 +361,10 @@ void BTimeSource::DirectStart(bigtime_t at) { UNIMPLEMENTED(); - fStopped = false; + if (fBuf) + atomic_or(&fBuf->isrunning, 1); + else + fStarted = true; } @@ -361,7 +373,10 @@ BTimeSource::DirectStop(bigtime_t at, bool immediate) { UNIMPLEMENTED(); - fStopped = true; + if (fBuf) + atomic_and(&fBuf->isrunning, 0); + else + fStarted = false; } diff --git a/src/kits/media/TimeSourceObject.cpp b/src/kits/media/TimeSourceObject.cpp index d5e3de76b4..0a11f40df3 100644 --- a/src/kits/media/TimeSourceObject.cpp +++ b/src/kits/media/TimeSourceObject.cpp @@ -13,14 +13,26 @@ #include "TimeSourceObject.h" #include "TimeSourceObjectManager.h" -TimeSourceObject::TimeSourceObject(media_node_id id) : - BMediaNode("some timesource object", id, B_TIME_SOURCE), - BTimeSource(id) +TimeSourceObject::TimeSourceObject(const media_node &node) + : BMediaNode("some timesource object", node.node, node.kind), + BTimeSource(node.node) { // printf("TimeSourceObject::TimeSourceObject enter, id = %ld\n", id); - delete_port(fControlPort); - fControlPort = -999666; // must match value in BMediaNode::~BMediaNode() - ASSERT(id == fNodeID); + if (fControlPort > 0) + delete_port(fControlPort); + fControlPort = node.port; + ASSERT(fNodeID == node.node); + ASSERT(fKinds == node.kind); + + live_node_info lni; + if (B_OK == BMediaRoster::Roster()->GetLiveNodeInfo(node, &lni)) { + strcpy(fName, lni.name); + } else { + sprintf(fName, "timesource %ld", node.node); + } + + AddNodeKind(NODE_KIND_SHADOW_TIMESOURCE); + fControlPort = -1234; // printf("TimeSourceObject::TimeSourceObject leave, node id %ld\n", fNodeID); } @@ -52,12 +64,13 @@ TimeSourceObject::DeleteHook(BMediaNode *node) } -SystemTimeSourceObject::SystemTimeSourceObject(media_node_id id) - : BMediaNode("System Time Source", id, B_TIME_SOURCE), - TimeSourceObject(id) +SystemTimeSourceObject::SystemTimeSourceObject(const media_node &node) + : BMediaNode("System Clock", node.node, node.kind), + TimeSourceObject(node) { // printf("SystemTimeSourceObject::SystemTimeSourceObject enter, id = %ld\n", id); fIsRealtime = true; + AddNodeKind(NODE_KIND_SYSTEM_TIMESOURCE); // printf("SystemTimeSourceObject::SystemTimeSourceObject leave, node id %ld\n", ID()); } diff --git a/src/kits/media/TimeSourceObject.h b/src/kits/media/TimeSourceObject.h index 948ae423be..fdb98154c6 100644 --- a/src/kits/media/TimeSourceObject.h +++ b/src/kits/media/TimeSourceObject.h @@ -11,12 +11,16 @@ #include +#define NODE_KIND_USER_MASK 0x00000000FFFFFFFFLL +#define NODE_KIND_SHADOW_TIMESOURCE 0x0000000100000000LL +#define NODE_KIND_SYSTEM_TIMESOURCE 0x0000000200000000LL + namespace BPrivate { namespace media { class TimeSourceObject : public BTimeSource { public: - TimeSourceObject(media_node_id id); + TimeSourceObject(const media_node &node); protected: virtual status_t TimeSourceOp( @@ -33,7 +37,7 @@ protected: class SystemTimeSourceObject : public TimeSourceObject { public: - SystemTimeSourceObject(media_node_id id); + SystemTimeSourceObject(const media_node &node); protected: // override from BMediaNode diff --git a/src/kits/media/TimeSourceObjectManager.cpp b/src/kits/media/TimeSourceObjectManager.cpp index e62e50d43a..0a5cadc81e 100644 --- a/src/kits/media/TimeSourceObjectManager.cpp +++ b/src/kits/media/TimeSourceObjectManager.cpp @@ -23,6 +23,7 @@ TimeSourceObjectManager::TimeSourceObjectManager() : fSystemTimeSource(0), fSystemTimeSourceID(0) { + CALLED(); fLock = new BLocker("timesource object manager locker"); fMap = new Map; } @@ -30,6 +31,7 @@ TimeSourceObjectManager::TimeSourceObjectManager() TimeSourceObjectManager::~TimeSourceObjectManager() { + CALLED(); delete fLock; // force unloading all currently loaded @@ -48,6 +50,7 @@ TimeSourceObjectManager::~TimeSourceObjectManager() BTimeSource * TimeSourceObjectManager::GetTimeSource(const media_node &node) { + CALLED(); BAutolock lock(fLock); // printf("TimeSourceObjectManager::GetTimeSource, node id %ld\n", node.node); @@ -55,14 +58,14 @@ TimeSourceObjectManager::GetTimeSource(const media_node &node) if (fSystemTimeSource == 0) { media_node clone; status_t rv; - rv = BMediaRoster::Roster()->GetSystemTimeSource(&clone); + // XXX this clone is never released + rv = BMediaRoster::Roster()->GetSystemTimeSource(&clone); if (rv != B_OK) { FATAL("TimeSourceObjectManager::GetTimeSource, GetSystemTimeSource failed\n"); return NULL; } - fSystemTimeSourceID = clone.node; - fSystemTimeSource = new SystemTimeSourceObject(fSystemTimeSourceID); - ASSERT(fSystemTimeSourceID == fSystemTimeSource->ID()); + fSystemTimeSource = new SystemTimeSourceObject(clone); + fSystemTimeSourceID = fSystemTimeSource->ID(); } if (node.node == fSystemTimeSourceID) @@ -82,7 +85,7 @@ TimeSourceObjectManager::GetTimeSource(const media_node &node) } BTimeSource *ts; - ts = new TimeSourceObject(clone.node); + ts = new TimeSourceObject(clone); fMap->Insert(clone.node, ts); return ts; } @@ -90,6 +93,7 @@ TimeSourceObjectManager::GetTimeSource(const media_node &node) void TimeSourceObjectManager::ObjectDeleted(BTimeSource *timesource) { + CALLED(); BAutolock lock(fLock); // printf("TimeSourceObjectManager::ObjectDeleted, node id %ld\n", timesource->ID()); diff --git a/src/servers/media/NodeManager.cpp b/src/servers/media/NodeManager.cpp index 10eeb2333d..eefd2e7851 100644 --- a/src/servers/media/NodeManager.cpp +++ b/src/servers/media/NodeManager.cpp @@ -399,6 +399,7 @@ NodeManager::GetLiveNodes(Stack *livenodes, int32 maxcount, cons } + status_t NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &node) { @@ -407,6 +408,10 @@ NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node & registered_node *rn; for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) { if (rn->nodeid == node.node) { + if (rn->addon_id == -1) { // This function must return an error if the node is application owned + TRACE("NodeManager::GetDormantNodeInfo NODE IS APPLICATION OWNED! node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name); + return B_ERROR; + } ASSERT(node.port == rn->port); ASSERT(node.kind == rn->kinds); node_info->addon = rn->addon_id;