[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