r3260 - in trunk/libmsip: include/libmsip source
svn at minisip.org
svn at minisip.org
Wed May 9 13:58:25 CEST 2007
Author: erik
Date: 2007-04-26 17:05:16 +0200 (Thu, 26 Apr 2007)
New Revision: 3260
Modified:
trunk/libmsip/include/libmsip/SipLayerDialog.h
trunk/libmsip/include/libmsip/SipSMCommand.h
trunk/libmsip/source/SipCommandDispatcher.cxx
trunk/libmsip/source/SipLayerDialog.cxx
trunk/libmsip/source/SipSMCommand.cxx
Log:
* libmsip: Bug fix+optimization: SipLayerDialog stored the transactions in a "minilist" (linked
list).
-> Terminated calls are now removed at the correct time. Before if
there were multiple terminated dialogs in the "termwait" state
waiting for transactions to terminate, all of them would be
removed once one of them had no more transactions. This was
only visible in debug output, and we have no functionality
that was affected by it.
-> removing a dialog was O(n^2), and now it's O(log n), n=number
of dialogs in the stack.
-> routing a command to a dialog was O(n), and now it's O(log n).
For commands that are sent without destination id, it's still
O(n) (for example "proxy_register"). It's only the registration
dialog that accepts commands without callId. For scalability
purposes, it should not be implemented that way.
-> when doing debug output of the stack ("+"), then the dialogs
are ordered by callId. They were ordered by when they were created
which was probably a bit better.
Modified: trunk/libmsip/include/libmsip/SipLayerDialog.h
===================================================================
--- trunk/libmsip/include/libmsip/SipLayerDialog.h 2007-04-26 11:54:16 UTC (rev 3259)
+++ trunk/libmsip/include/libmsip/SipLayerDialog.h 2007-04-26 15:05:16 UTC (rev 3260)
@@ -32,7 +32,7 @@
#include<list>
#include<libmutil/Mutex.h>
#include<libmutil/MemObject.h>
-#include<libmutil/minilist.h>
+#include<map>
class SipDialog;
class SipCommandDispatcher;
@@ -49,7 +49,7 @@
MRef<SipDefaultHandler*> getDefaultDialogCommandHandler();
void addDialog(MRef<SipDialog*> d);
- void removeTerminatedDialogs();
+ bool removeDialog(std::string callId);
virtual std::string getMemObjectType() const {return "SipLayerDialog";}
@@ -60,7 +60,7 @@
private:
MRef<SipDefaultHandler*> defaultHandler;
- minilist<MRef<SipDialog*> > dialogs;
+ std::map<std::string, MRef<SipDialog*> > dialogs;
MRef<SipCommandDispatcher*> dispatcher;
Modified: trunk/libmsip/include/libmsip/SipSMCommand.h
===================================================================
--- trunk/libmsip/include/libmsip/SipSMCommand.h 2007-04-26 11:54:16 UTC (rev 3259)
+++ trunk/libmsip/include/libmsip/SipSMCommand.h 2007-04-26 15:05:16 UTC (rev 3260)
@@ -73,9 +73,19 @@
int getSource() const;
void setSource(int s);
+ /**
+ * This is one of transport_layer, dialog_layer,
+ * transaction_layer or dispatcher
+ */
int getDestination() const;
void setDestination(int s);
+ /**
+ * The destiationId of a SIP message is the callId. The
+ * destinationId is CommandString::getDestinationId().
+ */
+ std::string getDestinationId() const;
+
MRef<SipMessage*> getCommandPacket() const;
CommandString getCommandString() const;
#ifdef _WIN32_WCE
Modified: trunk/libmsip/source/SipCommandDispatcher.cxx
===================================================================
--- trunk/libmsip/source/SipCommandDispatcher.cxx 2007-04-26 11:54:16 UTC (rev 3259)
+++ trunk/libmsip/source/SipCommandDispatcher.cxx 2007-04-26 15:05:16 UTC (rev 3260)
@@ -317,9 +317,7 @@
return true;
}else if (c.getCommandString().getOp()==SipCommandString::call_terminated){
- dialogLayer->removeTerminatedDialogs();
- return true;
-
+ return dialogLayer->removeDialog(c.getDestinationId());
}else if ( c.getCommandString().getOp() == SipCommandString::sip_stack_shutdown ||
c.getCommandString().getOp() == SipCommandString::register_all_identities ||
c.getCommandString().getOp() == SipCommandString::register_all_identities_done ||
Modified: trunk/libmsip/source/SipLayerDialog.cxx
===================================================================
--- trunk/libmsip/source/SipLayerDialog.cxx 2007-04-26 11:54:16 UTC (rev 3259)
+++ trunk/libmsip/source/SipLayerDialog.cxx 2007-04-26 15:05:16 UTC (rev 3260)
@@ -39,40 +39,37 @@
}
SipLayerDialog::~SipLayerDialog(){
- list<MRef<SipDialog*> > l;
+ std::map<std::string, MRef<SipDialog*> >::iterator i;
dialogListLock.lock();
- for (int i=0; i< dialogs.size(); i++)
- dialogs[i]->freeStateMachine();;
+ for (i=dialogs.begin(); i!= dialogs.end(); i++)
+ (*i).second->freeStateMachine();
dialogListLock.unlock();
-
}
list<MRef<SipDialog*> > SipLayerDialog::getDialogs() {
list<MRef<SipDialog*> > l;
+ std::map<std::string, MRef<SipDialog*> >::iterator i;
dialogListLock.lock();
- for (int i=0; i< dialogs.size(); i++)
- l.push_back(dialogs[i]);
+ for (i=dialogs.begin(); i!=dialogs.end(); i++)
+ l.push_back( (*i).second );
dialogListLock.unlock();
return l;
}
-
-void SipLayerDialog::removeTerminatedDialogs(){
-
- for (int i=0; i< dialogs.size(); i++){
- if ( dialogs[i]->dialogState.isTerminated || dialogs[i]->getCurrentStateName()=="terminated"){
- MRef<SipDialog *> dlg = dialogs[i];
- dialogs.remove(i);
- //merr << "CESC: SipMsgDispatcher::hdleCmd : breaking the dialog vicious circle" << endl;
- dlg->freeStateMachine();
- i=0;
- }
+bool SipLayerDialog::removeDialog(string callId){
+ size_t n = dialogs.erase(callId);
+#ifdef DEBUG_OUTPUT
+ if (n!=1){
+ merr << "WARNING: dialogs.erase should return 1, but returned "<< n<<endl;
}
+#endif
+ return n==1;
}
void SipLayerDialog::addDialog(MRef<SipDialog*> d){
+ massert(d->dialogState.callId!="");
dialogListLock.lock();
- dialogs.push_front(d);
+ dialogs[d->dialogState.callId] = d;
dialogListLock.unlock();
}
@@ -90,34 +87,44 @@
#ifdef DEBUG_OUTPUT
mdbg<< "SipLayerDialog: got command: "<< c <<end;
#endif
+ cerr << "EEEE: command: "<< c << endl;
- dialogListLock.lock();
- // 2. If not any branch parameter or the transaction was not found, try with each dialog
- //int j=0; //unused??
- MRef<SipDialog *> dialog;
- int i;
+ string cid = c.getDestinationId();
+
try{
- for (i=0; i<dialogs.size(); i++){
- dialog = dialogs[i];
+ MRef<SipDialog *> dialog;
+ if (cid.size()>0){
+ dialogListLock.lock();
+ dialog = dialogs[cid];
dialogListLock.unlock();
+ if ( dialog && dialog->handleCommand(c) )
+ return true;
+ }else{
- if ( dialog->handleCommand(c) ){
- //dialogListLock.unlock();
- return true;
+ std::map<std::string, MRef<SipDialog*> >::iterator i;
+ dialogListLock.lock();
+ for (i=dialogs.begin(); i!=dialogs.end(); i++){
+ dialog = (*i).second;
+ dialogListLock.unlock();
+
+ if ( dialog->handleCommand(c) ){
+ return true;
+ }
+ dialogListLock.lock();
}
- dialogListLock.lock();
+ dialogListLock.unlock();
}
- }catch(exception &e){
- cerr << "SipLayerDialog: caught exception i="<< i<<" what: "<< e.what() << endl;
- }
- dialogListLock.unlock();
+ if (defaultHandler){
+ //cerr << "SipLayerDialog: No dialog handled the message - sending to default handler"<<endl;
+ return defaultHandler->handleCommand(c);
+ }else{
+ cerr << "ERROR: libmsip: SipLayerDialog::handleCommand: No default handler for dialog commands set!"<<endl;
+ return false;
+ }
- if (defaultHandler){
- //cerr << "SipLayerDialog: No dialog handled the message - sending to default handler"<<endl;
- return defaultHandler->handleCommand(c);
- }else{
- cerr << "ERROR: libmsip: SipLayerDialog::handleCommand: No default handler for dialog commands set!"<<endl;
+ }catch(exception &e){
+ cerr << "SipLayerDialog: caught exception: "<< e.what() << endl;
return false;
}
}
Modified: trunk/libmsip/source/SipSMCommand.cxx
===================================================================
--- trunk/libmsip/source/SipSMCommand.cxx 2007-04-26 11:54:16 UTC (rev 3259)
+++ trunk/libmsip/source/SipSMCommand.cxx 2007-04-26 15:05:16 UTC (rev 3260)
@@ -73,6 +73,13 @@
destination=i;
}
+string SipSMCommand::getDestinationId() const{
+ if (type==SipSMCommand::COMMAND_PACKET)
+ return cmdpkt->getCallId();
+ else
+ return cmdstr.getDestinationId();
+}
+
int SipSMCommand::getSource() const{
return source;
}
More information about the Minisip-devel
mailing list