title: Boost Thread inside class can't access member variables
body: <p>I have a class being instantiated dynamically ( as the pointer is passed back and forth through a C interface ) that has a member boost thread.  In a member function the following code is executed:</p>
  
  <pre><code>_thrd = boost::thread( boost::bind( &amp;cls::thrdProc, this, other vars ) );
  </code></pre>
  
  <p>I know the following:
  The thread was created
  Because the thread procedure is a non-static member function of the same class "this" is passed as the first argument.
  I've tried it with and without boost::bind.</p>
  
  <p>Also in that class is a member variable of a queue I wrote. The thread procedure creates a hidden message window, a communications library is initialized, and as data is received the library sends a Windows message to the message procedure (which is in the thread). The message procedure dispatches the message to a static window procedure which redirects it to a member function of the same class with the thread.  Messages are received and the thread procedure is entered.  The problem is inside it the queue appears to not have been initialized ( actually all member variables of the class are invalid ). Thus, since the thread procedure and the main application code use a boost::mutex to guard the queue data after a moment ( depends on the number of packets received by the communications library ) I get a runtime error on a <code>boost::lock_guard</code> ( tried <code>boost::scoped_lock</code> too ).  It's because the thread procedure calls <code>_queue.push</code> which tries to lock the mutex which is uninitialized so <code>BOOST_VERIFY</code> complains.</p>
  
  <p>I've read several questions and examples that mention the thread copies arguments but the arguments aren't the issue.  It seems like <code>this</code> is pointing to something else or wrapper class object doesn't exist.  It does though and I can confirm the original pointer is valid.</p>
  
  <p>Is there some other copy issue I'm not aware of?
  Thanks in advance!</p>
  
  <pre><code>        HEADER FILE
  
  interface language_proxy
  {
  virtual int connectToQ( int * id ) = 0;
  virtual int deconnectFromQ( int const id ) = 0;
  virtual int startDataCollection() = 0;
  virtual int stopDataCollection() = 0;
  ...
  };
  
  class CMyThread : public language_proxy
  {
  public:
      CMyThread( com lib args );
  
      int connectToQ( int * id );
      int deconnectFromQ( int const id );
      int startDataCollection();  
      int stopDataCollection();
      ...
  
  protected:
      boost::mutex        _mutex;
      CMyQueue            _queue;
      boost::thread       _thrd;
      ...
  
      uint thrdProc( com lib args );
  };
  
  
  EXECUTABLE FILE(S)
  
  int CMyThread::startDataCollection()
  {
  // guard against multiple starts
  if( boost::thread:id() == _thrd.get_id() )
      {
      _thrd = boost::thread( boost::bind( &amp;CMyThread::thrdProc, this, member vars for com lib ) );
      }
  }
  
  uint CMyThread::thrdProc( com lib args )
  {
  // create hidden messaging window
  WNDCLASSEX                  wc                  = { 0 };
  
  // many parameters can be ignored since window will be hidden
  wc.cbSize        = sizeof( WNDCLASSEX );
  wc.lpszClassName = MSG_WND_CLS;
  wc.lpfnWndProc   = &amp;CMyThread::StaticWndProc;
  wc.hInstance     = GetModuleHandle( 0 );
  
  // register the class with Windows
  RegisterClassEx( &amp;wc );
  
  // create a window based on the above class parameters
  _msg_hwnd = CreateWindowEx
                  (
                  0,
                  wc.lpszClassName,
                  L"HiddenMessageWindow",
                  0,
                  CW_USEDEFAULT,
                  CW_USEDEFAULT,
                  0,
                  0,
                  HWND_MESSAGE,
                  0,
                  0,
                  this
                  );
  
  // initialize com lib
  
  // process windows messages
  while( true )
      {
      // process available messages
      if( PeekMessage( &amp;msg, _msg_hwnd, 0, 0, PM_REMOVE ) )
          {
          // break out of the loop if the quit message is found
          if( WM_QUIT == msg.message )
              {
              printf( "Quit message found\n" );
              break;
              }
  
          TranslateMessage( &amp;msg );
          DispatchMessage( &amp;msg );
          }
  
      else
          {
          // throws boost::thread_interrupted if the thread has been interrupted
          boost::this_thread::sleep_for( boost::chrono::milliseconds( _msg_loop_dly ) );
          }
      }
  
  UnregisterClass( MSG_WND_CLS, GetModuleHandle( 0 ) );
  }
  
  LRESULT CALLBACK CMyThread::StaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  {
  CMyThread *         pWnd                = 0;
  
  try
  {
  // store class pointer for window being created
  if( WM_NCCREATE == uMsg )
      {
      // use SetWindowLongPtr to be 64-bit compatible ( a class pointer will be 64 bits and a long is only 32 bits )
      pWnd = ( CMyThread * )( ( LPCREATESTRUCT )lParam )-&gt;lpCreateParams;
      SetWindowLongPtr( hWnd, GWLP_USERDATA, *reinterpret_cast&lt; LONG_PTR * &gt;( pWnd ) );
      }
  
  // access the class pointer
  else
      {
      pWnd = ( CMyThread * )GetWindowLong( hWnd, GWL_USERDATA );
      }
  
  // if a class pointer for the window exists, call its procedure
  if( pWnd )
      {
      return( pWnd-&gt;WndProc( hWnd, uMsg, wParam, lParam ) );
      }
  }
  
  catch( ... )
  {
  int x = 5;
  }
  
  // call the default window procedure
  return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
  }
  
  LRESULT CALLBACK CMyThread::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  {
  switch( uMsg )
      {
      // when a request to close the window is received, destroy the window
      case WM_CLOSE:
          {
          DestroyWindow( hWnd );
          } break;
  
      // when a window is destroyed put a quit message in the queue to stop message processing
      case WM_DESTROY:
          {
          PostQuitMessage( 0 );
          } break;
  
      // handle messages from com library
      case UWM_RX_COM_LIB_MSG:
          {
          // use GetWindowLongPtr to be 64-bit compatible ( a class pointer will be 64 bits and a long is only 32 bits )
          LONG_PTR            lPtr                = GetWindowLongPtr( hWnd, GWLP_USERDATA );
          CMyThread *         pWnd                = reinterpret_cast&lt; CMyThread * &gt;( &amp;lPtr );
          pWnd-&gt;onRx();
          } break;
  
      // handle all other cases by default behaviour
      default:
          {
          return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
          }
      }
  
  return( 0 );
  }
  
  void CMyThread::onRx()
  {
  // extract packet(s) from com library
  // add packet(s) to vector
  
  // THIS QUEUE IS UNINITIALIZED!
  _queue.push( pkts );
  }
  
  int C_Interface_create
      (
      com lib arguments,
      language_proxy **   p
      )
  {
  // instantiate the C++ object through the C interface
  language_proxy *        tmp_p       = new CMyThread( com lib args );
  
  if( tmp_p )
      {
      *p = tmp_p;
      }
  
      return( 0 );
  }
  
  int C_Interface_start_thread( language_proxy * p )
  {
  p-&gt;startDataCollection();
      return( 0 );
  }
  
  
  // actually in a DLL but so you have some idea of what the operation flow is
  void main()
  {
  static language_proxy *     s_proxy = 0;
  
  C_Interface_create( 1, 2, 3, &amp;s_proxy );
  c_Interface_start_thread( s_proxy );
  
  // for debugging, endless loop to allow rx'd packets to be processed and guarantee
  // s_proxy is still alive
  while( 1 );
  }
  </code></pre>