I created a static map that holds several Sessions of connected clients.
std::map<std::string, std::shared_ptr<Session>> Communication::m_appSockets;
The Listener that accepts incomming clients is implemented in the Communication class.
class Communication : public std::enable_shared_from_this<Communication>
{
private:
boost::asio::io_context m_ioc;
boost::asio::io_context::work m_work;
boost::asio::streambuf m_buffer;
boost::asio::ip::tcp::acceptor m_acceptor;
std::thread m_senderThread;
std::thread m_ioThread;
public:
static std::map<std::string, std::shared_ptr<Session>> m_appSockets;
Communication(uint16_t t_port);
void accept();
void doAccept();
void senderThread();
};
After accepting a client the method "doAccept" creates a session object and moves the socket like this
m_acceptor.async_accept(
[this](boost::system::error_code t_ec, boost::asio::ip::tcp::socket t_socket) {
if (!t_ec)
{
m_appSockets.emplace(std::pair<std::string, std::shared_ptr<Session>>(
"app0", std::make_shared<Session>(std::move(t_socket))));
m_appSockets["app0"]->start();
}
accept();
});
Session.h looks like this:
class Session : public std::enable_shared_from_this<Session>
{
private:
boost::asio::ip::tcp::socket m_socket;
boost::asio::streambuf m_buffer;
public:
Session(boost::asio::ip::tcp::socket t_socket);
void write(std::string &t_msg);
void doWrite(std::string &t_msg);
void start();
...
};
void start() is used for starting the async read on the socket, which is working fine. A session object is created this way:
Session::Session(boost::asio::ip::tcp::socket t_socket) : m_socket(std::move(t_socket))
{}
What I need to do for my implementation is to access the write-method of session through the shared_ptr in the map of Communication.h. I tried it the following way
void Communication::senderThread()
{
for (;;)
{
....
//blocking until queue holds a message
std::string buf = *message from queue*//pseudo code
m_appSockets["app0"].get()->write(buf);
}
}
A senderthread blocks until a message is available in a queue which will be forwarded to the write method of session
The write-method can be called but as soon as i try an operation on any member of the session it gives me a segmentation fault:
void Session::write(std::string &t_msg)
{
//here it crashes
m_socket.get_executor().context().post(std::bind(&Session::doWrite, shared_from_this(), t_msg));
}
void Session::doWrite(std::string &t_msg)
{
boost::asio::async_write(
m_socket, boost::asio::buffer(t_msg),
std::bind(&Session::onWrite, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
It feels like the Session object runs out of scope as soon as I enter its method. I have tried creating dummy members in Session which all gave the same segmentation fault when accessing them. Am I getting the shared_ptr/object lifetime wrong at some point?
Thank you very much in advance.
EDIT 1: Running gdb ./programm.out core gave me this:
Thread 2 "programm.out" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7ffff58f1700 (LWP 5651)] 0x0000555555605932 in Session::write (this=0x0, t_msg="{\"destination\":\"app0\"}") at /usr/Sources/Session.cpp:58 58 std::cout << dummyMember << std::endl;
I added a member to Session (int dummyMember{5};).
How can it be that this is pointing to 0x0?