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