jowi24 / vdr-fritz

A plugin for VDR to access AVMs Fritz Box routers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

fritzbox_patches.zip

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;
        }
 }