< Previous by Date Date Index Next by Date >
  Thread Index Next in Thread >

[reSIProcate] Some recommended changes to accommodate us Mac guys


Hi,

NON Mac people - you can ignore this..

In the cleaning up phase of my Apple SIP Phone,  I'm getting hundreds of
these messages...

2006-03-25 15:52:33.340 newSipTestApp[1760] *** _NSAutoreleaseNoPool(): Object 0xb722e10 of class NSConcreteData autoreleased with no pool in place - just leaking 2006-03-25 15:52:33.341 newSipTestApp[1760] *** _NSAutoreleaseNoPool(): Object 0x8224c00 of class NSConcreteData autoreleased with no pool in place - just leaking 2006-03-25 15:52:33.341 newSipTestApp[1760] *** _NSAutoreleaseNoPool(): Object 0xb722d20 of class NSConcreteMutableData autoreleased with no pool in place - just leaking 2006-03-25 15:52:33.341 newSipTestApp[1760] *** _NSAutoreleaseNoPool(): Object 0xb722c60 of class NSIdEnumerator autoreleased with no pool in place - just leaking

The reason for this is the fact that any external threads when combined with Cocoa programs on the Mac, have to have the following code changes... in order to eliminate a lot of Mac related leaking problems. Since my callbacks are being made from a thread,
any Cocoa allocations I make will now be released properly.

I propose the following changes.  Should not affect the other parts of the
SIP stack...

<------  in SipStack.cxx ------>
#ifdef MAC <--- Or whatever constant you want to use.
#import <Cocoa/Cocoa.h>
#endif
#include "resiprocate/StackThread.hxx"
#include "resiprocate/SipStack.hxx"
#include "resiprocate/SipMessage.hxx"
#include "resiprocate/os/Logger.hxx"

void
StackThread::thread()
{
#ifdef MAC
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
#endif
  while (!isShutdown())
  {
     try
     {
        resip::FdSet fdset;
        buildFdSet(fdset);
        mStack.buildFdSet(fdset);
int ret = fdset.selectMilliSeconds(resipMin(mStack.getTimeTillNextProcessMS(), getTimeTillNextProcessMS()));
        if (ret >= 0)
        {
// .dlb. use return value to peak at the message to see if it is a
           // shutdown, and call shutdown if it is
           mStack.process(fdset);
        }
     }
     catch (BaseException& e)
     {
        InfoLog (<< "Unhandled exception: " << e);
     }
  }
  WarningLog (<< "Shutting down stack thread");
#ifdef MAC
  [pool release];
#endif
}

Be sure to set the file type to:   sourcecode.cpp.objcpp
for both DumStack.cxx,  and SipStack.cxx.  So the compiler
will understand the Objective C code.

I built my resipStack as a static library and seperate target
from within X-Code.

Do the same for DumStack.cxx

Now, any time you allocate Cocoa objects (which most will want to do), they
will be "autoreleased" properly.

Of course you are going to have to also add this to your "awakeFromNIB"
method...
   [NSThread detachNewThreadSelector:@selector(dummy:)
                            toTarget:nil
                          withObject:nil];

This essentially creates a NSThread. You have to have at least one in order to switch the Application to a "multiThreaded" mode. This is essentially a silly dummy thread that does nothing. Now, for every POSIX thread you create, you'll have to wrap this around your thread code.

   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   [pool release];

Of course you'll need this...

// ----------------------------------------------------------------
// Dummy thread - used tp go into multi-theaded mode
// ----------------------------------------------------------------
- (void)dummy:(id)arg
{
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   [pool release];
}

I put this code in my main "Controller.m" module.

Any comments?

I suppose I could have subclassed the DumThread and StackThread
and that would have worked also.

John