jeudi 28 février 2019

nofify_all() crashes when the program is closed

I have a very simple C++ program like below. When I close this application, it sometimes crashing while calling notify_all() on the condition variable. Can anybody give me a hint about the reason?

I have checked lots of Q/As on SO, but non of them solved my problem. I work on windows 7 and VS 2013.

    class B;

    class C
    {
    public:
        C(const std::weak_ptr<B>& b) : mB(b)
        {
        }
        virtual ~C() 
        {
        }

        void run()
        {
            while (true)
            {
                std::unique_lock<std::mutex> uLock(mMutex);

                // Wait until some event is happening
                mCondition.wait_for(uLock, std::chrono::seconds(300));

                if (!mStop)
                {
                    //do something here
                }
                else
                {
                    return;
                }
            }
        }


        void start()
        {
            mThread = std::thread(&C::run, this);
        }

        void stop()
        {
            mStop = false;
        }

        void notify()
        {
            mCondition.notify_all();
        }

        void join()
        {
            if (mThread.joinable())
            {
                mThread.join();
            }
        }

        private:
            std::atomic<bool> mStop;
            std::condition_variable mCondition;
            std::mutex mMutex;
            std::thread mThread;
            std::weak_ptr<B> mB;
        };


    class B : public std::enable_shared_from_this<B>
    {
    public:
        B() {}
        ~B()
        {
            if (mC)
            {
                mC->stop();
                mC->notify();
                mC->join();
            }
        }

        // basic methods
        void init()
        {
            mC = std::unique_ptr<C>(new C(shared_from_this()));
            mC->start();
        }

    private:
        std::unique_ptr<C> mC;
    };

    class A
    {
    public:
        ~A(){}

        void init() { pImpl->init(); }

        static std::shared_ptr<A> getInstance(){
            static std::shared_ptr<A> instance(new A);
            return instance;
        }

    private:
        A() : pImpl(std::make_shared<B>()){}
        std::shared_ptr<B> pImpl;
    };


    void main()
    {
        std::shared_ptr<A> a = A::getInstance();
        a->init();

        int x;
        std::cin >> x;
    }

Aucun commentaire:

Enregistrer un commentaire