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. postEvent to potentially destroyed receiver in another thread
QtWS25 Last Chance

postEvent to potentially destroyed receiver in another thread

Scheduled Pinned Locked Moved Solved General and Desktop
posteventthread
5 Posts 4 Posters 908 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.
  • B Offline
    B Offline
    BigOleg
    wrote on last edited by
    #1

    Hello, i am using QCoreApplication::post Event to send result of task from worker thread to an arbitrary receiver that lives in GUI thread. Receiver instance can be deleted during the execution of task. The Worker class stores receiver as QPointer and checks it before passing it to postEvent.

    struct Task
    {
        ...
        QPointer<QObject> receiver;
    };
    ...
    if (task.receiver)  
        QCoreApplication::postEvent(task.receiver, new TaskResultEvent{result}); 
    

    But if the receiver is actually deleted in GUI thread right after QPointer::operator T*() in worker thread the receiver parameter will become dangling and program will crash when trying to access receiver->d_func() inside postEvent.
    Is there safe way to send events for such cases without using signal-slot connections?
    Sorry for my English

    Pl45m4P 1 Reply Last reply
    0
    • KH-219DesignK Offline
      KH-219DesignK Offline
      KH-219Design
      wrote on last edited by KH-219Design
      #4

      @BigOleg said in postEvent to potentially destroyed receiver in another thread:

      program will crash when trying to access receiver->d_func() inside postEvent.

      There is a saying that says "often, a sufficiently well-formed problem statement is indistinguishable from a solution."

      You have described the problem very clearly.

      There is indeed a solution that I can envision quite clearly in conceptual terms. I leave it up to you to "port" the following conceptual solution to actual nuts-and-bolts of using QPointer or other Qt features:

      You need another layer of indirection. When the asynchronous event is "unpacked" (currently happening inside the application event loop when the posted-event is actually handled), at that later asynchronous point is when you need to check if (task.receiver) to guard against a crash.

      So you need to "post" a more involved bit of work. You need to queue up something more like a lambda, such that when the application event loop pulls the work off the queue in the GUI thread, the if (task.receiver) happens at THAT point. It needs to happen when the work is dequeued, not when it is enqueued. (Although you may wish to check for null in both places.)

      www.219design.com
      Software | Electrical | Mechanical | Product Design

      1 Reply Last reply
      1
      • B BigOleg

        Hello, i am using QCoreApplication::post Event to send result of task from worker thread to an arbitrary receiver that lives in GUI thread. Receiver instance can be deleted during the execution of task. The Worker class stores receiver as QPointer and checks it before passing it to postEvent.

        struct Task
        {
            ...
            QPointer<QObject> receiver;
        };
        ...
        if (task.receiver)  
            QCoreApplication::postEvent(task.receiver, new TaskResultEvent{result}); 
        

        But if the receiver is actually deleted in GUI thread right after QPointer::operator T*() in worker thread the receiver parameter will become dangling and program will crash when trying to access receiver->d_func() inside postEvent.
        Is there safe way to send events for such cases without using signal-slot connections?
        Sorry for my English

        Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by
        #2

        @BigOleg

        Cant you just make the Worker stop running as soon as the potential receiver gets destroyed?! Stop your worker and then call deleteLater on your receiver.


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        1 Reply Last reply
        0
        • B Offline
          B Offline
          BigOleg
          wrote on last edited by
          #3

          The purpose of the worker thread is to manage resources (for example, a connection to a database) whose opening/closing operations are relatively expensive. And widgets (with their lifetime) use this connection to query their data by sending tasks (e.g. query sets) through lightweight task instances.

          1 Reply Last reply
          0
          • KH-219DesignK Offline
            KH-219DesignK Offline
            KH-219Design
            wrote on last edited by KH-219Design
            #4

            @BigOleg said in postEvent to potentially destroyed receiver in another thread:

            program will crash when trying to access receiver->d_func() inside postEvent.

            There is a saying that says "often, a sufficiently well-formed problem statement is indistinguishable from a solution."

            You have described the problem very clearly.

            There is indeed a solution that I can envision quite clearly in conceptual terms. I leave it up to you to "port" the following conceptual solution to actual nuts-and-bolts of using QPointer or other Qt features:

            You need another layer of indirection. When the asynchronous event is "unpacked" (currently happening inside the application event loop when the posted-event is actually handled), at that later asynchronous point is when you need to check if (task.receiver) to guard against a crash.

            So you need to "post" a more involved bit of work. You need to queue up something more like a lambda, such that when the application event loop pulls the work off the queue in the GUI thread, the if (task.receiver) happens at THAT point. It needs to happen when the work is dequeued, not when it is enqueued. (Although you may wish to check for null in both places.)

            www.219design.com
            Software | Electrical | Mechanical | Product Design

            1 Reply Last reply
            1
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #5

              Hi,

              Following @KH-219Design suggestion, you should have a task manager rather than relying on the task object itself to do all the job.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0

              • Login

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