Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Weird thread parameter problem

Weird thread parameter problem

Scheduled Pinned Locked Moved C / C++ / MFC
c++windows-admintestingtoolshelp
5 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Christian Skovdal Andersen
    wrote on last edited by
    #1

    I have a ATL class with one member function. If i invoke a thread from the member function passing the 'this' pointer as the CreateThread() parameter the data is invalid when the parameter is casted back inside the thread function. A test app demonstrating the problem is available on http://www.codeit.dk/christian/threadtest.zip Like this // This is my member function which // is invoked from within my vb test app STDMETHODIMP Cxx::yy() { DWORD dwID=0; // I put some data into a member variable m_dwFoo = 200873; ::CreateThread(NULL, 0, _TheThread, (LPVOID)this, 0, &dwID); return S_OK; } static DWORD WINAPI _TheThread(LPVOID lpv) { // Cast the lpv pointer back to a class instance // (the this pointer) Cxx* p = (Cxx*)lpv; // Now p->m_dwFoo is corrupted with an invalid value!! return 0; } If I invoke the thread method from within 'OnFinalConstruct()' everything is peachy. It only happens when it is invoked from within a exposed automation method. The class is declared a free-threaded in the registry. Any clues? Christian Skovdal Andersen

    F P 2 Replies Last reply
    0
    • C Christian Skovdal Andersen

      I have a ATL class with one member function. If i invoke a thread from the member function passing the 'this' pointer as the CreateThread() parameter the data is invalid when the parameter is casted back inside the thread function. A test app demonstrating the problem is available on http://www.codeit.dk/christian/threadtest.zip Like this // This is my member function which // is invoked from within my vb test app STDMETHODIMP Cxx::yy() { DWORD dwID=0; // I put some data into a member variable m_dwFoo = 200873; ::CreateThread(NULL, 0, _TheThread, (LPVOID)this, 0, &dwID); return S_OK; } static DWORD WINAPI _TheThread(LPVOID lpv) { // Cast the lpv pointer back to a class instance // (the this pointer) Cxx* p = (Cxx*)lpv; // Now p->m_dwFoo is corrupted with an invalid value!! return 0; } If I invoke the thread method from within 'OnFinalConstruct()' everything is peachy. It only happens when it is invoked from within a exposed automation method. The class is declared a free-threaded in the registry. Any clues? Christian Skovdal Andersen

      F Offline
      F Offline
      Focht
      wrote on last edited by
      #2

      Hiya, at first - Visual Basic only supports Apartment-model even if "free threaded" is preferred in registry. When you create additional threads in your COM app, care must be taken when calling any methods/events from that threads. Without looking into sample code, i would guess the apartment instance pointer, your 'this' must be wrapped/marshalled in some way when it was invoked from the STA vb app (in a free threaded app, it would be marshalled for the random RPC thread). This means the interface pointer is a temporary one (limted lifetime and scope) than the CreateInstance()/OnFinalConstruct() one. When you CreateThread(), the (worker)thread function itself is not guaranteed to execute with the supplied 'this' while the method scope isnt left. When the method scope is left with "return S_OK", the internal COM/RPC invocations are returning too, possibly destroying any temporary (interface) pointers, freeing memory etc. The case that OnFinalConstruct() works may be an exception, possibly COM-apartment issues. You may compare both 'this' pointers (from OnFinalConstruct() and method invocation). If you *really* need additional threads in your COM server, then follow the threading rules (marshal interface ptrs or synchronize via postmessage to main STA thread or use static instance 'this'). There exist some MSDN articles regarding asynchronous COM and threading. Hope this helps, A. Focht

      L 1 Reply Last reply
      0
      • F Focht

        Hiya, at first - Visual Basic only supports Apartment-model even if "free threaded" is preferred in registry. When you create additional threads in your COM app, care must be taken when calling any methods/events from that threads. Without looking into sample code, i would guess the apartment instance pointer, your 'this' must be wrapped/marshalled in some way when it was invoked from the STA vb app (in a free threaded app, it would be marshalled for the random RPC thread). This means the interface pointer is a temporary one (limted lifetime and scope) than the CreateInstance()/OnFinalConstruct() one. When you CreateThread(), the (worker)thread function itself is not guaranteed to execute with the supplied 'this' while the method scope isnt left. When the method scope is left with "return S_OK", the internal COM/RPC invocations are returning too, possibly destroying any temporary (interface) pointers, freeing memory etc. The case that OnFinalConstruct() works may be an exception, possibly COM-apartment issues. You may compare both 'this' pointers (from OnFinalConstruct() and method invocation). If you *really* need additional threads in your COM server, then follow the threading rules (marshal interface ptrs or synchronize via postmessage to main STA thread or use static instance 'this'). There exist some MSDN articles regarding asynchronous COM and threading. Hope this helps, A. Focht

        L Offline
        L Offline
        loket
        wrote on last edited by
        #3

        I think you must differntiate between interface pointers and 'this' pointers. If 'this' pointers where to be marshaled it would mean new instances of the objects had to be created. My bet for the original bug posted is that the last instance to the object is released before the thread function is trying to access the supplied this pointer parameter.

        C 1 Reply Last reply
        0
        • C Christian Skovdal Andersen

          I have a ATL class with one member function. If i invoke a thread from the member function passing the 'this' pointer as the CreateThread() parameter the data is invalid when the parameter is casted back inside the thread function. A test app demonstrating the problem is available on http://www.codeit.dk/christian/threadtest.zip Like this // This is my member function which // is invoked from within my vb test app STDMETHODIMP Cxx::yy() { DWORD dwID=0; // I put some data into a member variable m_dwFoo = 200873; ::CreateThread(NULL, 0, _TheThread, (LPVOID)this, 0, &dwID); return S_OK; } static DWORD WINAPI _TheThread(LPVOID lpv) { // Cast the lpv pointer back to a class instance // (the this pointer) Cxx* p = (Cxx*)lpv; // Now p->m_dwFoo is corrupted with an invalid value!! return 0; } If I invoke the thread method from within 'OnFinalConstruct()' everything is peachy. It only happens when it is invoked from within a exposed automation method. The class is declared a free-threaded in the registry. Any clues? Christian Skovdal Andersen

          P Offline
          P Offline
          Patrick_Kutch
          wrote on last edited by
          #4

          I have experienced similar problems due to the type casting back to your class not resulting in the correct vtable. The class I passed had multiple inheritence. In order to fix the problem, I first had to cast the LPVOID to the base class, and then once again cast that resulting pointer into the desired class. Anyhow, that is what worked for me.

          1 Reply Last reply
          0
          • L loket

            I think you must differntiate between interface pointers and 'this' pointers. If 'this' pointers where to be marshaled it would mean new instances of the objects had to be created. My bet for the original bug posted is that the last instance to the object is released before the thread function is trying to access the supplied this pointer parameter.

            C Offline
            C Offline
            Christian Skovdal Andersen
            wrote on last edited by
            #5

            You are absolutely right! I tried to change my vb variable holding the object to a global instance, and it worked like a charm! Apparently Visual Basic dereferences the interface pointer when leaving scope. Thanks for helping me out :-) Christian Skovdal Andersen

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups