Я пытаюсь разрешить циклическую зависимость во время жизни общего цикла обработки событий и общего объекта, который обеспечивает время жизни цикла обработки событий.
Чтобы сделать это конкретным, вот разделверсия моего кода:
class TcpConn : public std::enable_shared_from_this<TcpConn> {
std::shared_ptr<EventLoop> event_loop;
void send_impl();
public:
TcpConn(std::shared_ptr<EventLoop> event_loop) : event_loop{event_loop} {}
void send() {
std::weak_ptr<TcpConn> wp = shared_from_this();
event_loop->call_soon([wp]() {
auto sp = wp.lock();
if (sp) {
sp->send_impl();
}
});
}
};
event_loop
гарантированно будет существовать в течение жизни TcpConn
.event_loop
может пережить TcpConn
, что делает его немного более сложным.
Чтобы убедиться, что TcpConn
жив, когда event_loop
выполняет send_impl()
, я беру weak_ptr
на TcpConn
и его блокировку на время send_impl()
.
Если все другие ссылки на TcpConn
исчезнут во время вызова на send_impl()
, event_loop
останется с последнимshared_ptr
до TcpConn
.Затем event_loop
попытается уничтожить TcpConn
, включая, возможно, уничтожение последнего экземпляра event_loop
...
event_loop
, разрушение самого себя вызывает всевозможные проблемы, особенно в моем случае, когдаEventLoop
- абстрактный базовый класс, реализованный пользователями моей библиотеки.Обычные реализации EventLoop
используют поток, а event_loop
, уничтожая себя, заставит поток присоединиться к самому себе.
Есть ли шаблон, который я пропускаю, который не даст event_loop
иметьпоследний оставшийся TcpConn
?