{"id":10913,"date":"2011-04-18T07:00:00","date_gmt":"2011-04-18T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2011\/04\/18\/dont-forget-to-include-the-message-queue-in-your-lock-hierarchy\/"},"modified":"2011-04-18T07:00:00","modified_gmt":"2011-04-18T07:00:00","slug":"dont-forget-to-include-the-message-queue-in-your-lock-hierarchy","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20110418-00\/?p=10913","title":{"rendered":"Don&#039;t forget to include the message queue in your lock hierarchy"},"content":{"rendered":"<p>\nIn addition to the loader lock,\nthe message queue is another resource that people often\nforget to incorporate into their lock hierarchy.\nIf your code runs on a UI thread, then it implicitly owns\nthe message queue whenever it is running,\nbecause messages cannot be dispatched to a thread until\nit calls a message-retrieval function\nsuch as <code>Get&shy;Message<\/code> or\n<code>Peek&shy;Message<\/code>.\nIn other words, whenever a thread is not checking for a message,\nit cannot receive a message.\n<\/p>\n<p>\nFor example, consider the following code:\n<\/p>\n<pre>\nEnterCriticalSection(&amp;g_cs);\nfor (int i = 0; i &lt; 10; i++) {\n  SendMessage(hwndLB, LB_ADDSTRING, 0, (LPARAM)strings[i]);\n}\nLeaveCriticalSection(&amp;g_cs);\n<\/pre>\n<p>\nIf <code>hwndLB<\/code> belongs to another thread,\nthen you have a potential deadlock,\nbecause that thread might be waiting for your critical section.\n<\/p>\n<pre>\ncase WM_DOESNTMATTERWHAT:\n    EnterCriticalSection(&amp;g_cs);\n    ... doesn't matter what goes here ...\n    LeaveCriticalSection(&amp;g_cs);\n    break;\n<\/pre>\n<p>\nIf you happen to try to send the message while that other\nthread is waiting for the critical section,\nyou will deadlock because you are waiting for that thread\nto finish whatever it&#8217;s doing so it can process the message\nyou sent to it,\nbut that thread is waiting for\nthe critical section which you own.\n<\/p>\n<p>\nEven if you promise that\n<code>hwndLB<\/code> belongs to your thread,\nthe possibility of subclassing or window hooks\nmeans that you do not have full control over\nwhat happens when you try to send that message.\nA <code>WH_CALL&shy;WND&shy;PROC<\/code>\nwindow hook may decide to communicate with\nanother thread (for example, to log the message).\nBoom, what you thought was a simple message sent\nto a window on your thread turned into a cross-thread\nmessage.\n<\/p>\n<p>\nThere are many actions that generate message traffic\nthat may not be obvious at first glance because\nthey don&#8217;t involve explicitly sending a message.\nInvoking a COM method from an STA thread on an object\nwhich belongs to another apartment\nrequires the call to be marshaled to the thread that hosts\nthe object.\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/02\/21\/10131989.aspx\">\nTinkering with a window&#8217;s scroll bars<\/a>\ncan result in\nthe <code>WS_HSCROLL<\/code>\nor <code>WS_VSCROLL<\/code> style being added or removed,\nwhich in turn generates\n<code>WM_STYLE&shy;CHANGING<\/code> and\n<code>WM_STYLE&shy;CHANGED<\/code> messages.\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2003\/08\/21\/54675.aspx\">\nObtaining the text from a window\nbelonging to another thread in your process<\/a>\nresults in synchronous message traffic.\n<\/p>\n<p>\nA good rule of thumb is basically to avoid anything that\ninvolves windows belonging to other threads while holding\na critical section or other resource.\nAnd even windows which belong to your thread are suspect\n(due to hooks and subclassing).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In addition to the loader lock, the message queue is another resource that people often forget to incorporate into their lock hierarchy. If your code runs on a UI thread, then it implicitly owns the message queue whenever it is running, because messages cannot be dispatched to a thread until it calls a message-retrieval function [&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-10913","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>In addition to the loader lock, the message queue is another resource that people often forget to incorporate into their lock hierarchy. If your code runs on a UI thread, then it implicitly owns the message queue whenever it is running, because messages cannot be dispatched to a thread until it calls a message-retrieval function [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/10913","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=10913"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/10913\/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=10913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=10913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=10913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}