[vtkusers] vtkSmartPointer bug hiding in about 20 lines of code here...
Mike Gagnon
mike at gagnon.com
Thu Aug 1 11:47:46 EDT 2013
Hello vtk list!
I have some code on a worker thread that sends user matrices to actors
by wrapping the data up in a
struct with a vtkSmartPointer member and some other info I need for the
UI thread to render. There's
a subtle reference count error that I'm having a tough time finding, so
I'm posting my code here hoping
someone can tell me what I'm doing wrong.
The code runs very well for 30 minutes at times, and blows up eventually
with an access violation. other times it happens much more quickly -
I'm definitely not calling delete anywhere, but somehow, on an
intermittent interval, I can see the matrix has been cleaned up and I
get an access violation when trying to use it.
The only code pertinent to all this is below and there's no other
objects that are using the matrices, other than at the end when being
rendered by vtk.
// in the worker thread:
vtkMatrix4x4 * pMatrix = vtkMatrix4x4::New();
/// set elements in matrix here...
ACTOR_MOVEMENT_MATRIX m(pMatrix, true);
// SIDE NOTE - the struct takes ownership of the vtkMatrix4x4, and
here's the constructor:
// ACTOR_MOVEMENT_MATRIX(vtkMatrix4x4 * pMatrix, bool bShouldRender) {
// m_Matrix = vtkSmartPointer<vtkMatrix4x4>::Take(pMatrix);
// m_bShouldRenderNow = bShouldRender;
//}
g_Queue.push(m); // templated queue class
// my templated queue class implements the push in a lock since the push
comes from a worker thread:
void push (T imdata) {
lock lk(monitor);
q.push(imdata);
SetEvent(m_hItemPushedEvent); // <-- so I know when to read
(pull)
}
// when the UI thread is notified, you can pull from this queue:
bool pull (T & t) {
lock lk(monitor);
if(q.size() == 0) // sanity check
return false;
t = q.front();
q.pop();
return true;
since my elements in the queue are of type ACTOR_MOVEMENT_MATRIX - they
implement operator=, like this:
ACTOR_MOVEMENT_MATRIX & operator= (const ACTOR_MOVEMENT_MATRIX & other)
{
m_Matrix = NULL; // decrement the count on any existing smart
pointer
m_Matrix = other.m_Matrix;
m_bShouldRenderNow = other.m_bShouldRenderNow;
return *this;
}
// later, in my UI thread, I wait for the event from the push, and
handle it when I get it, like this:
ACTOR_MOVEMENT_MATRIX matrix; // <-- this is before the event wait
loop, reused for each matrix,
// which is why I set m_Matrix to
NULL first in operator=()
// And to handle the matrix push event:
g_Queue.pull(matrix);
// the signal below hooks up to the document, and I send the raw
vtkMatrix4x4 pointer to it
m_SigUpdateActorUserMatrix(matrix.m_Matrix, matrix.m_bShouldRenderNow);
Note that I'm sending the vtkSmartPointer<vtkMatrix4x4>
(matrix.m_Matrix) in the above signal to the
void vtkMFCDocument::UpdateActorUserMatrix(vtkMatrix4x4 * pUserMatrix,
bool bShouldRender)
Any clue where I'm going wrong with smart pointers here??
Thanks for any help!
Mike
More information about the vtkusers
mailing list