Added option to start new calls in a PWlib thread as the Gatekeeper client

crashes otherwise.


git-svn-id: http://yate.null.ro/svn/yate/trunk@1139 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2006-12-19 13:43:38 +00:00
parent 5fb3458b30
commit 7b8d5db7fb
2 changed files with 54 additions and 8 deletions

View File

@ -23,7 +23,7 @@
;build=0
; status: keyword: Code status: alpha, beta or release
;status=alpha
;status=release
; needmedia: bool: Drop calls for which no common media could be negotiated
;needmedia=yes
@ -52,6 +52,9 @@
; maxcleaning: int: default: 100
;maxcleaning=100
; pwlibthread: bool: Make new calls in a PWlib thread, required for LRQ calls
;pwlibthread=no
[codecs]
; This section allows to individually enable or disable the codecs

View File

@ -88,6 +88,7 @@ namespace { // anonymous
static bool s_externalRtp;
static bool s_fallbackRtp;
static bool s_passtrough;
static bool s_pwlibThread;
static int s_maxCleaning = 0;
static Configuration s_cfg;
@ -223,7 +224,7 @@ class H323Process : public PProcess
s_cfg.getValue("general","product","YATE"),
(unsigned short)s_cfg.getIntValue("general","major",YATE_MAJOR),
(unsigned short)s_cfg.getIntValue("general","minor",YATE_MINOR),
(PProcess::CodeStatus)s_cfg.getIntValue("general","status",dict_str2code,PProcess::AlphaCode),
(PProcess::CodeStatus)s_cfg.getIntValue("general","status",dict_str2code,PProcess::ReleaseCode),
(unsigned short)s_cfg.getIntValue("general","build",YATE_BUILD)
)
{ Resume(); }
@ -489,6 +490,22 @@ protected:
PString m_name;
};
class YateCallThread : public PThread
{
PCLASSINFO(YateCallThread, PThread);
public:
YateCallThread(YateH323EndPoint* ep, const char* remoteParty, void* userData, int& status)
: PThread(10000), m_ep(ep), m_userData(userData), m_remoteParty(remoteParty), m_status(status)
{ }
virtual void Main();
static bool makeCall(YateH323EndPoint* ep, const char* remoteParty, void* userData, bool newThread = false);
protected:
YateH323EndPoint* m_ep;
void* m_userData;
PString m_remoteParty;
int& m_status;
};
class UserHandler : public MessageHandler
{
public:
@ -926,6 +943,36 @@ void YateH323EndPoint::checkGkClient()
}
// make a call either normally or in a proxy PWlib thread
bool YateCallThread::makeCall(YateH323EndPoint* ep, const char* remoteParty, void* userData, bool newThread)
{
if (!newThread) {
PString token;
return ep->MakeCallLocked(remoteParty,token,userData) != 0;
}
int status = 0;
YateCallThread* call = new YateCallThread(ep,remoteParty,userData,status);
call->SetAutoDelete();
call->Resume();
while (!status)
Thread::yield();
return status > 0;
}
// the actual method that does the job in the proxy thread
void YateCallThread::Main()
{
PString token;
YateH323Connection* conn = static_cast<YateH323Connection*>(m_ep->MakeCallLocked(m_remoteParty,token,m_userData));
if (conn) {
conn->Unlock();
m_status = 1;
}
else
m_status = -1;
}
YateH323Connection::YateH323Connection(YateH323EndPoint& endpoint,
H323Transport* transport, unsigned callReference, void* userdata)
: H323Connection(endpoint,callReference), m_chan(0), m_mutex(0),
@ -2218,15 +2265,10 @@ bool H323Driver::msgExecute(Message& msg, String& dest)
}
Debug(this,DebugInfo,"Found call to H.323 target='%s'",
dest.c_str());
PString p;
YateH323EndPoint* ep = hplugin.findEndpoint(msg.getValue("line"));
if (ep) {
YateH323Connection* conn = static_cast<YateH323Connection*>(
ep->MakeCallLocked(dest.c_str(),p,&msg));
if (conn) {
conn->Unlock();
if (YateCallThread::makeCall(ep,dest.c_str(),&msg,msg.getBoolValue("pwlibthread",s_pwlibThread)))
return true;
}
// the only reason a YateH323Connection is not created is congestion
msg.setParam("error","congestion");
return false;
@ -2262,6 +2304,7 @@ void H323Driver::initialize()
// mantain compatibility with old config files
s_passtrough = s_cfg.getBoolValue("general","passtrough_rtp",s_passtrough);
s_maxCleaning = s_cfg.getIntValue("general","maxcleaning",100);
s_pwlibThread = s_cfg.getBoolValue("general","pwlibthread");
maxRoute(s_cfg.getIntValue("incoming","maxqueue",5));
maxChans(s_cfg.getIntValue("ep","maxconns",0));
if (!s_process) {