no message

git-svn-id: http://yate.null.ro/svn/yate/trunk@378 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2005-05-30 15:13:02 +00:00
parent 3f261fc812
commit d6b03a2919
5 changed files with 217 additions and 17 deletions

View File

@ -232,7 +232,9 @@ void* DataSource::getObject(const String& name) const
}
DataEndpoint::DataEndpoint(CallEndpoint* call, const char* name)
: m_name(name), m_source(0), m_consumer(0), m_peer(0), m_call(call)
: m_name(name), m_source(0), m_consumer(0),
m_peer(0), m_call(call),
m_peerRecord(0), m_callRecord(0)
{
Debug(DebugInfo,"DataEndpoint::DataEndpoint(%p,'%s') [%p]",call,name,this);
if (m_call)
@ -246,6 +248,8 @@ DataEndpoint::~DataEndpoint()
if (m_call)
m_call->m_data.remove(this,false);
disconnect();
setPeerRecord();
setCallRecord();
setSource();
setConsumer();
}
@ -281,6 +285,9 @@ bool DataEndpoint::connect(DataEndpoint* peer)
if (!native) {
DataSource *s = getSource();
DataConsumer *c = peer->getConsumer();
if (s && c)
DataTranslator::attachChain(s,c);
c = peer->getPeerRecord();
if (s && c)
DataTranslator::attachChain(s,c);
@ -288,6 +295,9 @@ bool DataEndpoint::connect(DataEndpoint* peer)
c = getConsumer();
if (s && c)
DataTranslator::attachChain(s,c);
c = getPeerRecord();
if (s && c)
DataTranslator::attachChain(s,c);
}
m_peer = peer;
@ -304,11 +314,17 @@ void DataEndpoint::disconnect()
DataSource *s = getSource();
DataConsumer *c = m_peer->getConsumer();
if (s && c)
DataTranslator::detachChain(s,c);
c = m_peer->getPeerRecord();
if (s && c)
DataTranslator::detachChain(s,c);
s = m_peer->getSource();
c = getConsumer();
if (s && c)
DataTranslator::detachChain(s,c);
c = getPeerRecord();
if (s && c)
DataTranslator::detachChain(s,c);
@ -323,27 +339,50 @@ void DataEndpoint::setSource(DataSource* source)
{
if (source == m_source)
return;
DataConsumer *consumer = m_peer ? m_peer->getConsumer() : 0;
DataConsumer *c1 = m_peer ? m_peer->getConsumer() : 0;
DataConsumer *c2 = m_peer ? m_peer->getPeerRecord() : 0;
DataSource *temp = m_source;
if (consumer)
consumer->ref();
if (c1)
c1->ref();
if (c2)
c2->ref();
if (m_callRecord)
m_callRecord->ref();
m_source = 0;
if (temp) {
if (consumer) {
DataTranslator::detachChain(temp,consumer);
if (consumer->getConnSource())
Debug(DebugWarn,"consumer source not cleared in %p",consumer);
if (c1) {
DataTranslator::detachChain(temp,c1);
if (c1->getConnSource())
Debug(DebugWarn,"consumer source not cleared in %p",c1);
}
if (c2) {
DataTranslator::detachChain(temp,c2);
if (c2->getConnSource())
Debug(DebugWarn,"consumer source not cleared in %p",c2);
}
if (m_callRecord) {
DataTranslator::detachChain(temp,m_callRecord);
if (m_callRecord->getConnSource())
Debug(DebugWarn,"consumer source not cleared in %p",m_callRecord);
}
temp->deref();
}
if (source) {
source->ref();
if (consumer)
DataTranslator::attachChain(source,consumer);
if (c1)
DataTranslator::attachChain(source,c1);
if (c2)
DataTranslator::attachChain(source,c2);
if (m_callRecord)
DataTranslator::attachChain(source,m_callRecord);
}
m_source = source;
if (consumer)
consumer->deref();
if (c1)
c1->deref();
if (c2)
c2->deref();
if (m_callRecord)
m_callRecord->deref();
}
void DataEndpoint::setConsumer(DataConsumer* consumer)
@ -365,6 +404,43 @@ void DataEndpoint::setConsumer(DataConsumer* consumer)
}
}
void DataEndpoint::setPeerRecord(DataConsumer* consumer)
{
if (consumer == m_peerRecord)
return;
DataSource *source = m_peer ? m_peer->getSource() : 0;
DataConsumer *temp = m_peerRecord;
if (consumer) {
consumer->ref();
if (source)
DataTranslator::attachChain(source,consumer);
}
m_peerRecord = consumer;
if (temp) {
if (source)
DataTranslator::detachChain(source,temp);
temp->deref();
}
}
void DataEndpoint::setCallRecord(DataConsumer* consumer)
{
if (consumer == m_callRecord)
return;
DataConsumer *temp = m_callRecord;
if (consumer) {
consumer->ref();
if (m_source)
DataTranslator::attachChain(m_source,consumer);
}
m_callRecord = consumer;
if (temp) {
if (m_source)
DataTranslator::detachChain(m_source,temp);
temp->deref();
}
}
ThreadedSource::~ThreadedSource()
{
stop();

View File

@ -310,22 +310,19 @@ void ThreadPrivate::killall()
while (l && (t = static_cast<ThreadPrivate *>(l->get())) != 0)
{
Debug(DebugInfo,"Trying to kill ThreadPrivate '%s' [%p], attempt %d",t->m_name,t,c);
tmutex.unlock();
bool ok = t->cancel(c > SOFT_KILLS);
if (ok) {
int d = 0;
// delay a little (exponentially) so threads have a chance to clean up
for (int i=1; i<=KILL_WAIT; i<<=1) {
tmutex.unlock();
Thread::msleep(i-d);
d = i;
tmutex.lock();
bool done = (t != l->get());
tmutex.unlock();
if (done)
if (t != l->get())
break;
}
}
tmutex.lock();
if (t != l->get())
c = 1;
else {

View File

@ -97,6 +97,13 @@ public:
virtual bool received(Message &msg);
};
class RecordHandler : public MessageHandler
{
public:
RecordHandler() : MessageHandler("chan.record") { }
virtual bool received(Message &msg);
};
class WaveFileDriver : public Driver
{
public:
@ -430,6 +437,87 @@ bool AttachHandler::received(Message &msg)
return !more;
}
bool RecordHandler::received(Message &msg)
{
int more = 2;
String c1(msg.getValue("call"));
if (c1.null())
more--;
else {
Regexp r("^wave/\\([^/]*\\)/\\(.*\\)$");
if (c1.matches(r)) {
if (c1.matchString(1) == "record") {
c1 = c1.matchString(2);
more--;
}
else {
Debug(DebugWarn,"Could not attach call recorder with method '%s', use 'record'",
c1.matchString(1).c_str());
c1 = "";
}
}
else
c1 = "";
}
String c2(msg.getValue("peer"));
if (c2.null())
more--;
else {
Regexp r("^wave/\\([^/]*\\)/\\(.*\\)$");
if (c2.matches(r)) {
if (c2.matchString(1) == "record") {
c2 = c2.matchString(2);
more--;
}
else {
Debug(DebugWarn,"Could not attach peer recorder with method '%s', use 'record'",
c2.matchString(1).c_str());
c2 = "";
}
}
else
c2 = "";
}
if (c1.null() && c2.null())
return false;
String ml(msg.getValue("maxlen"));
unsigned maxlen = ml.toInteger(0);
CallEndpoint *ch = static_cast<CallEndpoint*>(msg.userData("CallEndpoint"));
DataEndpoint *de = static_cast<DataEndpoint*>(msg.userData("DataEndpoint"));
if (ch && !de)
de = ch->setEndpoint();
if (!de) {
if (!c1.null())
Debug(DebugWarn,"Wave source '%s' call record with no data channel!",c1.c_str());
if (!c2.null())
Debug(DebugWarn,"Wave source '%s' peer record with no data channel!",c2.c_str());
return false;
}
if (!c1.null()) {
WaveConsumer* c = new WaveConsumer(c1,ch,maxlen);
c->setNotify(msg.getValue("notify"));
de->setCallRecord(c);
c->deref();
}
if (!c2.null()) {
WaveConsumer* c = new WaveConsumer(c2,ch,maxlen);
c->setNotify(msg.getValue("notify"));
de->setPeerRecord(c);
c->deref();
}
// Stop dispatching if we handled all requested
return !more;
}
bool WaveFileDriver::msgExecute(Message& msg, String& dest)
{
Regexp r("^\\([^/]*\\)/\\(.*\\)$");
@ -509,6 +597,7 @@ void WaveFileDriver::initialize()
if (!m_handler) {
m_handler = new AttachHandler;
Engine::install(m_handler);
Engine::install(new RecordHandler);
}
}

View File

@ -235,6 +235,14 @@ public:
inline RefObject* userData() const
{ return m_data; }
/**
* Get a pointer to a derived class of user data given that class name
* @param name Name of the class we are asking for
* @return Pointer to the requested class or NULL if user object id NULL or doesn't implement it
*/
inline void* userData(const String& name) const
{ return m_data ? m_data->getObject(name) : 0; }
/**
* Set obscure data associated with the message.
* The user data is reference counted to avoid stray pointers.

View File

@ -669,6 +669,34 @@ public:
inline DataConsumer* getConsumer() const
{ return m_consumer; }
/**
* Set the data consumer for recording peer generated data.
* This will be connected to the peer data source.
* @param consumer A pointer to the new consumer or NULL
*/
void setPeerRecord(DataConsumer* consumer = 0);
/**
* Get the data consumer used for recording peer generated data.
* @return A pointer to the DataConsumer object or NULL
*/
inline DataConsumer* getPeerRecord() const
{ return m_peerRecord; }
/**
* Set the data consumer for recording local call generated data
* This will be connected to the local data source.
* @param consumer A pointer to the new consumer or NULL
*/
void setCallRecord(DataConsumer* consumer = 0);
/**
* Get the data consumer used for recording local call generated data.
* @return A pointer to the DataConsumer object or NULL
*/
inline DataConsumer* getCallRecord() const
{ return m_callRecord; }
/*
* Get a pointer to the peer endpoint
* @return A pointer to the peer endpoint or NULL
@ -705,6 +733,8 @@ private:
DataConsumer* m_consumer;
DataEndpoint* m_peer;
CallEndpoint* m_call;
DataConsumer* m_peerRecord;
DataConsumer* m_callRecord;
};
/**