Hello OpenSG users,

I have a problem with my multithreaded application (with OpenSG 1.8). To 
illustrate what my program does I added some simplified samples of my original 
code (e.g. access to the boolean variables is done via InterlockedExchange 
calls within the original code).
The main thread pushes information (e.g. a filename) about geometry that needs 
to be loaded into the background thread. The background thread in turn will use 
this information to finally load the geometry. The synchronisation part is the 
tricky one. Pushing filenames into the background thread needs to be done in a 
thread safe manner. I do that by entering a critical section, pushing as much 
information as needed to the background thread and then leaving the critical 
section. After that the methods BackgroundThread::synch and 
BackgroundThread::applyChanges are called by the background thread and the main 
thread, respectively.

The call that entered the critical section I mentioned above also sets a flag 
mAppChangesNeeded to true. The method BackgroundThread::synch() will apply the 
changes made by the background thread to the main thread and if the 
mAppChangesNeeded flag is equal to true the bg thread will also receive changes 
made by the main thread.
However, here is where my problem occurs. Sometimes the background thread wants 
to receive changes because the mAppChangesNeeded flag is true but the main 
thread will never reach the corresponding code within 
BackgroundThread::applyChanges because it already left this method. Leading to 
a background thread captured within a call for gSyncBarrier->enter(2).

I have no idea why this can happen. Maybe some of you can see my mistake by 
looking at the code below. I hope I didn't confuse you with my explanations. 
Any hint is appreciated and if you think that there's a better of way a 
accomplishing my goal, please, let me know.

void BackgroundThread::beginAlteration()
{
        if (mAlterationActive == true) throw std::exception();

        mAlterationActive = true;

        EnterCriticalSection(&mCS);
}

void BackgroundThread::endAlteration()
{
        if (mAlterationActive == false) throw std::exception();

        mAppChangesNeeded = true;
        mAlterationActive = 0;

        LeaveCriticalSection(&mCS);
}

void BackgroundThread::applyChanges()
{
        if (mAlterationActive == true) throw std:exception();

        if (mSyncNeeded == true)
        {
                gSyncBarrier->enter(2);
                gBackgroundThread->getChangeList()->applyAndClear();
                gSyncBarrier->enter(2);

                if (mAppChangesNeeded == true)
                {
                        gSyncBarrier->enter(2);
                        gSyncBarrier->enter(2);
                }
                //else osg::Thread::getCurrentChangeList()->clearAll();
        }
}

void BackgroundThread::synch()
{
        mSyncNeeded = true;
        gSyncBarrier->enter(2);
        mSyncNeeded = false;
        gSyncBarrier->enter(2);

        if (mAppChangesNeeded == true)
        {
                gSyncBarrier->enter(2);
                // ^ this is the part the background thread sometimes
                // will be trapped in

                gApplicationThread->getChangeList()->applyAndClear();
                mAppChangesNeeded = false;
                gSyncBarrier->enter(2);
        }
}

BackgroundThread::run()
{
        for(EVER)
        {
                synch();

                EnterCriticalSection(&mCS);

                // load resources here

                LeaveCriticalSection(&mCS);
        }
}

Main::Loop()
{
        for(EVER)
        {
                BackgroundThread::getInstance()->applyChanges();

                // render stuff here

                // sometimes call:
                // beginAlteration();
                // push information to the background thread
                // endAlteration();
        }
}

BTW: I don't know if this helps but I also need to move the camera at startup 
to finally see the geometry.


Cheers
Till
-- 
GMX DSL Doppel-Flat ab 19,99 Euro/mtl.! Jetzt mit 
gratis Handy-Flat! http://portal.gmx.net/de/go/dsl

------------------------------------------------------------------------------
The modern datacenter depends on network connectivity to access resources
and provide services. The best practices for maximizing a physical server's
connectivity to a physical network are well understood - see how these
rules translate into the virtual world? 
http://p.sf.net/sfu/oracle-sfdevnlfb
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to