vdr 2.4.1 will not stop without killing, using ubuntu focal 20.04
CKone01 opened this issue · comments
Hello
in several ppa attached two patches are used to make it compile with boost 1.67. Plugin functionality seems ok but vdr will not stop.
Thanks a lot
Christian
Thanks for your work!
- Regarding boost patch, this is already in the codebase thanks to #1
- Regarding the formatting issue, I will apply your patch. Thanks!
Sorry but the issue was not solved by the patched attached, this was only for your information of used code. :(
Its still the problem that vdr does not stop when using vdr-plugin-fritzbox on ubuntu 20.04 focal.
Aah misunderstood your issue.
To add some info after looking into the call stack with gdb after initiating a vdr shutdown:
It seems that std::getline() does not finish (https://github.com/jowi24/libfritzpp/blob/master/Listener.cpp#L138 -> https://github.com/jowi24/libnetpp/blob/master/TcpClient.cpp#L47).
As far as I undestand the documentation of boost::asio::ip::tcp::iostream breaking the connection by timeout only affects operations scheduled after the call, so https://github.com/jowi24/libnetpp/blob/212847f0efaeffee8422059b8e202d844174aaf3/TcpClient.cpp#L59 doesn't have the intended effect of breaking out of the reading operation, which prevents the thread from joining.
boost::asio seems quite a complex library (especially for a C++ newbie like me) - I wonder if switching to async_read_until(), which in turn runs a callback once it has found a newline in the incoming data would circumvent this blocking operation, since https://www.boost.org/doc/libs/1_74_0/doc/html/boost_asio/reference/basic_stream_socket/close/overload1.html states, that closing the socket would cancel async operations immediately.
A quick workaround is to cancel the underlying pthread, but I do not know if this has unintended side-effects:
Index: vdr-plugin-fritzbox-1.5.3+git20200520-8-b56735f/libfritz++/Listener.h
===================================================================
--- vdr-plugin-fritzbox-1.5.3+git20200520-8-b56735f.orig/libfritz++/Listener.h 2020-08-31 10:11:46.241955807 +0200
+++ vdr-plugin-fritzbox-1.5.3+git20200520-8-b56735f/libfritz++/Listener.h 2020-08-31 10:11:56.473933841 +0200
@@ -60,6 +60,7 @@
EventHandler *event;
std::vector<int> activeConnections;
std::thread *thread;
+ pthread_t threadNativeHandle;
network::TcpClient *tcpClientPtr = nullptr;
Listener(EventHandler *event);
void handleNewCall(bool outgoing, int connId, std::string remoteNumber, std::string localParty, std::string medium);
Index: vdr-plugin-fritzbox-1.5.3+git20200520-8-b56735f/libfritz++/Listener.cpp
===================================================================
--- vdr-plugin-fritzbox-1.5.3+git20200520-8-b56735f.orig/libfritz++/Listener.cpp 2020-05-20 15:03:14.000000000 +0200
+++ vdr-plugin-fritzbox-1.5.3+git20200520-8-b56735f/libfritz++/Listener.cpp 2020-08-31 12:20:28.668567578 +0200
@@ -41,13 +41,17 @@
{
this->event = event;
thread = new std::thread(&Listener::run, this);
+ threadNativeHandle = thread->native_handle();
+ thread->detach();
}
Listener::~Listener()
{
if (thread) {
cancelThread();
- thread->join();
+ int r = pthread_cancel(threadNativeHandle);
+ if (r != 0)
+ ERR(std::string{"could not cancel thread: "} + strerror(r));
delete thread;
}
}