r3132 - in trunk/libmsip: include/libmsip source
erik at minisip.org
erik at minisip.org
Sat Jan 20 17:41:03 CET 2007
Author: erik
Date: 2007-01-20 17:41:03 +0100 (Sat, 20 Jan 2007)
New Revision: 3132
Modified:
trunk/libmsip/include/libmsip/SipCommandDispatcher.h
trunk/libmsip/include/libmsip/SipCommandString.h
trunk/libmsip/include/libmsip/SipLayerTransport.h
trunk/libmsip/include/libmsip/SipStackInternal.h
trunk/libmsip/source/SipCommandDispatcher.cxx
trunk/libmsip/source/SipCommandString.cxx
trunk/libmsip/source/SipLayerTransport.cxx
trunk/libmsip/source/SipSocketServer.cxx
trunk/libmsip/source/SipStack.cxx
trunk/libmsip/source/SipStackInternal.cxx
Log:
* Fix memory leak in SipStack (loops prevented objects from being freed when
deleteing a SipStack)
- Stop threads
- Break reference loops
Modified: trunk/libmsip/include/libmsip/SipCommandDispatcher.h
===================================================================
--- trunk/libmsip/include/libmsip/SipCommandDispatcher.h 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/include/libmsip/SipCommandDispatcher.h 2007-01-20 16:41:03 UTC (rev 3132)
@@ -65,6 +65,8 @@
public:
SipCommandDispatcher(MRef<SipStackInternal*> stack, MRef<SipLayerTransport*> transport);
+ void free();
+
void setCallback(MRef<CommandReceiver*> cb);
MRef<CommandReceiver*> getCallback();
Modified: trunk/libmsip/include/libmsip/SipCommandString.h
===================================================================
--- trunk/libmsip/include/libmsip/SipCommandString.h 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/include/libmsip/SipCommandString.h 2007-01-20 16:41:03 UTC (rev 3132)
@@ -41,6 +41,7 @@
*/
static const std::string sip_stack_shutdown;
static const std::string sip_stack_shutdown_done;
+ static const std::string no_op;
static const std::string register_all_identities;
static const std::string register_all_identities_done;
static const std::string unregister_all_identities;
Modified: trunk/libmsip/include/libmsip/SipLayerTransport.h
===================================================================
--- trunk/libmsip/include/libmsip/SipLayerTransport.h 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/include/libmsip/SipLayerTransport.h 2007-01-20 16:41:03 UTC (rev 3132)
@@ -32,7 +32,6 @@
#include<libmnetutil/DatagramSocket.h>
#include<libmnetutil/StreamSocket.h>
#include<libmutil/Mutex.h>
-#include<libmutil/Thread.h>
#include<libmutil/Semaphore.h>
#include<libmutil/MemObject.h>
#include<libmcrypto/cert.h>
@@ -46,6 +45,7 @@
class SipLayerTransport;
class SipCommandDispatcher;
+class StreamThreadData;
class SipLayerTransport : public SipSMCommandReceiver {
public:
@@ -117,6 +117,7 @@
Mutex serversLock;
std::list<MRef<SipSocketServer *> > servers;
+ std::list<MRef<StreamThreadData *> > workers;
Mutex socksLock;
std::list<MRef<StreamSocket *> > socks;
Modified: trunk/libmsip/include/libmsip/SipStackInternal.h
===================================================================
--- trunk/libmsip/include/libmsip/SipStackInternal.h 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/include/libmsip/SipStackInternal.h 2007-01-20 16:41:03 UTC (rev 3132)
@@ -94,6 +94,8 @@
void startTcpServer();
void startTlsServer();
+ void free();
+
private:
// std::string getDialogDebugString(MRef<SipDialog*> d, list<MRef<SipTransaction*> > &trans,
Modified: trunk/libmsip/source/SipCommandDispatcher.cxx
===================================================================
--- trunk/libmsip/source/SipCommandDispatcher.cxx 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/source/SipCommandDispatcher.cxx 2007-01-20 16:41:03 UTC (rev 3132)
@@ -50,6 +50,16 @@
}
+void SipCommandDispatcher::free(){
+ sipStackInternal=NULL;
+ callback=NULL;
+ managementHandler=NULL;
+ transportLayer->setDispatcher(NULL);
+ transportLayer=NULL;
+ dialogLayer=NULL;
+ transactionLayer=NULL;
+}
+
void SipCommandDispatcher::setDialogManagement(MRef<SipDialog*> mgmt){
managementHandler = mgmt;
}
@@ -63,6 +73,17 @@
void SipCommandDispatcher::stopRunning(){
keepRunning=false;
+
+ transportLayer->stop();
+
+ //The SIP stack is blocking on a semaphore waiting for
+ //something to process. We wake it by sending it a
+ //no-operation command. It will then check
+ //the "keepRunning" flag and exit
+ CommandString c("",SipCommandString::no_op);
+ SipSMCommand sc(c, SipSMCommand::dispatcher, SipSMCommand::dispatcher);
+ enqueueCommand(sc, LOW_PRIO_QUEUE);
+
}
list<MRef<SipDialog *> > SipCommandDispatcher::getDialogs(){
@@ -120,7 +141,7 @@
#endif
if (item.type == TYPE_COMMAND){
-
+
handled=handleCommand(**(item.command));
}else{ // item.type == TYPE_TIMEOUT
@@ -278,6 +299,9 @@
bool SipCommandDispatcher::maintainenceHandleCommand(const SipSMCommand &c){
if (c.getType()==SipSMCommand::COMMAND_STRING){
+ if (c.getCommandString().getOp()==SipCommandString::no_op){
+ return true;
+ }
if (c.getCommandString().getOp()==SipCommandString::transaction_terminated){
transactionLayer->removeTerminatedTransactions();
Modified: trunk/libmsip/source/SipCommandString.cxx
===================================================================
--- trunk/libmsip/source/SipCommandString.cxx 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/source/SipCommandString.cxx 2007-01-20 16:41:03 UTC (rev 3132)
@@ -28,6 +28,7 @@
const string SipCommandString::sip_stack_shutdown="sip_stack_shutdown";
const string SipCommandString::sip_stack_shutdown_done="sip_stack_shutdown_done";
+const string SipCommandString::no_op="no_op";
const string SipCommandString::register_all_identities="register_all_identities";
const string SipCommandString::register_all_identities_done="register_all_identities_done";
const string SipCommandString::unregister_all_identities="unregister_all_identities";
Modified: trunk/libmsip/source/SipLayerTransport.cxx
===================================================================
--- trunk/libmsip/source/SipLayerTransport.cxx 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/source/SipLayerTransport.cxx 2007-01-20 16:41:03 UTC (rev 3132)
@@ -269,20 +269,46 @@
return 0;
}
-class StreamThreadData{
+class StreamThreadData : public MObject{
public:
StreamThreadData( MRef<SipLayerTransport *> );
+ void run();
+ void stop();
+ void join();
+ void streamSocketRead( MRef<StreamSocket *> socket );
+ private:
SipMessageParser parser;
MRef<SipLayerTransport *> transport;
- void run();
- void streamSocketRead( MRef<StreamSocket *> socket );
+ bool doStop;
+ ThreadHandle th;
};
+static void * streamThread( void * arg ){
+ StreamThreadData * data;
+ data = (StreamThreadData *)arg;
+
+ // We want to keep a reference to the object so that it
+ // exist (at least) until we exit this function.
+ MRef<StreamThreadData *> ref=data;
+
+ ref->run();
+ return NULL;
+}
+
StreamThreadData::StreamThreadData( MRef<SipLayerTransport *> transport){
+ doStop=false;
this->transport = transport;
+ cerr << "Creating thread"<<endl;
+ th=Thread::createThread(streamThread, this);
+ cerr << "threadhandle is as long int: "<<th.asLongInt()<<endl;
}
+void StreamThreadData::join(){
+ cerr << "threadhandle is as long int: "<<th.asLongInt()<<endl;
+ Thread::join(th);
+}
+
bool sipdebug_print_packets=false;
void set_debug_print_packets(bool f){
@@ -333,7 +359,8 @@
int i;
for( i=0; i < NB_THREADS ; i++ ){
- Thread::createThread(streamThread, new StreamThreadData(this));
+ StreamThreadData *worker = new StreamThreadData(this);
+ workers.push_back(worker);
}
}
@@ -361,13 +388,36 @@
void SipLayerTransport::stop(){
serversLock.lock();
+ list<MRef<StreamThreadData*> >::iterator j;
+
+
+ for( j=workers.begin(); j != workers.end(); j++ ){
+ MRef<StreamThreadData*> w = *j;
+ w->stop();
+ }
+
list<MRef<SipSocketServer *> >::iterator i;
-
for( i=servers.begin(); i != servers.end(); i++ ){
MRef<SipSocketServer *> server = *i;
server->stop();
+ *i=NULL;
}
+
+ //wake up blocking threads
+ int n;
+ for (n=0; n< NB_THREADS; n++){
+ semaphore.inc();
+ }
+
+ for( j=workers.begin(); j != workers.end(); j++ ){
+ MRef<StreamThreadData*> w = *j;
+ w->join();
+ *j=NULL;
+ }
+
+ workers.clear();
+ servers.clear();
serversLock.unlock();
}
@@ -1067,25 +1117,38 @@
} // if event
}
+void StreamThreadData::stop(){
+ doStop=true;
+ transport=NULL;
+}
+
void StreamThreadData::run(){
- while(true){
+ while(!doStop){
MRef<StreamSocket *> socket;
- transport->semaphore.dec();
+
+ //Keep a local reference of transport so that
+ //it is not deleted until we are done with it.
+ MRef<SipLayerTransport*> transp = transport;
+ if (!transp)
+ break;
+ transp->semaphore.dec();
+ if (doStop)
+ break;
/* Take the last socket pending to be read */
- transport->socksPendingLock.lock();
- socket = transport->socksPending.front();
- transport->socksPending.pop_front();
- transport->socksPendingLock.unlock();
+ transp->socksPendingLock.lock();
+ socket = transp->socksPending.front();
+ transp->socksPending.pop_front();
+ transp->socksPendingLock.unlock();
/* Read from it until it gets closed */
streamSocketRead( socket );
/* The socket was closed */
- transport->socksLock.lock();
- transport->socks.remove( socket );
- transport->socksLock.unlock();
+ transp->socksLock.lock();
+ transp->socks.remove( socket );
+ transp->socksLock.unlock();
#ifdef DEBUG_OUTPUT
mdbg << "StreamSocket closed" << end;
#endif
@@ -1104,7 +1167,7 @@
int avail;
MRef<SipMessage*> pack;
- while( true ){
+ while( !doStop){
fd_set set;
do{
@@ -1203,11 +1266,5 @@
}// while true
}
-static void * streamThread( void * arg ){
- StreamThreadData * data;
- data = (StreamThreadData *)arg;
- data->run();
- return NULL;
-}
Modified: trunk/libmsip/source/SipSocketServer.cxx
===================================================================
--- trunk/libmsip/source/SipSocketServer.cxx 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/source/SipSocketServer.cxx 2007-01-20 16:41:03 UTC (rev 3132)
@@ -37,6 +37,7 @@
// SipSocketServer
//
+
SipSocketServer::SipSocketServer(MRef<SipLayerTransport*> r, MRef<Socket*> sock): ssock(sock), receiver(r),doStop(false){
externalPort = ssock->getPort();
}
Modified: trunk/libmsip/source/SipStack.cxx
===================================================================
--- trunk/libmsip/source/SipStack.cxx 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/source/SipStack.cxx 2007-01-20 16:41:03 UTC (rev 3132)
@@ -79,6 +79,9 @@
SipStack::~SipStack(){
MRef<SipStackInternal*> * mrefPtr = (MRef<SipStackInternal*> *) sipStackInternal;
+
+ (*mrefPtr)->free();
+
delete mrefPtr;
}
Modified: trunk/libmsip/source/SipStackInternal.cxx
===================================================================
--- trunk/libmsip/source/SipStackInternal.cxx 2007-01-19 20:54:43 UTC (rev 3131)
+++ trunk/libmsip/source/SipStackInternal.cxx 2007-01-20 16:41:03 UTC (rev 3132)
@@ -150,6 +150,15 @@
return dispatcher;
}
+void SipStackInternal::free(){
+ setCallback(NULL);
+ setConfCallback(NULL);
+ dispatcher->free();
+ dispatcher=NULL;
+ timeoutProvider->stopThread();
+ timeoutProvider=NULL;
+}
+
MRef<SipStackConfig*> SipStackInternal::getStackConfig(){
return config;
}
More information about the Minisip-devel
mailing list