CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Nov 2010
    Posts
    54

    Can two functions in same DLL be called by two threads?

    I write a DLL MyDLL.dll with Visual C++ 2008, as follows:

    (1) MFC static linked
    (2) Using multi-thread runtime library.

    In the DLL, this is a global data m_Data shared by two export functions, as follows:

    ULONGLONG WINAPI MyFun1(LPVOID *lpCallbackFun1)
    {
    ...
    Write m_Data(using Critical section to protect)


    return xxx;
    }

    ULONGLONG WINAPI MyFun2(LPVOID *lpCallbackFun2)
    {
    ...
    Suspend MyThread1 to prevent conflict.
    Read m_Data(using Critical section to protect)
    Resume MyThread1.


    return xxx;
    }

    In in my main application, it will first call LoadLibrary to load MyDLL.dll, then get the address of MyFun1 and MyFun2, then do the following thing:

    (1) Start a new thread MyThread1, which will invoke MyFun1 to do a time-consuming task.
    (2) Start a new thread MyThread2, which will invoke MyFun2 for several times, as follows:

    for (nIndex = 0; nIndex = 20; nIndex)
    {
    nResult2 = MyFun2(lpCallbackFun2);
    NextStatement2;
    }

    Although MyThread1 and MyThread2 using critical section to protect the shared data m_Data, I will still suspend MyThread1 before accessing the shared data, to prevent any possible conflicts.

    The problem is:

    (1) When the first invoke of MyFun2, everything is OK, and the return value of MyFun2(that is nResult2) is 1 , which is expected.
    (2) When the second, third and fourth invoke of MyFun2, the operations in MyFun2 are executed successfully, but the return value of MyFun2(that is nResult2) is a random value instead of the expected value 1. I try to using Debug to trace into MyFun2, and confirm that the last return statement is just return a value of 1, but the invoker will receive a random value instead of 1 when inspecting nResult2.
    (3) After the fourth invoke of MyFun2 and return back to the next statement follow MyFun2, I will always get a “buffer overrun detected” error, whatever the next statement is.

    I think this looks like a stack corruption, so try to make some tests:

    1. I confirm the /GS (Stack security check) feature in the compiler is ON.
    2. If MyFun2 is invoked after MyFun1 in MyThread1 is completed, then everything will be OK.
    3. In debug mode, the codeline in MyFun2 that reads the shared data m_Data will not cause any errors or exceptions. Neither will the codeline in MyFun1 that writes the shared Data.

    So, how to solve this problem

    Thank you!

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Can two functions in same DLL be called by two threads?

    Quote Originally Posted by AlanCCC View Post
    Suspend MyThread1 to prevent conflict.
    How are you suspending the thread? If you're using SuspendThread, that shouldn't be used for synchronization.

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    Regards,

    Paul McKenzie

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

    Re: Can two functions in same DLL be called by two threads?

    If you are using a critical section [properly] to protect the shared data, there is no reason to have to suspend the thread.

    If the return value is some sort of global variable (and isn't protected by the critical section), you will need to synchronize access to it.

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Can two functions in same DLL be called by two threads?

    Quote Originally Posted by AlanCCC View Post
    The problem is:

    (1) When the first invoke of MyFun2, everything is OK, and the return value of MyFun2(that is nResult2) is 1 , which is expected.
    (2) When the second, third and fourth invoke of MyFun2, the operations in MyFun2 are executed successfully, but the return value of MyFun2(that is nResult2) is a random value instead of the expected value 1. I try to using Debug to trace into MyFun2, and confirm that the last return statement is just return a value of 1, but the invoker will receive a random value instead of 1 when inspecting nResult2.
    (3) After the fourth invoke of MyFun2 and return back to the next statement follow MyFun2, I will always get a “buffer overrun detected” error, whatever the next statement is.
    It seems your buffer appears overrun at the moment you start getting random return values, so your problem hardly has anything to do with threading or DLL. It's most probably either true corruption of local thread stack or wild pointer dereference.
    Best regards,
    Igor

  5. #5
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Can two functions in same DLL be called by two threads?

    suspending a thread is a bad idea, especially if you try to do it as a means of getting or avoiding synchronisation.

    The simple case failure scenario...
    * Thread 1 is busy doing some stuff and has left internal data structures in an incomplete/half finished state.
    * Thread 2 suspends thread 1
    * Thread 2 uses the internal data structures which aren't complete. This is the failure point. "anything could happen" when thread 2 uses the incomplete data. It might even seem thread 2 is working 'ok'.
    * Thread 2 resumes thread
    * Thread 1 may now have to deal with other stuff Thread2 has done to the incomplete data and causing thread 1 to behave unexpectedly. This could end up being hard to track down since you'll be assuming there's a bug in this code, when the real culprit is in the other thread.

    If you ARE using proper synchronisation, then suspending a thread may cause a deadlock.
    Even if you guard against that, it may have other issues such as severe performance degradation.

    Avoid thread suspension, there are a few edge cases where you need it, but for the most part, it is probably a sign of a serious design flaw.

Tags for this Thread

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