Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Calling a function callback on a specific known thread

Calling a function callback on a specific known thread

Scheduled Pinned Locked Moved C / C++ / MFC
helpcomdata-structuresquestion
4 Posts 2 Posters 0 Views 1 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.
  • T Offline
    T Offline
    tonyschr
    wrote on last edited by
    #1

    I'm creating a synchronized queue where callers can register to have a function called after a specified timeout (or after the previous one has finished, whichever comes last). Everything works great, but I would like to extend this so that any thread can queue up items, and the callback is guaranteed to be executed on that thread. Ideally, a function like SetTimerOnThread(DWORD dwThreadID, TIMERPROC lpTimerFunc) is what I'm looking for. SetTimer() will call back on the originating thread, but the problem is that after it returns from the callback I need to set the timer for the next workitem, which may have been queued up from a different thread. Posting messages to various windows would help, but might get hairy. I'm trying to build this so that it doesn't depend on a windprocs having direct knowledge of the queue, or the queue having direct knowledge of windows. Another potential solution is to CoMarshalInterThreadInterfaceInStream the item when it enters the queue, and unmarshal just prior to executing it. The marshalling should take care of making sure everything happens on the right thread. I don't particularly like this solution though. It's overkill and the queue doesn't currently use COM. Any suggestions? --CoolDev :cool:

    T 1 Reply Last reply
    0
    • T tonyschr

      I'm creating a synchronized queue where callers can register to have a function called after a specified timeout (or after the previous one has finished, whichever comes last). Everything works great, but I would like to extend this so that any thread can queue up items, and the callback is guaranteed to be executed on that thread. Ideally, a function like SetTimerOnThread(DWORD dwThreadID, TIMERPROC lpTimerFunc) is what I'm looking for. SetTimer() will call back on the originating thread, but the problem is that after it returns from the callback I need to set the timer for the next workitem, which may have been queued up from a different thread. Posting messages to various windows would help, but might get hairy. I'm trying to build this so that it doesn't depend on a windprocs having direct knowledge of the queue, or the queue having direct knowledge of windows. Another potential solution is to CoMarshalInterThreadInterfaceInStream the item when it enters the queue, and unmarshal just prior to executing it. The marshalling should take care of making sure everything happens on the right thread. I don't particularly like this solution though. It's overkill and the queue doesn't currently use COM. Any suggestions? --CoolDev :cool:

      T Offline
      T Offline
      Tomasz Sowinski
      wrote on last edited by
      #2

      the callback is guaranteed to be executed on that thread Wow, that's quite impressive requirement. What should happen if that thread is busy? Seems that you'll need some cooperation from the thread you want your callback to be executed on - for example, waiting for Win32 event when there's no work to do. When the event is in signaled state, thread picks up callback address from the queue and jumps into it. Tomasz Sowinski -- http://www.shooltz.com

      T 1 Reply Last reply
      0
      • T Tomasz Sowinski

        the callback is guaranteed to be executed on that thread Wow, that's quite impressive requirement. What should happen if that thread is busy? Seems that you'll need some cooperation from the thread you want your callback to be executed on - for example, waiting for Win32 event when there's no work to do. When the event is in signaled state, thread picks up callback address from the queue and jumps into it. Tomasz Sowinski -- http://www.shooltz.com

        T Offline
        T Offline
        tonyschr
        wrote on last edited by
        #3

        The idea is that it's on a timer, so it happens whenever the thread gets around to handling the message. (I'm not trying to do something like QueueUserAPC() without expecting the thread to be in a waitable state!) This requires that all threads using the queue have a message pump, but that will always be the case for this application. If you do away with encapsulation and let a WndProc on each thread know about the queue, and have the queue store a handle to a window on each thread, than it would just be a matter of posting a message to the window once the timer has elapsed. If MSDN didn't explicitly disallow it I could pass an HWND who's message pump lives on another thread to SetTimer() with the expectation that it would post a WM_TIMER message to that window after the timeout. If params I sent to SetTimer() included a callback then it could call the callback without having to handle WM_TIMER in each WndProc. --CoolDev :cool:

        T 1 Reply Last reply
        0
        • T tonyschr

          The idea is that it's on a timer, so it happens whenever the thread gets around to handling the message. (I'm not trying to do something like QueueUserAPC() without expecting the thread to be in a waitable state!) This requires that all threads using the queue have a message pump, but that will always be the case for this application. If you do away with encapsulation and let a WndProc on each thread know about the queue, and have the queue store a handle to a window on each thread, than it would just be a matter of posting a message to the window once the timer has elapsed. If MSDN didn't explicitly disallow it I could pass an HWND who's message pump lives on another thread to SetTimer() with the expectation that it would post a WM_TIMER message to that window after the timeout. If params I sent to SetTimer() included a callback then it could call the callback without having to handle WM_TIMER in each WndProc. --CoolDev :cool:

          T Offline
          T Offline
          Tomasz Sowinski
          wrote on last edited by
          #4

          I think you should use PostThreadMessage and place the call to message handling code inside the thread's message loop, since messages posted with PostThreadMessage have hwnd == NULL. Tomasz Sowinski -- http://www.shooltz.com

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups