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