Reference counters are strictly enforced.

git-svn-id: http://voip.null.ro/svn/yate@651 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2006-01-18 16:06:05 +00:00
parent c0b59ae099
commit 6771d7472e
7 changed files with 47 additions and 16 deletions

View File

@ -87,9 +87,15 @@ bool CallEndpoint::connect(CallEndpoint* peer, const char* reason)
}
#endif
ref();
// are we already dead?
if (!ref())
return false;
disconnect(reason);
peer->ref();
// is our intended peer dead?
if (!peer->ref()) {
deref();
return false;
}
peer->disconnect(reason);
ObjList* l = m_data.skipNull();

View File

@ -212,7 +212,8 @@ void DataSource::Forward(const DataBlock& data, unsigned long tStamp)
if (f)
tStamp += f->guessSamples(data.length());
}
ref();
if (!ref())
return;
ObjList *l = m_consumers.skipNull();
for (; l; l=l->skipNext()) {
DataConsumer *c = static_cast<DataConsumer *>(l->get());

View File

@ -580,6 +580,8 @@ int Engine::run()
Thread::msleep(200);
m_dispatcher.dequeue();
checkPoint();
// We are occasionally doing things that can cause crashes so don't abort
abortOnBug(false);
Thread::killall();
checkPoint();
m_dispatcher.dequeue();

View File

@ -444,6 +444,8 @@ bool RefObject::deref()
s_refmutex.unlock();
if (i == 1)
zeroRefs();
else if (i <= 0)
Debug(DebugFail,"RefObject::deref() called with count=%d [%p]",i,this);
return (i <= 1);
}

View File

@ -254,9 +254,11 @@ void ThreadPrivate::run()
::pthread_detach(::pthread_self());
#endif
// FIXME: possible race if public object is destroyed during thread startup
while (!m_started)
Thread::usleep(10,true);
m_thread->run();
if (m_thread)
m_thread->run();
#ifndef _WINDOWS
pthread_cleanup_pop(1);

View File

@ -62,6 +62,7 @@ public:
{ return now > m_finish; }
static GenConnection* find(const String& id);
static bool oneCall(String* target = 0);
static int dropAll(bool resume = false);
private:
String m_status;
String m_callto;
@ -221,6 +222,26 @@ bool GenConnection::oneCall(String* target)
return false;
}
int GenConnection::dropAll(bool resume)
{
int dropped = 0;
s_mutex.lock();
s_runs = false;
ListIterator iter(s_calls);
for (;;) {
RefPointer<GenConnection> c = static_cast<GenConnection*>(iter.get());
s_mutex.unlock();
if (!c)
break;
c->disconnect();
c = 0;
s_mutex.lock();
++dropped;
}
s_runs = resume;
return dropped;
}
void GenConnection::disconnected(bool final, const char *reason)
{
Debug("CallGen",DebugInfo,"Disconnected '%s' reason '%s' [%p]",id().c_str(),reason,this);
@ -326,7 +347,7 @@ void CleanThread::run()
if (!c)
break;
if (c->oldAge(t))
c->destruct();
c->disconnect();
c = 0;
s_mutex.lock();
}
@ -372,17 +393,12 @@ bool CmdHandler::doCommand(String& line, String& rval)
s_runs = false;
s_numcalls = 0;
s_mutex.unlock();
s_calls.clear();
rval << "Stopping generator and clearing calls";
int dropped = GenConnection::dropAll();
rval << "Stopping generator and cleared " << dropped << " calls";
}
else if (line == "drop") {
s_mutex.lock();
bool tmp = s_runs;
s_runs = false;
s_mutex.unlock();
s_calls.clear();
s_runs = tmp;
rval << "Clearing calls and continuing";
int dropped = GenConnection::dropAll(s_runs);
rval << "Cleared " << dropped << " calls and continuing";
}
else if (line == "pause") {
s_runs = false;
@ -484,11 +500,12 @@ CallGenPlugin::CallGenPlugin()
CallGenPlugin::~CallGenPlugin()
{
Output("Unloading module Call Generator, clearing %u calls",s_calls.count());
s_mutex.lock();
Output("Unloading module Call Generator, clearing %u calls",s_calls.count());
s_runs = false;
s_calls.clear();
s_mutex.unlock();
GenConnection::dropAll();
s_calls.clear();
}
void CallGenPlugin::initialize()

View File

@ -2694,6 +2694,7 @@ bool SIPDriver::received(Message &msg, int id)
static_cast<YateSIPLine*>(l->get())->timer(msg.msgTime());
}
else if (id == Halt) {
dropAll(msg);
channels().clear();
s_lines.clear();
}