0

I have a shared dll library that contains a class as below :

inside A.dll >> Header File :

class API ErrorHandler  
{
public:
    ErrorHandler();

    virtual ~ErrorHandler();
protected:  
    static ErrorHandler* defaultHandler();

private:
    static ErrorHandler* _pHandler;
    static std::mutex     _mutex;
};

source(.cpp)

ErrorHandler* ErrorHandler::_pHandler = ErrorHandler::defaultHandler();
std::mutex ErrorHandler::_mutex;


ErrorHandler::ErrorHandler()
{
}


ErrorHandler::~ErrorHandler()
{
}

ErrorHandler* ErrorHandler::defaultHandler()
{   
    static SingletonHolder<ErrorHandler> sh;
    return sh.get(); **<<====== here we get hanged** see the declaration of get
}

SingletoneHolder header file

template <class S>
class SingletonHolder
{
public:
    SingletonHolder():
        _pS(0)
    {
    }

    ~SingletonHolder()
    {
        delete _pS;
    }

    S* get()
    {
        std::lock_guard<std::mutex> lock(_m); <===== cause thread hang
        if (!_pS) _pS = new S;

        return _pS;
    }

private:
    S* _pS;
    std::mutex _m;
};

After building the above code (every thing related to compiler setting configured correctly) now I want to use it in my console app.

After running console app, app hangs and never reach to main function.

Why std::lock_guard<std::mutex> lock(_m); hangs and prevent main thread to continue executing?

What is alternative?

I am using VS2013 Update5.

content of main file :

#include "ErrorHandler" <== when remove this include app run correctly
#include <iostream>

int main()
{
   getchar();
   return 0;
}
amir110
  • 33
  • 6
  • Works fine for me on VS 2013 Update 5 with an empty `main`. You should post the contents of the console app, maybe you are invoking some of the exported class members. – Rudolfs Bundulis Jul 29 '16 at 13:24
  • Possible duplicate of [C++11 std::mutex in Visual Studio 2012 deadlock when locked from DllMain()](http://stackoverflow.com/questions/14711263/c11-stdmutex-in-visual-studio-2012-deadlock-when-locked-from-dllmain) – Rudolfs Bundulis Jul 29 '16 at 13:29
  • Two mutex objects, I smell a rat. Post the call stack of the deadlocked thread. – Hans Passant Jul 29 '16 at 13:34
  • @Rudolfs Bundulis : DllMain is generated by default. i never use it – amir110 Jul 29 '16 at 14:06
  • @amir110 I know that it is generated by default. Nevertheless that is where the initialization of static objects take place. – Rudolfs Bundulis Jul 29 '16 at 14:07
  • here : ErrorHandler* ErrorHandler::_pHandler = ErrorHandler::defaultHandler(); – amir110 Jul 31 '16 at 06:11

1 Answers1

1

First, you should post exact contents of the main - with an empty main everything works. Things go south when the ErrorHandler class is being instantiated inside main.

Second, the initialization of your static members occurs inside __DllMainCRTStartup and as stated in the SO question I marked as duplicate, MSDN states that using synchronization primitives from __DllMainCRTStartup can cause a deadlock. A possible solution is to switch to a critical secion.

Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71
  • first of all , my main function is emty and i only include the ErrorHandler class header file.(when i remove EventHandler header file from include list every thing works fine and i can get break inside main function). i implement the mutext class using Critical_Section and now every thing works fine – amir110 Jul 29 '16 at 13:52
  • @amir110 sorry if my wording was incorrect - I mean you must have instantiated the `ErrorHandler` instance somewhere, ok maybe not inside `main` but somewhere, otherwise if you did no have any calls to the dll it would not even be loaded. – Rudolfs Bundulis Jul 29 '16 at 14:08
  • as ErrorHandler class variable declared as static (if you check the code above) it is instantiated when app become live. – amir110 Jul 31 '16 at 06:11