Boost thread overrides value of member variables

109 views Asked by At

I am currently working on a project where we try to develop a video game for blind and sighted people using the Microsoft Kinect, haptic feedback devices like the PAHANTOM and stereo rendering for different 3D devices. In the current situation everything runs within a single thread and as you could imagine the application lacks performance since the haptic devices need to run their control loop with at least 1000 Hz. What I am trying to do here is to create 4 threads, one for the rendering done with Ogre3D, one for the Collision Detection, one for the haptic and the last will manage the data collected by the Kinect.

Each part has its own manager class such as KinectManager, HapticManager etc. Because we are using Ogre3D we have class called MainApplication which inherits from BaseApplication in which all necessary functions such as setup(), configure() etc. are implemented. Within the MainApplication the function createScene() is called in which the ColisionManager is created:

void MainApplication::createScene()
{
    // Initialize CollisionManager
    CollisionManager cManager;
    cManager.run();

    // Set the scene's ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));

    // Create a Light and set its position
    Ogre::Light* light = mSceneMgr->createLight("MainLight");
    light->setPosition(20.0f, 80.0f, 50.0f);

    // Haptic indicator
    Ogre::Entity* hapticJoystick = mSceneMgr->createEntity("hapticPos", "Icosphere.mesh");
    hapticNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("hapticPos");
    hapticNode->attachObject(hapticJoystick);
}

The CollisionManager.h looks like this:

#ifndef __COLLISIONMANAGER_H_
#define __COLLISIONMANAGER_H_

#include "HapticManager.h"
#include "KinectManager.h"

#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/shared_ptr.hpp>

#include <OgreManualObject.h>
#include <OgreSceneManager.h>

bool cManagerReady = false;

class CollisionManager
{
public:
    CollisionManager();
    virtual ~CollisionManager();

    void run();
    bool isBusy();

private:
    KinectManager *kManager;
    HapticManager *hManager;

    bool mBusy;
    bool mShutdown;
    boost::shared_ptr<boost::thread> mThread;
    boost::mutex mMutex;

    void work();
};

#endif // __COLLISIONMANAGER_H_

The run() function from the CollisionManager is called by the MainApplication to initialize and start the thread for the collision detection. The work() function will do all the work and needs to call non static member variables and functions.

The implementation looks like this:

#include "CollisionManager.h"

using namespace std;

CollisionManager::CollisionManager() :
    kManager ( new KinectManager ),
    hManager ( new HapticManager ),
    mShutdown ( false ),
    mBusy ( false )
{
}

CollisionManager::~CollisionManager(void)
{
}

bool CollisionManager::isBusy()
{
    return this->mBusy;
}

void CollisionManager::run()
{
    if (!this->mBusy) 
    {
        this->mBusy = true;
        this->mThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CollisionManager::work, this)));
    }
}

void CollisionManager::work()
{
    while(!mShutdown)
    {
        cout << boolalpha << mShutdown << endl;
    }
}

Currently I create the thread with a boost::shared_ptr because I was running into the problem that I could not access non static member variables. Now at least I solved this problem by using the shared_ptr. Within the work() function the thread should run as long as the mSutdown variable is set to false which is the initial value assigned in the constructor. Somehow the value of mShutdown is changed by something and cannot figure out where and what is changing the value since I am not explicitly changing it. The behaviour is that the thread stops running because the flag turns true. Does this phenomenon tend to occur when using the shared_ptr from boost?

0

There are 0 answers