1

As title says I'm having this problem when I can't understand why this thread

enter image description here

never stops running even after Client's destructor destroys asio::io_service::work variable

enter image description here

When I'm running this program output is always like this

enter image description here

Anyone sees what I'm missing here?

#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>

using namespace boost;


class Client{
public:

    Client(const Client& other) = delete;

    Client()
    {
        m_work.reset(new boost::asio::io_service::work(m_ios));

        m_thread.reset(new std::thread([this]()
        {
            m_ios.run();
        }));
    }

    ~Client(){ close(); }

private:

    void close();

    asio::io_service m_ios;
    std::unique_ptr<boost::asio::io_service::work> m_work;
    std::unique_ptr<std::thread> m_thread;

};

void Client::close()
{
    m_work.reset(nullptr);

    if(m_thread->joinable())
    {
        std::cout << "before joining thread" << std::endl;
        m_thread->join();
        std::cout << "after joining thread" << std::endl;
    }
}



int main()
{
    {
         Client client;
    }

    return 0;
}

EDIT


After StPiere comments I changed code to this and it worked :)

class Client{
public:

    Client(const Client& other) = delete;

    Client()
    {
        m_work.reset(new boost::asio::executor_work_guard<boost::asio::io_context::executor_type>(boost::asio::make_work_guard(m_ios)));
        m_thread.reset(new std::thread([this]()
        {
            m_ios.run();
        }));
    }

    ~Client(){ close(); }

private:

    void close();

    asio::io_context m_ios;

    std::unique_ptr<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> m_work;
    std::unique_ptr<std::thread> m_thread;

};
etrusks
  • 165
  • 1
  • 8
  • which compiler/os/boost version ? on vc2019 , boost 1.75 it works fine. – StPiere Jan 18 '21 at 10:17
  • @StPiere I'm using TDM-GCC 9.2.0 compiler and 1.75 boost version. Also using it in CodeBlocks if it makes any difference – etrusks Jan 18 '21 at 10:46
  • io_service is basically deprecated and should be replaced with io_context. Can you try and check if you get the same issue by using io_context instead of io_service ? – StPiere Jan 18 '21 at 10:49
  • Ohh thanks man. I didnt know it was changed. I'm using 1 cookbook to make this example so I'll change it and will let u know – etrusks Jan 18 '21 at 10:50
  • and if it still doesnt work, you can try replacing io_context::work with io_context::executor_work_guard, because io_context::work is also deprecated. see boost docs. – StPiere Jan 18 '21 at 10:53
  • @StPiere Thanks. Changing jsut io_service to context didnt help. But it will take some time for me to test that work_guard coz I have no idea how to use it right now – etrusks Jan 18 '21 at 10:59
  • @StPiere Bro I just found example with work guard and it worked. :) Thank you so much bro. You should write it as answer – etrusks Jan 18 '21 at 11:07
  • glad that could help. – StPiere Jan 18 '21 at 11:15
  • 1
    No doubt you have other async operations pending on the service. No need to use unique_ptr with either the thread nor the executor_work_guard (the latter has a `.reset()` member of its own). Sometimes when heisenbugs like this appear there is a hidden cause (like you're not debugging an up-to-date build for some reason) – sehe Jan 18 '21 at 16:38
  • @sehe Ohh im new to this `executor_work_guard `. I will keep this in mind and update my code. I have to research a bit what has changed in boost::asio. Thanks man :) – etrusks Jan 18 '21 at 23:02

1 Answers1

2

I cannot reproduce the error on either compiler. Here example for gcc 9.3 and boost 1.73

Normally the work destructor will use something like InterLockedDecrement on windows to decrement the number of outstanding works.

It looks like some compiler or io_service/work implementation issue.

As stated in comments, io_service and io_service::work are deprecated in terms of io_context and executor_work_guard.

StPiere
  • 4,113
  • 15
  • 24