{"id":1373,"date":"2014-03-28T07:00:00","date_gmt":"2014-03-28T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/03\/28\/the-dangers-of-buffering-up-posted-messages-and-then-reposting-them-later\/"},"modified":"2014-03-28T07:00:00","modified_gmt":"2014-03-28T07:00:00","slug":"the-dangers-of-buffering-up-posted-messages-and-then-reposting-them-later","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140328-00\/?p=1373","title":{"rendered":"The dangers of buffering up posted messages and then reposting them later"},"content":{"rendered":"<p>\nA customer wanted to check that their idea for solving a re-entrancy\nproblem doesn&#8217;t have any hidden gotchas.\n<\/p>\n<blockquote CLASS=\"q\">\n<p>\nWe have a window which processes incoming work.\nOne of our work items enters a modal loop,\nand if new work gets posted to the window while the modal loop is\nrunning, our work manager gets re-entered,\nand Bad Things happen.\n<\/p>\n<p>\nOur proposed solution is to alter the modal loop so that\nit buffers up all messages destined for the worker window.\n(Messages for any other window are dispatched normally.)\nWhen the modal loop completes, we re-post all the messages\nfrom the buffer, thereby allowing the worker window to resume\nprocessing.\n<\/p>\n<\/blockquote>\n<p>\nThe danger here is that reposting messages can result in messages\nbeing processed out of order.\nDepending on how your worker window is designed, this might or might\nnot be a problem.\nFor example, suppose that during the modal operation,\nsomebody posts the\n<code>WWM_FOO&shy;STARTED<\/code> message to the worker window.\nYou buffer it up.\nWhen your modal operation is complete, you are about to post the\nmessage back into the queue, but another thread races against you\nand posts the\n<code>WWM_FOO&shy;COMPLETED<\/code> message\nbefore you can post your buffered messages back into the queue.\nResult: The worker window receives the\n<code>WWM_FOO&shy;COMPLETED<\/code> message\nbefore it receives the\n<code>WWM_FOO&shy;STARTED<\/code> message.\nThis will probably lead to confusion.\n<\/p>\n<p>\nThe place to solve this problem is in the window itself.\nThat gets rid of the race condition.\n<\/p>\n<pre>\nLRESULT CALLBACK WorkerWindow::WndProc(\n    HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\n{\n if (uMsg is a work message) {\n  if (m_cBusy) {\n   \/\/ Now is a bad time to process the work message.\n   \/\/ Queue it up for later.\n   m_queue.Append(uMsg, wParam, lParam);\n  } else {\n   m_cBusy++; \/\/ prevent re-entrancy\n   do {\n    ProcessWorkMessage(uMsg, wParam, lParam);\n   } while (m_queue.RemoveFirst(&amp;uMsg, &amp;wParam, &amp;lParam));\n   m_cBusy--; \/\/ re-entrancy no longer a problem\n  }\n  return 0;\n }\n ...  \/\/ handle the other messages\n}\n<\/pre>\n<p>\nBy queueing up the work inside the window itself,\nyou ensure that the messages are processed in the same order\nthey were received.\n<\/p>\n<p>\nThis technique can be extended to, say, have the worker window\ndo some degree of work throttling.\nFor example, you might keep track of how long you&#8217;ve been\nprocessing work,\nand if it&#8217;s been a long time,\nthen stop to pump messages for a while in case any system messages\ncame in,\nand somebody is waiting for your answer.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer wanted to check that their idea for solving a re-entrancy problem doesn&#8217;t have any hidden gotchas. We have a window which processes incoming work. One of our work items enters a modal loop, and if new work gets posted to the window while the modal loop is running, our work manager gets re-entered, [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-1373","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer wanted to check that their idea for solving a re-entrancy problem doesn&#8217;t have any hidden gotchas. We have a window which processes incoming work. One of our work items enters a modal loop, and if new work gets posted to the window while the modal loop is running, our work manager gets re-entered, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/1373","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=1373"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/1373\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=1373"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=1373"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=1373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}