I think I have a problem in my program. I must create an object that continuosly communicate with an external tracking system and get coordinates of point from it. I wrapped this class inside a boost::thread and before the first calls to my Glut Application I create the thread object and I detach it
The code for the salient methods of the class is the following
boost::mutex resourceMutex;
void Tracker::init()
{
boost::mutex::scoped_lock lock(resourceMutex);
try
{
// some initializations
}
catch (std::bad_alloc const&)
{
cerr << "Memory allocation fail during init!" << endl;
}
try
{
p3dData = (Position3d*)calloc( NUM_MARKERS , sizeof( Position3d ) );
if ( p3dData==NULL )
throw std::bad_alloc();
}
catch ( std::bad_alloc const&)
{
cerr << "Memory allocation fail during memory allocation!" << endl;
}
}
void Tracker::update()
{
boost::mutex::scoped_lock lock(optotrakResourceMutex);
//... operations on vector< Eigen::Vector3d > points
}
vector<Eigen::Vector3d> &Tracker::getAllPoints()
{
return points;
}
My glutTimerFunc makes a call to an update function that every frame picks the points with the method getAllPoints, while the tracker thread continuosly update them (in fact the frequencies of access to data are different, the thread calls to is faster than the glut update functions calls.
Now when the program exit, I first delete the Tracker object allocated with new then interrupt the thread containing it, but sometimes I get strange behaviours I think they are memory leak
Is the way of getting data with different frequencies of access and the use of scoped_lock correct or should I put some guard in the getAllPoints method?
I understand your dedicated tracker thread continuously calls
Tracker::update()
to acquire the localization data from your device (NDI Optotrak?)Then, your OpenGL application accesses the latest points at regular interval from the main thread using
Tracker::getAllPoints()
.In this case, the vector of 3D points
Tracker::points
is a shared resource between these two threads.To prevent concurrent access, both the writing operation in
update()
and the reading withgetAllPoints()
must be protected by the mutex, not only the writing as in your current code. The reading code in the main thread must also lock the mutex:Caveat: If your operations on points in the
timerFunc()
are slow, then the mutex will remain locked for a long time and your tracker thread will block on it when callingTracker::update()
.A better design would be to change
Tracker::getAllPoints()
to return a copy of the 3D points vector instead of a reference:Note how the mutex is encapsulated in the
Tracker
class and how thetimerFunc()
does not need to worry about it.Also note how the mutex is locked only during the copy. The copy of a list of 3D vectors is certainly going to be faster than mathematical operations on them.