Added names to the Mutex class to ease debugging of deadlocks.
git-svn-id: http://yate.null.ro/svn/yate/trunk@2611 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
edfe266f4d
commit
85da36395b
|
@ -62,11 +62,11 @@ bool TelEngine::isE164(const char* str)
|
|||
}
|
||||
|
||||
static unsigned int s_callid = 0;
|
||||
static Mutex s_callidMutex;
|
||||
static Mutex s_callidMutex(false,"CallID");
|
||||
|
||||
// this is to protect against two threads trying to (dis)connect a pair
|
||||
// of call endpoints at the same time
|
||||
static Mutex s_mutex(true);
|
||||
static Mutex s_mutex(true,"CallEndpoint");
|
||||
|
||||
CallEndpoint::CallEndpoint(const char* id)
|
||||
: m_peer(0), m_id(id), m_mutex(0)
|
||||
|
@ -851,7 +851,7 @@ const char* Module::messageName(int id)
|
|||
}
|
||||
|
||||
Module::Module(const char* name, const char* type, bool earlyInit)
|
||||
: Plugin(name,earlyInit), Mutex(true),
|
||||
: Plugin(name,earlyInit), Mutex(true,"Module"),
|
||||
m_init(false), m_relays(0), m_name(name), m_type(type), m_changed(0)
|
||||
{
|
||||
debugName(m_name);
|
||||
|
|
|
@ -148,9 +148,9 @@ static String s_rejectReason = "Rejected";
|
|||
static String s_hangupReason = "User hangup";
|
||||
static String s_cancelReason = "Cancelled";
|
||||
static unsigned int s_eventLen = 0; // Log maximum lines (0: unlimited)
|
||||
static Mutex s_debugMutex;
|
||||
static Mutex s_proxyMutex;
|
||||
static Mutex s_postponeMutex;
|
||||
static Mutex s_debugMutex(false,"ClientDebug");
|
||||
static Mutex s_proxyMutex(false,"ClientProxy");
|
||||
static Mutex s_postponeMutex(false,"ClientPostpone");
|
||||
static ObjList s_postponed;
|
||||
static NamedList* s_debugLog = 0;
|
||||
static ClientThreadProxy* s_proxy = 0;
|
||||
|
@ -186,7 +186,7 @@ String ClientDriver::s_confName = "conf/client"; // The name of the client's con
|
|||
bool ClientDriver::s_dropConfPeer = true; // Drop a channel's old peer when terminated while in conference
|
||||
String ClientDriver::s_device; // Currently used audio device
|
||||
ObjList ClientSound::s_sounds; // ClientSound's list
|
||||
Mutex ClientSound::s_soundsMutex(true); // ClientSound's list lock mutex
|
||||
Mutex ClientSound::s_soundsMutex(true,"ClientSound"); // ClientSound's list lock mutex
|
||||
String ClientSound::s_calltoPrefix = "wave/play/"; // Client sound target prefix
|
||||
|
||||
// Client relays
|
||||
|
@ -3243,7 +3243,7 @@ ClientChannel* ClientDriver::findChanByPeer(const String& peer)
|
|||
// Constructor
|
||||
ClientAccount::ClientAccount(const char* proto, const char* user,
|
||||
const char* host, bool startup)
|
||||
: Mutex(true),
|
||||
: Mutex(true,"ClientAccount"),
|
||||
m_port(0), m_startup(startup), m_expires(-1), m_connected(false),
|
||||
m_resource(0)
|
||||
{
|
||||
|
@ -3254,7 +3254,7 @@ ClientAccount::ClientAccount(const char* proto, const char* user,
|
|||
|
||||
// Constructor. Build an account from a list of parameters.
|
||||
ClientAccount::ClientAccount(const NamedList& params)
|
||||
: Mutex(true),
|
||||
: Mutex(true,"ClientAccount"),
|
||||
m_port(0), m_startup(false), m_expires(-1), m_connected(false),
|
||||
m_resource(0)
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ static unsigned int s_maxCallHistory = 20;
|
|||
|
||||
ObjList ClientLogic::s_accOptions;
|
||||
ObjList ClientLogic::s_protocols;
|
||||
Mutex ClientLogic::s_protocolsMutex(true);
|
||||
Mutex ClientLogic::s_protocolsMutex(true,"ClientProtocols");
|
||||
// Parameters that are applied from provider template
|
||||
const char* ClientLogic::s_provParams[] = {
|
||||
"server",
|
||||
|
@ -177,7 +177,7 @@ inline void activatePageCalls(ClientLogic* logic, Window* wnd = 0)
|
|||
*/
|
||||
// Constructor
|
||||
ClientLogic::ClientLogic(const char* name, int priority)
|
||||
: m_durationMutex(true), m_name(name), m_prio(priority)
|
||||
: m_durationMutex(true,"ClientLogic::duration"), m_name(name), m_prio(priority)
|
||||
{
|
||||
Debug(ClientDriver::self(),DebugAll,"ClientLogic(%s) [%p]",m_name.c_str(),this);
|
||||
Client::addLogic(this);
|
||||
|
|
|
@ -109,7 +109,7 @@ static TranslatorCaps s_stereoCaps[] = {
|
|||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static Mutex s_dataMutex(true);
|
||||
static Mutex s_dataMutex(true,"DataEndpoint");
|
||||
|
||||
class ThreadedSourcePrivate : public Thread
|
||||
{
|
||||
|
@ -1079,7 +1079,7 @@ bool DataTranslator::synchronize(DataSource* source)
|
|||
return true;
|
||||
}
|
||||
|
||||
Mutex DataTranslator::s_mutex(true);
|
||||
Mutex DataTranslator::s_mutex(true,"DataTranslator");
|
||||
ObjList DataTranslator::s_factories;
|
||||
unsigned int DataTranslator::s_maxChain = 3;
|
||||
static ObjList s_compose;
|
||||
|
|
|
@ -270,7 +270,8 @@ bool MessageRelay::receivedInternal(Message& msg)
|
|||
|
||||
|
||||
MessageDispatcher::MessageDispatcher()
|
||||
: m_changes(0), m_warnTime(0)
|
||||
: Mutex(false,"MessageDispatcher"),
|
||||
m_changes(0), m_warnTime(0)
|
||||
{
|
||||
XDebug(DebugInfo,"MessageDispatcher::MessageDispatcher() [%p]",this);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace TelEngine {
|
|||
|
||||
class MutexPrivate {
|
||||
public:
|
||||
MutexPrivate(bool recursive);
|
||||
MutexPrivate(bool recursive, const char* name);
|
||||
~MutexPrivate();
|
||||
inline void ref()
|
||||
{ ++m_refcount; }
|
||||
|
@ -57,6 +57,8 @@ public:
|
|||
{ if (!--m_refcount) delete this; }
|
||||
inline bool recursive() const
|
||||
{ return m_recursive; }
|
||||
inline const char* name() const
|
||||
{ return m_name; }
|
||||
bool locked() const
|
||||
{ return (m_locked > 0); }
|
||||
bool lock(long maxwait);
|
||||
|
@ -68,6 +70,7 @@ private:
|
|||
int m_refcount;
|
||||
volatile unsigned int m_locked;
|
||||
bool m_recursive;
|
||||
const char* m_name;
|
||||
const char* m_owner;
|
||||
};
|
||||
|
||||
|
@ -140,8 +143,9 @@ void GlobalMutex::unlock()
|
|||
}
|
||||
|
||||
|
||||
MutexPrivate::MutexPrivate(bool recursive)
|
||||
: m_refcount(1), m_locked(0), m_recursive(recursive), m_owner(0)
|
||||
MutexPrivate::MutexPrivate(bool recursive, const char* name)
|
||||
: m_refcount(1), m_locked(0), m_recursive(recursive),
|
||||
m_name(name), m_owner(0)
|
||||
{
|
||||
GlobalMutex::lock();
|
||||
s_count++;
|
||||
|
@ -185,11 +189,11 @@ MutexPrivate::~MutexPrivate()
|
|||
#endif
|
||||
GlobalMutex::unlock();
|
||||
if (m_locked)
|
||||
Debug(DebugFail,"MutexPrivate owned by '%s' destroyed with %u locks [%p]",
|
||||
m_owner,m_locked,this);
|
||||
Debug(DebugFail,"MutexPrivate '%s' owned by '%s' destroyed with %u locks [%p]",
|
||||
m_name,m_owner,m_locked,this);
|
||||
else if (warn)
|
||||
Debug(DebugGoOn,"MutexPrivate owned by '%s' unlocked in destructor [%p]",
|
||||
m_owner,this);
|
||||
Debug(DebugGoOn,"MutexPrivate '%s' owned by '%s' unlocked in destructor [%p]",
|
||||
m_name,m_owner,this);
|
||||
}
|
||||
|
||||
bool MutexPrivate::lock(long maxwait)
|
||||
|
@ -253,8 +257,8 @@ bool MutexPrivate::lock(long maxwait)
|
|||
deref();
|
||||
GlobalMutex::unlock();
|
||||
if (warn && !rval)
|
||||
Debug(DebugFail,"Thread '%s' could not take lock owned by '%s' for %lu usec!",
|
||||
Thread::currentName(),m_owner,maxwait);
|
||||
Debug(DebugFail,"Thread '%s' could not lock mutex '%s' owned by '%s' for %lu usec!",
|
||||
Thread::currentName(),m_name,m_owner,maxwait);
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -269,8 +273,8 @@ void MutexPrivate::unlock()
|
|||
if (!--m_locked) {
|
||||
const char* tname = thr ? thr->name() : 0;
|
||||
if (tname != m_owner)
|
||||
Debug(DebugFail,"MutexPrivate unlocked by '%s' but owned by '%s' [%p]",
|
||||
tname,m_owner,this);
|
||||
Debug(DebugFail,"MutexPrivate '%s' unlocked by '%s' but owned by '%s' [%p]",
|
||||
m_name,tname,m_owner,this);
|
||||
m_owner = 0;
|
||||
}
|
||||
int locks = --s_locks;
|
||||
|
@ -288,21 +292,17 @@ void MutexPrivate::unlock()
|
|||
deref();
|
||||
}
|
||||
else
|
||||
Debug(DebugFail,"MutexPrivate::unlock called on unlocked mutex [%p]",this);
|
||||
Debug(DebugFail,"MutexPrivate::unlock called on unlocked '%s' [%p]",m_name,this);
|
||||
GlobalMutex::unlock();
|
||||
}
|
||||
|
||||
|
||||
Mutex::Mutex()
|
||||
Mutex::Mutex(bool recursive, const char* name)
|
||||
: m_private(0)
|
||||
{
|
||||
m_private = new MutexPrivate(false);
|
||||
}
|
||||
|
||||
Mutex::Mutex(bool recursive)
|
||||
: m_private(0)
|
||||
{
|
||||
m_private = new MutexPrivate(recursive);
|
||||
if (!name)
|
||||
name = "?";
|
||||
m_private = new MutexPrivate(recursive,name);
|
||||
}
|
||||
|
||||
Mutex::Mutex(const Mutex &original)
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
using namespace TelEngine;
|
||||
|
||||
static Mutex s_mutex;
|
||||
static Mutex s_mutex(false,"Socket");
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
|
|
@ -47,7 +47,7 @@ void srandom(unsigned int seed)
|
|||
|
||||
int _gmtime_s(struct tm* _tm, const time_t* time)
|
||||
{
|
||||
static TelEngine::Mutex m;
|
||||
static TelEngine::Mutex m(false,"_gmtime_s");
|
||||
struct tm* tmp;
|
||||
if (!_tm)
|
||||
return EINVAL;
|
||||
|
@ -142,8 +142,8 @@ static void dbg_colorize_func(const char* buf, int level)
|
|||
static void (*s_output)(const char*,int) = dbg_stderr_func;
|
||||
static void (*s_intout)(const char*,int) = 0;
|
||||
|
||||
static Mutex out_mux;
|
||||
static Mutex ind_mux;
|
||||
static Mutex out_mux(false,"DebugOutput");
|
||||
static Mutex ind_mux(false,"DebugIndent");
|
||||
static Thread* s_thr = 0;
|
||||
|
||||
static bool reentered()
|
||||
|
@ -610,7 +610,7 @@ void GenObject::destruct()
|
|||
}
|
||||
|
||||
|
||||
static Mutex s_refmutex;
|
||||
static Mutex s_refmutex(false,"RefObject");
|
||||
|
||||
RefObject::~RefObject()
|
||||
{
|
||||
|
|
|
@ -117,7 +117,7 @@ static TokenDict s_prio[] = {
|
|||
};
|
||||
|
||||
static ObjList s_threads;
|
||||
static Mutex s_tmutex(true);
|
||||
static Mutex s_tmutex(true,"Thread");
|
||||
|
||||
ThreadPrivate* ThreadPrivate::create(Thread* t,const char* name,Thread::Priority prio)
|
||||
{
|
||||
|
|
|
@ -2840,7 +2840,7 @@ public:
|
|||
* @param name List's name used for debug purposes
|
||||
*/
|
||||
inline ClientAccountList(const char* name)
|
||||
: String(name), Mutex(true)
|
||||
: String(name), Mutex(true,"ClientAccountList")
|
||||
{}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3544,17 +3544,13 @@ class YATE_API Mutex
|
|||
{
|
||||
friend class MutexPrivate;
|
||||
public:
|
||||
/**
|
||||
* Construct a new unlocked fast mutex
|
||||
*/
|
||||
Mutex();
|
||||
|
||||
/**
|
||||
* Construct a new unlocked mutex
|
||||
* @param recursive True if the mutex has to be recursive (reentrant),
|
||||
* false for a normal fast mutex
|
||||
* @param name Static name of the mutex (for debugging purpose only)
|
||||
*/
|
||||
Mutex(bool recursive);
|
||||
Mutex(bool recursive = false, const char* name = 0);
|
||||
|
||||
/**
|
||||
* Copy constructor creates a shared mutex
|
||||
|
|
Loading…
Reference in New Issue