Я создал статическую карту, которая содержит несколько сеансов подключенных клиентов.
std::map<std::string, std::shared_ptr<Session>> Communication::m_appSockets;
Слушатель, который принимает входящие клиенты, реализован в классе Communication.
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();
};
После принятияклиент метод "doAccept" создает объект сеанса и перемещает сокет следующим образом
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 выглядит так:
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 () используется для запускаasync читает на сокете, который работает нормальноОбъект сеанса создается следующим образом:
Session::Session(boost::asio::ip::tcp::socket t_socket) : m_socket(std::move(t_socket))
{}
Что мне нужно сделать для моей реализации, так это получить доступ к методу записи сеанса через shared_ptr в карте Communication.h.Я попытался сделать это следующим образом:
void Communication::senderThread()
{
for (;;)
{
....
//blocking until queue holds a message
std::string buf = *message from queue*//pseudo code
m_appSockets["app0"].get()->write(buf);
}
}
Отправитель блокирует поток, пока в очереди не появится сообщение, которое будет перенаправлено в метод записи сеанса
Метод записи можно вызвать, нокак только я пытаюсь выполнить операцию с любым членом сеанса, возникает ошибка сегментации:
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));
}
Такое ощущение, что объект Session выходит из области видимости, как только я вхожу в его метод.Я попытался создать фиктивные члены в сеансе, которые при доступе к ним давали одинаковую ошибку сегментацииЯ неправильно получаю время жизни shared_ptr / object?
Заранее большое спасибо.
EDIT 1: Запуск ядра gdb ./programm.out дал мне следующее:
Поток 2 "programm.out" получил сигнал SIGSEGV, Ошибка сегментации.[Переключение на поток 0x7ffff58f1700 (LWP 5651)] 0x0000555555605932 в сеансе :: запись (this = 0x0, t_msg = "{\" destination \ ": \" app0 \ "}") в /usr/Sources/Session.cpp:5858 std :: cout << dummyMember << std :: endl; </p>
Я добавил участника в сеанс (int dummyMember {5};).
Как может быть, что это указывает на 0x0?