I assume you have done the work to get expanded mode working properly. You need to wrap all your event handlers/callback functions in thunks. If not you will see random crashes... Palm OS makes no guarantee that the A4 register (used to hold c++ data like vtables) is restored like the A5 (Globals) register, so sometime it may work... but it is a time bomb waiting to go off.

We still use a reference count, and save it in a feature, but you could use a database or the app preferences... anything but globals :)

I believe we still work in multiple nested launches, but I also think we have re-engineered our code to avoid this complication.

If you need nested launches, then I think we had problems with the OS not setting the A4 register corretly on the innermost launches. Our solution was to save the A4 register (In another feature) from the outer most launch and restore it for second/third... launches

Here is a copy of our current startup/shutdown code.

--------------
inline void __SetA4__(UInt32 newValue)
{
        asm {   
        MOVE.L  newValue, A4                                    // set new value
        }
}

static UInt32 __GetA4__(void) = 0x200C;

///////////////////////////////////////////////////////////
/// \brief initalise all multi-segment info
///
/// set up CW expanded mode, Incriment referance count
/// set up multi-segment jump tables for non-global
/// launch codes (if ref count == 1)
///
/// \param launchFlags launch flags sent to PilotMain by
///                     the system
///
/// \sa term
///////////////////////////////////////////////////////////
void mutli_segment_object::init ( UInt16 launchFlags )
{

        UInt32 AppRefCount = GetRefCount( );
        AppRefCount++;
        SetRefCount( AppRefCount );

        // if this is the first instance
        // and we are called without globals,
        //   runtime lib will not have done loadandrelocate and we need to do so
        // only if it's not been done before
        if      ( 1 == AppRefCount )
        {
                _CW_SetupExpandedMode ( );

                SetSavedA4(__GetA4__());

                if ( !(launchFlags & sysAppLaunchFlagNewGlobals) )
                {
                        SysAppInfoType *appInfoP = NULL;
                        SysAppInfoType *rootAppInfoP = NULL;

                        appInfoP = SysGetAppInfo(&rootAppInfoP, &appInfoP);
                        
                        /* Relocate multi-segment applications */
                        MTWK::__LoadAndRelocate__(true, appInfoP->codeH);
                }
        }
        else
        {
                //We need to restore A4 without calling _CW_SetupExpandedMode()
        __SetA4__(GetSavedA4());        
        }
        
        if ( 1 == AppRefCount)
        {
                ncpl::singleton_manager::destroy();
        }
}

///////////////////////////////////////////////////////////
/// \brief cleanup all multi-segment info
///
/// Decncriment referance count, clean up up multi-segment
/// jump tables for non-global launch codes (if ref
/// count == 0)
///
/// \param launchFlags launch flags sent to PilotMain by
///                     the system
///
/// \sa init
///////////////////////////////////////////////////////////
void mutli_segment_object::term ( UInt16 launchFlags )
{
        UInt32 AppRefCount = GetRefCount( );
        AppRefCount--;
        SetRefCount( AppRefCount );

        //      if this was the first instance
        if ( 0 == AppRefCount )
        {
                ncpl::singleton_manager::do_delete();

                if ( !(launchFlags & sysAppLaunchFlagNewGlobals) )
                {
                        SysAppInfoType *appInfoP = NULL;
                        SysAppInfoType *rootAppInfoP = NULL;

                        appInfoP = SysGetAppInfo(&rootAppInfoP, &appInfoP);

                        /* Relocate multi-segment applications */
                        MTWK::__LoadAndRelocate__(false, appInfoP->codeH);
                }
        }
}

---------

Gary wrote:
Hi Neil.

I spoke to soon about this working perfectly. It seemed fine at first glance, but now it's crashing fairly regularly, but not always at the same spot. I found this post of yours from last year:

http://news.palmos.com/read/messages?id=192785

You list your PilotMain logic as the following:

1) call _CW_SetupExpandedMode ( )
2) Get Reference count for App // Should be zero if we have just been
launched
3) Inc and save Reference Count
4) If launched without globals, and ref count = 1 (i.e. this is not a
nested launch) call MTWK::__LoadAndRelocate__ to relocate extra segments
5) Do Main program logic
6) Dec and save Reference Count
7) if RefCount 0 && lunched without globals call
MTWK::__LoadAndRelocate__ again to clean up
8) exit

Is this still how you do things? If so, do you just create a ref count and store it in a db somewhere (since you don't have globals)? Did you ever figure out whether you were supposed to call _CW_SetupExpandedMode on nested launches?

Thanks again,
Gary




--
For information on using the PalmSource Developer Forums, or to unsubscribe, 
please see http://www.palmos.com/dev/support/forums/

Reply via email to