Forward packets through the router without holding locks.

git-svn-id: http://yate.null.ro/svn/yate/trunk@2319 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2008-11-10 18:48:50 +00:00
parent 9c9216f9fe
commit 5be2897476
2 changed files with 71 additions and 36 deletions

View File

@ -42,7 +42,8 @@ void SS7Route::attach(SS7Layer3* network, SS7PointCode::Type type)
// No route to point code ?
if (priority == (unsigned int)-1)
return;
Lock lock(m_listMutex);
Lock lock(this);
m_changes++;
// Remove from list if already there
detach(network);
// Insert
@ -65,13 +66,14 @@ void SS7Route::attach(SS7Layer3* network, SS7PointCode::Type type)
// Remove a network from the list without deleting it
bool SS7Route::detach(SS7Layer3* network)
{
Lock lock(m_listMutex);
Lock lock(this);
ObjList* o = m_networks.skipNull();
if (!network)
return o != 0;
for (; o; o = o->skipNext()) {
L3Pointer* p = static_cast<L3Pointer*>(o->get());
if (*p && *p == network) {
m_changes++;
m_networks.remove(p,false);
break;
}
@ -83,17 +85,28 @@ bool SS7Route::detach(SS7Layer3* network)
int SS7Route::transmitMSU(const SS7Router* router, const SS7MSU& msu,
const SS7Label& label, int sls)
{
Lock lock(m_listMutex);
for (ObjList* o = m_networks.skipNull(); o; o = o->skipNext()) {
L3Pointer* p = static_cast<L3Pointer*>(o->get());
if (!*p)
continue;
DDebug(router,DebugAll,"Attempting transmitMSU on L3=%p '%s' [%p]",
(void*)(*p),(*p)->toString().c_str(),router);
int res = (*p)->transmitMSU(msu,label,sls);
if (res != -1)
return res;
}
lock();
ObjList* o;
do {
for (o = m_networks.skipNull(); o; o = o->skipNext()) {
L3Pointer* p = static_cast<L3Pointer*>(o->get());
RefPointer<SS7Layer3> l3 = static_cast<SS7Layer3*>(*p);
if (!l3)
continue;
DDebug(router,DebugAll,"Attempting transmitMSU on L3=%p '%s' [%p]",
l3.pointer(),l3->toString().c_str(),router);
int chg = m_changes;
unlock();
int res = l3->transmitMSU(msu,label,sls);
if (res != -1)
return res;
lock();
// if list has changed break with o not null so repeat the scan
if (chg != m_changes)
break;
}
} while (o);
unlock();
return -1;
}
@ -102,7 +115,7 @@ int SS7Route::transmitMSU(const SS7Router* router, const SS7MSU& msu,
* SS7Router
*/
SS7Router::SS7Router(const NamedList& params)
: Mutex(true)
: Mutex(true), m_changes(0)
{
setName("ss7router");
}
@ -129,6 +142,7 @@ void SS7Router::attach(SS7Layer3* network)
}
}
if (add) {
m_changes++;
m_layer3.append(new L3Pointer(network));
Debug(this,DebugAll,"Attached network (%p,'%s') [%p]",
network,network->toString().safe(),this);
@ -149,6 +163,7 @@ void SS7Router::detach(SS7Layer3* network)
L3Pointer* p = static_cast<L3Pointer*>(o->get());
if (*p != network)
continue;
m_changes++;
m_layer3.remove(p,false);
removeRoutes(network);
if (engine() && engine()->find(network)) {
@ -177,6 +192,7 @@ void SS7Router::attach(SS7Layer4* service)
}
}
if (add) {
m_changes++;
m_layer4.append(new L4Pointer(service));
Debug(this,DebugAll,"Attached service (%p,'%s') [%p]",
service,service->toString().safe(),this);
@ -195,6 +211,7 @@ void SS7Router::detach(SS7Layer4* service)
L4Pointer* p = static_cast<L4Pointer*>(o->get());
if (*p != service)
continue;
m_changes++;
m_layer4.remove(p,false);
const char* name = 0;
if (engine() && engine()->find(service)) {
@ -219,8 +236,9 @@ int SS7Router::transmitMSU(const SS7MSU& msu, const SS7Label& label, int sls)
{
XDebug(this,DebugStub,"Possibly incomplete SS7Router::transmitMSU(%p,%p,%d)",
&msu,&label,sls);
Lock lock(this);
SS7Route* route = findRoute(label.type(),label.dpc().pack(label.type()));
lock();
RefPointer<SS7Route> route = findRoute(label.type(),label.dpc().pack(label.type()));
unlock();
return route ? route->transmitMSU(this,msu,label,sls) : -1;
}
@ -228,17 +246,29 @@ bool SS7Router::receivedMSU(const SS7MSU& msu, const SS7Label& label, SS7Layer3*
{
XDebug(this,DebugStub,"Possibly incomplete SS7Router::receivedMSU(%p,%p,%p,%d)",
&msu,&label,network,sls);
Lock lock(this);
ObjList* l = &m_layer4;
for (; l; l = l->next()) {
L4Pointer* p = static_cast<L4Pointer*>(l->get());
if (!(p && *p))
continue;
DDebug(this,DebugAll,"Attempting receivedMSU to L4=%p '%s' [%p]",
(void*)(*p),(*p)->toString().c_str(),this);
if ((*p)->receivedMSU(msu,label,network,sls))
return true;
}
lock();
ObjList* l;
do {
for (l = &m_layer4; l; l = l->next()) {
L4Pointer* p = static_cast<L4Pointer*>(l->get());
if (!p)
continue;
RefPointer<SS7Layer4> l4 = static_cast<SS7Layer4*>(*p);
if (!l4)
continue;
DDebug(this,DebugAll,"Attempting receivedMSU to L4=%p '%s' [%p]",
l4.pointer(),l4->toString().c_str(),this);
int chg = m_changes;
unlock();
if (l4->receivedMSU(msu,label,network,sls))
return true;
lock();
// if list has changed break with l not null so repeat the scan
if (chg != m_changes)
break;
}
} while (l); // loop until the list was scanned to end
unlock();
return false;
}

View File

@ -3964,7 +3964,7 @@ protected:
m_l2userMutex.lock();
RefPointer<SS7L2User> tmp = m_l2user;
m_l2userMutex.unlock();
return tmp && tmp->receivedMSU(msu,RefPointer<SS7Layer2>(this),m_sls);
return tmp && tmp->receivedMSU(msu,this,m_sls);
}
/**
@ -3975,7 +3975,7 @@ protected:
RefPointer<SS7L2User> tmp = m_l2user;
m_l2userMutex.unlock();
if (tmp)
tmp->notify(RefPointer<SS7Layer2>(this));
tmp->notify(this);
}
private:
@ -4124,7 +4124,7 @@ protected:
m_l3userMutex.lock();
RefPointer<SS7L3User> tmp = m_l3user;
m_l3userMutex.unlock();
return tmp && tmp->receivedMSU(msu,label,RefPointer<SS7Layer3>(this),sls);
return tmp && tmp->receivedMSU(msu,label,this,sls);
}
/**
@ -4136,7 +4136,7 @@ protected:
RefPointer<SS7L3User> tmp = m_l3user;
m_l3userMutex.unlock();
if (tmp)
tmp->notify(RefPointer<SS7Layer3>(this),sls);
tmp->notify(this,sls);
}
/**
@ -4250,7 +4250,7 @@ private:
* to route to the enclosed destination point code
* @short A SS7 MSU route
*/
class YSIG_API SS7Route : public GenObject
class YSIG_API SS7Route : public RefObject, public Mutex
{
friend class SS7Layer3;
public:
@ -4260,7 +4260,8 @@ public:
* @param priority Optional value of the network priority
*/
inline SS7Route(unsigned int packed, unsigned int priority = 0)
: m_packed(packed), m_priority(priority), m_listMutex(true)
: Mutex(true),
m_packed(packed), m_priority(priority), m_changes(0)
{ m_networks.setDelete(false); }
/**
@ -4299,8 +4300,8 @@ public:
private:
unsigned int m_packed; // Packed destination point code
unsigned int m_priority; // Network priority for the given destination (used by SS7Layer3)
Mutex m_listMutex; // Lock list operations
ObjList m_networks; // List of networks used to route to the given destination (used by SS7Router)
int m_changes; // Counter used to spot changes in the list
};
/**
@ -4383,8 +4384,12 @@ protected:
*/
virtual void notify(SS7Layer3* network, int sls);
ObjList m_layer3; // List of L3 (networks) attached to this router
ObjList m_layer4; // List of L4 (services) attached to this router
/** List of L3 (networks) attached to this router */
ObjList m_layer3;
/** List of L4 (services) attached to this router */
ObjList m_layer4;
/** Counter used to spot changes in the lists of L3 or L4 */
int m_changes;
};
/**