Fixed a nasty bug in Linux TLS initialization.
Improved thread/mutex debugging. git-svn-id: http://yate.null.ro/svn/yate/trunk@652 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
73e01366aa
commit
8faacfe499
|
@ -51,7 +51,8 @@ public:
|
|||
: DataTranslator(sFormat,dFormat) { }
|
||||
virtual void Consume(const DataBlock& data, unsigned long tStamp)
|
||||
{
|
||||
ref();
|
||||
if (!ref())
|
||||
return;
|
||||
if (getTransSource()) {
|
||||
DataBlock oblock;
|
||||
if (oblock.convert(data, m_format, getTransSource()->getFormat())) {
|
||||
|
@ -228,10 +229,9 @@ bool DataSource::attach(DataConsumer* consumer, bool override)
|
|||
{
|
||||
DDebug(DebugAll,"DataSource [%p] attaching consumer%s [%p]",
|
||||
this,(override ? " as override" : ""),consumer);
|
||||
if (!consumer)
|
||||
if (!(consumer && consumer->ref()))
|
||||
return false;
|
||||
Lock lock(m_mutex);
|
||||
consumer->ref();
|
||||
if (override) {
|
||||
// adjust timestamp for possible gaps in data
|
||||
int64_t dt = Time::now() - consumer->m_lastTsTime;
|
||||
|
@ -355,7 +355,8 @@ bool DataEndpoint::connect(DataEndpoint* peer)
|
|||
return true;
|
||||
DDebug(DebugInfo,"DataEndpoint '%s' connecting peer %p to [%p]",m_name.c_str(),peer,this);
|
||||
|
||||
ref();
|
||||
if (!ref())
|
||||
return false;
|
||||
disconnect();
|
||||
peer->ref();
|
||||
peer->disconnect();
|
||||
|
@ -471,9 +472,12 @@ void DataEndpoint::setConsumer(DataConsumer* consumer)
|
|||
DataSource *source = m_peer ? m_peer->getSource() : 0;
|
||||
DataConsumer *temp = m_consumer;
|
||||
if (consumer) {
|
||||
consumer->ref();
|
||||
if (source)
|
||||
DataTranslator::attachChain(source,consumer);
|
||||
if (consumer->ref()) {
|
||||
if (source)
|
||||
DataTranslator::attachChain(source,consumer);
|
||||
}
|
||||
else
|
||||
consumer = 0;
|
||||
}
|
||||
m_consumer = consumer;
|
||||
if (temp) {
|
||||
|
@ -490,9 +494,12 @@ void DataEndpoint::setPeerRecord(DataConsumer* consumer)
|
|||
DataSource *source = m_peer ? m_peer->getSource() : 0;
|
||||
DataConsumer *temp = m_peerRecord;
|
||||
if (consumer) {
|
||||
consumer->ref();
|
||||
if (source)
|
||||
DataTranslator::attachChain(source,consumer);
|
||||
if (consumer->ref()) {
|
||||
if (source)
|
||||
DataTranslator::attachChain(source,consumer);
|
||||
}
|
||||
else
|
||||
consumer = 0;
|
||||
}
|
||||
m_peerRecord = consumer;
|
||||
if (temp) {
|
||||
|
@ -508,9 +515,12 @@ void DataEndpoint::setCallRecord(DataConsumer* consumer)
|
|||
return;
|
||||
DataConsumer *temp = m_callRecord;
|
||||
if (consumer) {
|
||||
consumer->ref();
|
||||
if (m_source)
|
||||
DataTranslator::attachChain(m_source,consumer);
|
||||
if (consumer->ref()) {
|
||||
if (m_source)
|
||||
DataTranslator::attachChain(m_source,consumer);
|
||||
}
|
||||
else
|
||||
consumer = 0;
|
||||
}
|
||||
m_callRecord = consumer;
|
||||
if (temp) {
|
||||
|
|
|
@ -222,7 +222,13 @@ bool MutexPrivate::lock(long maxwait)
|
|||
if (rval) {
|
||||
s_locks++;
|
||||
m_locked++;
|
||||
m_owner = Thread::currentName();
|
||||
Thread* thr = Thread::current();
|
||||
if (thr) {
|
||||
thr->m_locks++;
|
||||
m_owner = thr->name();
|
||||
}
|
||||
else
|
||||
m_owner = 0;
|
||||
}
|
||||
else
|
||||
deref();
|
||||
|
@ -238,6 +244,9 @@ void MutexPrivate::unlock()
|
|||
// Hope we don't hit a bug related to the debug mutex!
|
||||
GlobalMutex::lock();
|
||||
if (m_locked) {
|
||||
Thread* thr = Thread::current();
|
||||
if (thr)
|
||||
thr->m_locks--;
|
||||
if (!--m_locked)
|
||||
m_owner = 0;
|
||||
if (--s_locks < 0)
|
||||
|
|
|
@ -58,7 +58,6 @@ public:
|
|||
bool m_updest;
|
||||
bool m_cancel;
|
||||
const char* m_name;
|
||||
private:
|
||||
#ifdef _WINDOWS
|
||||
static void startFunc(void* arg);
|
||||
#else
|
||||
|
@ -66,7 +65,6 @@ private:
|
|||
#endif
|
||||
static void cleanupFunc(void* arg);
|
||||
static void destroyFunc(void* arg);
|
||||
static void keyAllocFunc();
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -81,7 +79,18 @@ using namespace TelEngine;
|
|||
DWORD tls_index = ::TlsAlloc();
|
||||
#else
|
||||
static pthread_key_t current_key;
|
||||
static pthread_once_t current_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
class ThreadPrivateKeyAlloc
|
||||
{
|
||||
public:
|
||||
ThreadPrivateKeyAlloc()
|
||||
{
|
||||
if (::pthread_key_create(¤t_key,ThreadPrivate::destroyFunc))
|
||||
Debug(DebugFail,"Failed to create current thread key!");
|
||||
}
|
||||
};
|
||||
|
||||
static ThreadPrivateKeyAlloc keyAllocator;
|
||||
#endif
|
||||
|
||||
static TokenDict s_prio[] = {
|
||||
|
@ -247,7 +256,6 @@ void ThreadPrivate::run()
|
|||
#ifdef _WINDOWS
|
||||
::TlsSetValue(tls_index,this);
|
||||
#else
|
||||
::pthread_once(¤t_key_once,keyAllocFunc);
|
||||
::pthread_setspecific(current_key,this);
|
||||
pthread_cleanup_push(cleanupFunc,this);
|
||||
::pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
|
||||
|
@ -273,9 +281,10 @@ bool ThreadPrivate::cancel(bool hard)
|
|||
ret = false;
|
||||
if (hard) {
|
||||
#ifdef _WINDOWS
|
||||
Debug(DebugFail,"ThreadPrivate terminating win32 thread %lu [%p]",thread,this);
|
||||
Debug(DebugGoOn,"ThreadPrivate terminating win32 thread %lu [%p]",thread,this);
|
||||
ret = ::TerminateThread(reinterpret_cast<HANDLE>(thread),0) != 0;
|
||||
#else
|
||||
Debug(DebugMild,"ThreadPrivate terminating pthread %p [%p]",&thread,this);
|
||||
ret = !::pthread_cancel(thread);
|
||||
#endif
|
||||
if (ret) {
|
||||
|
@ -296,9 +305,11 @@ void ThreadPrivate::cleanup()
|
|||
if (m_thread->m_private == this) {
|
||||
m_thread->m_private = 0;
|
||||
m_thread->cleanup();
|
||||
if (m_thread->locks())
|
||||
Debug(DebugFail,"Thread '%s' destroyed with %d mutex locks [%p]",m_name,m_thread->locks(),m_thread);
|
||||
}
|
||||
else {
|
||||
Debug(DebugWarn,"ThreadPrivate::cleanup() %p '%s' mismatching %p [%p]",m_thread,m_name,m_thread->m_private,this);
|
||||
Debug(DebugFail,"ThreadPrivate::cleanup() %p '%s' mismatching %p [%p]",m_thread,m_name,m_thread->m_private,this);
|
||||
m_thread = 0;
|
||||
}
|
||||
}
|
||||
|
@ -390,15 +401,6 @@ void ThreadPrivate::cleanupFunc(void* arg)
|
|||
t->cleanup();
|
||||
}
|
||||
|
||||
void ThreadPrivate::keyAllocFunc()
|
||||
{
|
||||
#ifndef _WINDOWS
|
||||
DDebug(DebugAll,"ThreadPrivate::keyAllocFunc()");
|
||||
if (::pthread_key_create(¤t_key,destroyFunc))
|
||||
Debug(DebugGoOn,"Failed to create current thread key!");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
void ThreadPrivate::startFunc(void* arg)
|
||||
#else
|
||||
|
@ -422,7 +424,7 @@ Runnable::~Runnable()
|
|||
}
|
||||
|
||||
Thread::Thread(const char* name, Priority prio)
|
||||
: m_private(0)
|
||||
: m_private(0), m_locks(0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debugger debug("Thread::Thread","(\"%s\",%d) [%p]",name,prio,this);
|
||||
|
@ -431,7 +433,7 @@ Thread::Thread(const char* name, Priority prio)
|
|||
}
|
||||
|
||||
Thread::Thread(const char *name, const char* prio)
|
||||
: m_private(0)
|
||||
: m_private(0), m_locks(0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Debugger debug("Thread::Thread","(\"%s\",\"%s\") [%p]",name,prio,this);
|
||||
|
|
|
@ -2731,6 +2731,7 @@ public:
|
|||
class YATE_API Thread : public Runnable
|
||||
{
|
||||
friend class ThreadPrivate;
|
||||
friend class MutexPrivate;
|
||||
public:
|
||||
/**
|
||||
* Running priorities, their mapping is operating system dependent
|
||||
|
@ -2766,6 +2767,13 @@ public:
|
|||
*/
|
||||
bool running() const;
|
||||
|
||||
/**
|
||||
* Count how many Yate mutexes are kept locked by this thread
|
||||
* @return Number of Mutex locks held by this thread
|
||||
*/
|
||||
inline int locks() const
|
||||
{ return m_locks; }
|
||||
|
||||
/**
|
||||
* Get the name of this thread
|
||||
* @return The pointer that was passed in the constructor
|
||||
|
@ -2895,6 +2903,7 @@ protected:
|
|||
|
||||
private:
|
||||
ThreadPrivate* m_private;
|
||||
int m_locks;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue