CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 29
  1. #1
    Join Date
    Jul 2010
    Posts
    88

    Question Enforcing single thread in MFC ActiveX using Mutex

    I have to make thread safety for my MFC ActiveX graphics engine because Windows 7 allow an application to run with a messagebox waiting for the user and even allowing the messagebox to be in the background while the user continue to use the program and make new calls to the engine. Without thread safety, the engine crashes with access violation.

    The following mutex code did absolutely nothing and I don't understand why.

    Code:
    // Declared in public class data
    HANDLE EngineMutex;
    
    // Executed in the class constructor
    EngineMutex = CreateMutex(NULL,FALSE,"EngineAccess");
    
    // Used in start and end of all interface calls
    #define START_CALL WaitForSingleObject(EngineMutex,INFINITE);
    #define END_CALL ReleaseMutex(EngineMutex);

  2. #2
    Join Date
    Jul 2010
    Posts
    88

    Re: Enforcing single thread in MFC ActiveX using Mutex

    It seems to be better to just put all error messages in a queue and wait for the calling application to read them.

  3. #3
    Join Date
    Jan 2009
    Posts
    54

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Are you protecting the right resource with your mutex?

  4. #4
    Join Date
    Jul 2010
    Posts
    88

    Re: Enforcing single thread in MFC ActiveX using Mutex

    I use the whole engine as a resource so that the caller should only be allowed to use one method at a time. My new error message system makes it safe to call from VB6 but a multicore application could still make the engine crash by having overlapping calls.

  5. #5
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Can you post the code for a few of the methods so we can see how you are protecting them?

  6. #6
    Join Date
    Jul 2010
    Posts
    88

    Re: Enforcing single thread in MFC ActiveX using Mutex

    I use the macros START_CALL and END_CALL in each area that reads or writes using the engine's shared data but the last time I tried, more than 10 threads was in the critical section at once and caused the engine to crash in 80% of the cases.
    Code:
    void CDFPGECtrl::Camera_RenderScene(int InputCamera, int OutputSurface, int ShaderChannel) {
    	START_CALL
    		GET_FROM_REF(Camera,InputCamera)
    		GET_FROM_REF(DrawSurface,OutputSurface)
    		if BAD_REF(InputCamera) {
    			REPORT_TYPE(Camera,Camera_RenderScene,InputCamera)
    		} else if BAD_REF(OutputSurface) {
    			REPORT_TYPE(DrawSurface,Camera_RenderScene,OutputSurface)
    		} else if (pOutputSurface->DepthBuffer == false) {
    			MQ->InsertMessage(L"Camera_RenderScene: The draw surface reference OutputSurface does not have a depth buffer.");
    		} else {
    			DGE->Camera_RenderScene(pInputCamera,pOutputSurface,ShaderChannel);
    		}
    	END_CALL
    }
    
    int CDFPGECtrl::Model_CreateCopy(int SourceModel) {
    	int Result;
    	START_CALL
    		GET_FROM_REF(Model,SourceModel)
    		if BAD_REF(SourceModel) {
    			REPORT_TYPE(Model,Model_CreateCopy,SourceModel)
    			Result = -1;
    		} else {
    			Result = DGE->IDFromPointer(DGE->Model_DuplicateModel(pSourceModel));
    		}
    	END_CALL
    	return Result;
    }

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enforcing single thread in MFC ActiveX using Mutex

    What is the code for START_CALL and END_CALL?

  8. #8
    Join Date
    Jul 2010
    Posts
    88

    Re: Enforcing single thread in MFC ActiveX using Mutex

    They are declared in the first post.

  9. #9
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Okay, so these locks are on a class instance level. This is fine if you are trying to prevent an instance of a class from calling more than one method in different threads.

    If you need to synchronize across multiple class instances, but the functionality into a singleton class and just forward the method calls to the singleton class.

    Something like:
    Code:
    void CDFPGECtrl::Camera_RenderScene(int InputCamera, int OutputSurface, int ShaderChannel)
    {
      // forward the call to the singleton instance
      Service::GetInstance( )->Camera_RenderScene( InputCamera, OutputSurface, ShaderChannel );
    }

  10. #10
    Join Date
    Jul 2010
    Posts
    88

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Quote Originally Posted by Arjay View Post
    If you need to synchronize across multiple class instances, but the functionality into a singleton class and just forward the method calls to the singleton class.
    I don't need synchronization between different class instances because I can run 2 instances of the engine at the same time without collisions.

  11. #11
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Quote Originally Posted by Dawoodoz View Post
    I don't need synchronization between different class instances because I can run 2 instances of the engine at the same time without collisions.
    If that is the case, then your previous statement appears to be incorrect: "I use the macros START_CALL and END_CALL in each area that reads or writes using the engine's shared data but the last time I tried, more than 10 threads was in the critical section at once and caused the engine to crash in 80% of the cases."

  12. #12
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Quote Originally Posted by Arjay View Post
    If that is the case, then your previous statement appears to be incorrect: "I use the macros START_CALL and END_CALL in each area that reads or writes using the engine's shared data but the last time I tried, more than 10 threads was in the critical section at once and caused the engine to crash in 80% of the cases."
    It appears that your engine isn't thread safe (and instances of the engine can't be called across multiple threads).

  13. #13
    Join Date
    Jul 2010
    Posts
    88

    Re: Enforcing single thread in MFC ActiveX using Mutex

    With shared data, I mean outside of the called function and not global memory.

  14. #14
    Join Date
    Jul 2010
    Posts
    88

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Quote Originally Posted by Arjay View Post
    It appears that your engine isn't thread safe (and instances of the engine can't be called across multiple threads).
    Yes, I wrote that in the first post.

  15. #15
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Enforcing single thread in MFC ActiveX using Mutex

    Quote Originally Posted by Dawoodoz View Post
    Yes, I wrote that in the first post.
    So put the engine into a singleton class and protect it as I've suggested.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured