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. Application events being processed after exit() call - bug or feature??
Forum Updated to NodeBB v4.3 + New Features

Application events being processed after exit() call - bug or feature??

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 459 Views
  • 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.
  • A Offline
    A Offline
    alexwtan
    wrote on 9 Dec 2021, 05:13 last edited by
    #1

    Hey all!
    Im wondering why qt application event loop process some events after exit() call ?

    Consider such a simple demo app:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QTimer>
    
    void print(int code)
    {
        qDebug() << code;
    }
    
    void reproduceBug()
    {
        QTimer::singleShot(0, nullptr, [](){print(1);});
        QTimer::singleShot(0, nullptr, [](){QCoreApplication::exit(0);});
        QTimer::singleShot(0, nullptr, [](){print(2);});
        QTimer::singleShot(0, nullptr, [](){print(3);});
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        reproduceBug();
        return a.exec();
    }
    
    

    I would expect output to be

    11:56:15: Starting ..\QtBugExitEventLoop.exe ...
    1
    11:56:15: ..\QtBugExitEventLoop.exe exited with code 0
    

    But actual output is

    11:56:15: Starting ..\QtBugExitEventLoop.exe ...
    1
    2
    3
    11:56:15: ..\QtBugExitEventLoop.exe exited with code 0
    

    You can see that message loop events still being processed after call to exit() !
    Looks like a bug, isn't it?.

    Documentation for qcoreapplication::exit says
    After this function has been called, the application leaves the main event loop and returns from the call to exec().

    So why it does not exit?


    Looking in source code I see that application::exec runs message loop which have check for exit:

    int QEventLoop::exec(ProcessEventsFlags flags) {
        ...
        while (!d->exit.loadAcquire()) <----- check
            processEvents(flags | WaitForMoreEvents | EventLoopExec);
    

    But the method processEvents itself leads to QCoreApplicationPrivate::sendPostedEvents and always process whole bunch of events which are in list by the time of the call to it:

    void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
                                                   QThreadData *data)
    {
    	...
    	while (i < data->postEventList.size()) {
    		// avoid live-lock
    		if (i >= data->postEventList.insertionOffset)
    			break;
    		const QPostEvent &pe = data->postEventList.at(i);
    		++i;
    		// and various checks but no one for exit called..
    		...
    		QCoreApplication::sendEvent(r, e);
    	}
    	...
    }
    
    

    Should I report a bug or this is somehow expected (by who?) behaviour?

    J 1 Reply Last reply 9 Dec 2021, 07:22
    0
    • A alexwtan
      9 Dec 2021, 05:13

      Hey all!
      Im wondering why qt application event loop process some events after exit() call ?

      Consider such a simple demo app:

      #include <QCoreApplication>
      #include <QDebug>
      #include <QTimer>
      
      void print(int code)
      {
          qDebug() << code;
      }
      
      void reproduceBug()
      {
          QTimer::singleShot(0, nullptr, [](){print(1);});
          QTimer::singleShot(0, nullptr, [](){QCoreApplication::exit(0);});
          QTimer::singleShot(0, nullptr, [](){print(2);});
          QTimer::singleShot(0, nullptr, [](){print(3);});
      }
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
          reproduceBug();
          return a.exec();
      }
      
      

      I would expect output to be

      11:56:15: Starting ..\QtBugExitEventLoop.exe ...
      1
      11:56:15: ..\QtBugExitEventLoop.exe exited with code 0
      

      But actual output is

      11:56:15: Starting ..\QtBugExitEventLoop.exe ...
      1
      2
      3
      11:56:15: ..\QtBugExitEventLoop.exe exited with code 0
      

      You can see that message loop events still being processed after call to exit() !
      Looks like a bug, isn't it?.

      Documentation for qcoreapplication::exit says
      After this function has been called, the application leaves the main event loop and returns from the call to exec().

      So why it does not exit?


      Looking in source code I see that application::exec runs message loop which have check for exit:

      int QEventLoop::exec(ProcessEventsFlags flags) {
          ...
          while (!d->exit.loadAcquire()) <----- check
              processEvents(flags | WaitForMoreEvents | EventLoopExec);
      

      But the method processEvents itself leads to QCoreApplicationPrivate::sendPostedEvents and always process whole bunch of events which are in list by the time of the call to it:

      void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
                                                     QThreadData *data)
      {
      	...
      	while (i < data->postEventList.size()) {
      		// avoid live-lock
      		if (i >= data->postEventList.insertionOffset)
      			break;
      		const QPostEvent &pe = data->postEventList.at(i);
      		++i;
      		// and various checks but no one for exit called..
      		...
      		QCoreApplication::sendEvent(r, e);
      	}
      	...
      }
      
      

      Should I report a bug or this is somehow expected (by who?) behaviour?

      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 9 Dec 2021, 07:22 last edited by
      #2

      @alexwtan QTimer::singleShot(0, ...) calls put all these 4 events into event loop. Next time the event loop runs it handles all events which are currently in the event loops. So, all 4 lambdas are executed and then the exit() tells event loop to terminate (in the while() condinion you posted). processEvents() processes all events as far as I know currently waiting in the event loop.
      So, no bug, works as expected.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      3
      • A Offline
        A Offline
        alexwtan
        wrote on 10 Dec 2021, 03:47 last edited by
        #3

        @jsulm Thank you for the clarifications!.

        I understand why current code works how it works. But sorry, I'm still don't understand why it is ok to process any application event after exit() call :)

        What if I have 2 events in list: first is user click on close application (exit() called while processing) and 2nd is message that starts long calculation process in background? I shouldn't process 2nd and this information is obvious to qt since exit flag is raised to moment when it will start processing 2nd event.

        Why I'm pushed to spawn redundant checks in user code instead of just do the work right in qt framework?

        1 Reply Last reply
        0

        1/3

        9 Dec 2021, 05:13

        • Login

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