|
|
@@ -116,11 +116,29 @@ struct frame_sender::impl {
|
|
|
boost::scoped_ptr<deadline_timer> keepalive_timer;
|
|
|
std::deque<sent_frame_info> sent_list; // pending confirm list
|
|
|
|
|
|
- std::thread *work_thread = nullptr;
|
|
|
+ std::unique_ptr<std::thread> work_thread;
|
|
|
|
|
|
impl() {
|
|
|
in_data = (char *) malloc(buffer_size);
|
|
|
out_data = (char *) malloc(buffer_size);
|
|
|
+
|
|
|
+ context.reset(new io_context{});
|
|
|
+ chan.reset(new chan_type{*context, channel_buffer_size});
|
|
|
+ keepalive_timer.reset(new deadline_timer{*context});
|
|
|
+
|
|
|
+ auto error_handler = [](std::exception_ptr ep) {
|
|
|
+ if (!ep) {
|
|
|
+ SPDLOG_ERROR("Infinite loop exited with no error.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ std::rethrow_exception(ep);
|
|
|
+ } catch (std::exception &e) {
|
|
|
+ SPDLOG_ERROR("Infinite loop exited with error: {}", e.what());
|
|
|
+ }
|
|
|
+ };
|
|
|
+ co_spawn(*context, main_loop(), error_handler);
|
|
|
+ co_spawn(*context, keepalive_loop(), error_handler);
|
|
|
}
|
|
|
|
|
|
~impl() {
|
|
|
@@ -473,48 +491,34 @@ struct frame_sender::impl {
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
- auto error_handler = [](std::exception_ptr ep) {
|
|
|
- if (!ep) {
|
|
|
- SPDLOG_ERROR("Infinite loop exited with no error.");
|
|
|
- return;
|
|
|
- }
|
|
|
- try {
|
|
|
- std::rethrow_exception(ep);
|
|
|
- } catch (std::exception &e) {
|
|
|
- SPDLOG_ERROR("Infinite loop exited with error: {}", e.what());
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- context.reset(new io_context{});
|
|
|
- chan.reset(new chan_type{*context, channel_buffer_size});
|
|
|
- keepalive_timer.reset(new deadline_timer{*context});
|
|
|
keepalive_timer->expires_at(pos_infin);
|
|
|
auto local_endpoint = udp::endpoint{udp::v4(), local_port};
|
|
|
socket.reset(new udp::socket{*context, local_endpoint});
|
|
|
socket->set_option(udp::socket::send_buffer_size{10 * 1024 * 1024}); // 10MB send buffer
|
|
|
assert(socket->is_open());
|
|
|
- co_spawn(*context, main_loop(), error_handler);
|
|
|
- co_spawn(*context, keepalive_loop(), error_handler);
|
|
|
+ if (context->stopped()) {
|
|
|
+ context->restart();
|
|
|
+ }
|
|
|
|
|
|
// request idr frame
|
|
|
idr_flag->test_and_set();
|
|
|
|
|
|
assert(work_thread == nullptr);
|
|
|
- work_thread = new std::thread{[this]() {
|
|
|
+ work_thread = std::make_unique<std::thread>([this]() {
|
|
|
try {
|
|
|
context->run();
|
|
|
} catch (std::exception &e) {
|
|
|
SPDLOG_ERROR("Frame sender error: {}", e.what());
|
|
|
}
|
|
|
- }};
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
void stop() {
|
|
|
if (work_thread == nullptr) return;
|
|
|
context->stop();
|
|
|
work_thread->join();
|
|
|
- delete work_thread;
|
|
|
work_thread = nullptr;
|
|
|
+ socket->close();
|
|
|
}
|
|
|
|
|
|
};
|