Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Delay closing the application in destructor waiting for a signal
Forum Updated to NodeBB v4.3 + New Features

Delay closing the application in destructor waiting for a signal

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 1.6k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mark81
    wrote on last edited by Mark81
    #1

    Is it possible to delay (possibly with a timeout) the closing of a console application inside a destructor?

    I have a class that needs to do some stuff (let's say an HTTP GET request or any other asynchronous call) when the application shuts down. It's easy to implement if you press the EXIT button... but I want to execute the procedure even in case of a SIGINT, SIGTERM, etc...

    Hence I wrote a simple function to catch those signals and I connected them to the QCoreApplication::quit slot. In this way the destructors of my classes are called before the application is shut down.

    In the destructor I fire the asynchronous call:

    MyClass::~MyClass()
    {
        // fire asynchronous call
        _myOtherClass->shutdownCall();
        // ? wait for a signal ?
    }
    

    But what if I want to wait for a signal before closing the application?

    // slot called when the related signal is emitted in shutdownCall()
    void MyClass::myOtherClassReply()
    {
        // ok, answer received, we can shut down
    }
    
    JonBJ 2 Replies Last reply
    0
    • M Mark81

      Is it possible to delay (possibly with a timeout) the closing of a console application inside a destructor?

      I have a class that needs to do some stuff (let's say an HTTP GET request or any other asynchronous call) when the application shuts down. It's easy to implement if you press the EXIT button... but I want to execute the procedure even in case of a SIGINT, SIGTERM, etc...

      Hence I wrote a simple function to catch those signals and I connected them to the QCoreApplication::quit slot. In this way the destructors of my classes are called before the application is shut down.

      In the destructor I fire the asynchronous call:

      MyClass::~MyClass()
      {
          // fire asynchronous call
          _myOtherClass->shutdownCall();
          // ? wait for a signal ?
      }
      

      But what if I want to wait for a signal before closing the application?

      // slot called when the related signal is emitted in shutdownCall()
      void MyClass::myOtherClassReply()
      {
          // ok, answer received, we can shut down
      }
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @Mark81
      The normal way to do a blocking wait for a signal to be emitted is via QEventLoop::exec().

      Whether it is safe/a good idea to do this in your class destructor depends on context.

      M 1 Reply Last reply
      0
      • JonBJ JonB

        @Mark81
        The normal way to do a blocking wait for a signal to be emitted is via QEventLoop::exec().

        Whether it is safe/a good idea to do this in your class destructor depends on context.

        M Offline
        M Offline
        Mark81
        wrote on last edited by
        #3

        @JonB what information I need to evaluate in order to decide whether the context is safe enough?

        JonBJ 1 Reply Last reply
        0
        • M Mark81

          @JonB what information I need to evaluate in order to decide whether the context is safe enough?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Mark81
          Well for a start I do not know if this even works from QCoreApplication::quit slot.

          M 1 Reply Last reply
          0
          • JonBJ JonB

            @Mark81
            Well for a start I do not know if this even works from QCoreApplication::quit slot.

            M Offline
            M Offline
            Mark81
            wrote on last edited by
            #5

            @JonB ok, so I change my question. What document should I read in order to learn how to achieve my goal?

            JonBJ 1 Reply Last reply
            0
            • M Mark81

              @JonB ok, so I change my question. What document should I read in order to learn how to achieve my goal?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @Mark81
              I don't know so I will leave someone else to comment.
              You might try it to see if it works or is a no-go from the outset.
              Normally shutdown is done in response to QCoreApplication::aboutToQuit() signal.
              I don't know whether there is an issue/how safe it is to do from your destructor.
              You must also be careful how you handle SIGINT/SIGTERM signals safely from a Qt application.

              1 Reply Last reply
              0
              • Axel SpoerlA Offline
                Axel SpoerlA Offline
                Axel Spoerl
                Moderators
                wrote on last edited by
                #7

                If connecting to a signal is not an option, the next thing that comes to mind is the destructor of a class that is deleted on the applications way out. A scope guard is practically the same, just that you can place it anywhere you want.

                If things can go wrong, it might be worth gambling with a custom message logger to intercept fatal messages. And if things can go terribly wrong but cleanup is needed in a safe environment, you can always write a second application as a watch dog. It can be dormant and occasionally check the main application for recent signs of life. If a critical state is diagnosed, it will send the fire fighters.

                Software Engineer
                The Qt Company, Oslo

                1 Reply Last reply
                2
                • Kent-DorfmanK Offline
                  Kent-DorfmanK Offline
                  Kent-Dorfman
                  wrote on last edited by
                  #8

                  already touch upon, but the brute force methods will be trapping signals and implementing an atexit() handler...but keep in mind that your cleanup may fail if the requisite objects have already been destroyed by the time the handlers are called.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    Mark81
                    wrote on last edited by
                    #9

                    Thank you all, guys.

                    1 Reply Last reply
                    0
                    • M Mark81

                      Is it possible to delay (possibly with a timeout) the closing of a console application inside a destructor?

                      I have a class that needs to do some stuff (let's say an HTTP GET request or any other asynchronous call) when the application shuts down. It's easy to implement if you press the EXIT button... but I want to execute the procedure even in case of a SIGINT, SIGTERM, etc...

                      Hence I wrote a simple function to catch those signals and I connected them to the QCoreApplication::quit slot. In this way the destructors of my classes are called before the application is shut down.

                      In the destructor I fire the asynchronous call:

                      MyClass::~MyClass()
                      {
                          // fire asynchronous call
                          _myOtherClass->shutdownCall();
                          // ? wait for a signal ?
                      }
                      

                      But what if I want to wait for a signal before closing the application?

                      // slot called when the related signal is emitted in shutdownCall()
                      void MyClass::myOtherClassReply()
                      {
                          // ok, answer received, we can shut down
                      }
                      
                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #10

                      @Mark81 said in Delay closing the application in destructor waiting for a signal:

                      Hence I wrote a simple function to catch those signals and I connected them to the QCoreApplication::quit slot.

                      One observation. I think you are saying you catch Linux signals like SIGINT/SIGTERM and either call QCoreApplication::quit() slot directly or maybe emit a signal which has this connected as a slot? What you are allowed to do from a Linux signal handler is very limited. The most I would do is emit a signal and the connect() must be Qt::QueuedConnection. I'm not even certain that is safe, but certainly better than anything which invokes QCoreApplication::quit() directly. Let us know if you want us to dig out some code reference about what is safe to do from a Linux signal in a Qt application.

                      M 1 Reply Last reply
                      1
                      • JonBJ JonB

                        @Mark81 said in Delay closing the application in destructor waiting for a signal:

                        Hence I wrote a simple function to catch those signals and I connected them to the QCoreApplication::quit slot.

                        One observation. I think you are saying you catch Linux signals like SIGINT/SIGTERM and either call QCoreApplication::quit() slot directly or maybe emit a signal which has this connected as a slot? What you are allowed to do from a Linux signal handler is very limited. The most I would do is emit a signal and the connect() must be Qt::QueuedConnection. I'm not even certain that is safe, but certainly better than anything which invokes QCoreApplication::quit() directly. Let us know if you want us to dig out some code reference about what is safe to do from a Linux signal in a Qt application.

                        M Offline
                        M Offline
                        Mark81
                        wrote on last edited by
                        #11

                        @JonB yep, currently I'm doing this in main.cpp:

                        QObject::connect(&handler, &SignalsHandler::quit, &a, QCoreApplication::quit);
                        

                        Actually, what do you mean when talking about "safe"?
                        Before kindly asking you to spend other time, I'm going to better understand what I have to do in order to close the connection with the remote device. Perhaps, there is a better way that does not require this "mess".

                        Thanks for your availability

                        JonBJ 1 Reply Last reply
                        0
                        • M Mark81

                          @JonB yep, currently I'm doing this in main.cpp:

                          QObject::connect(&handler, &SignalsHandler::quit, &a, QCoreApplication::quit);
                          

                          Actually, what do you mean when talking about "safe"?
                          Before kindly asking you to spend other time, I'm going to better understand what I have to do in order to close the connection with the remote device. Perhaps, there is a better way that does not require this "mess".

                          Thanks for your availability

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #12

                          @Mark81
                          While inside a Linux signal handler, such as from SIGINT/SIGTERM, you are very limited as to what you are allowed to do "safely". Basically you are in a context where you are supposed to do as little as possible (e.g. set a variable) and then exit the signal handler. You are not supposed to do anything at all "complicated". So, for example, using Qt I think it would be best to post a simple message/signal --- assuming that is safe --- and exit the signal handler, allowing the event loop to later pick that up and do the actual exiting, rather than doing the exit from within the signal handler directly.

                          In your connect() above, for example, I would be making it a Qt::QueuedConnection. (For other reasons the code at https://doc.qt.io/qt-6/qcoreapplication.html#quit actually recommends/shows this anyway.)

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved