[reSIProcate] Some recommended changes to accommodate us Mac guys

John Draper lists at webcrunchers.com
Sun Mar 26 16:16:59 CST 2006


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




More information about the resiprocate-devel mailing list