Made time sources mode BeOS R5 conforming.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2395 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2003-01-09 17:54:20 +00:00
parent cfe8d4a743
commit d6379053ba
7 changed files with 84 additions and 34 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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<void **>(const_cast<BPrivate::media::TimeSourceTransmit **>(&fBuf)), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
sprintf(name, "__cloned_timesource_buf_%ld", id);
fArea = clone_area(name, reinterpret_cast<void **>(const_cast<BPrivate::media::TimeSourceTransmit **>(&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;
}

View File

@ -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());
}

View File

@ -11,12 +11,16 @@
#include <TimeSource.h>
#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

View File

@ -23,6 +23,7 @@ TimeSourceObjectManager::TimeSourceObjectManager()
: fSystemTimeSource(0),
fSystemTimeSourceID(0)
{
CALLED();
fLock = new BLocker("timesource object manager locker");
fMap = new Map<media_node_id,BTimeSource *>;
}
@ -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());

View File

@ -399,6 +399,7 @@ NodeManager::GetLiveNodes(Stack<live_node_info> *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;