{"id":4043,"date":"2013-06-19T07:00:00","date_gmt":"2013-06-19T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/06\/19\/attachthreadinput-is-like-taking-two-threads-and-pooling-their-money-into-a-joint-bank-account-where-both-parties-need-to-be-present-in-order-to-withdraw-any-money\/"},"modified":"2013-06-19T07:00:00","modified_gmt":"2013-06-19T07:00:00","slug":"attachthreadinput-is-like-taking-two-threads-and-pooling-their-money-into-a-joint-bank-account-where-both-parties-need-to-be-present-in-order-to-withdraw-any-money","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130619-00\/?p=4043","title":{"rendered":"AttachThreadInput is like taking two threads and pooling their money into a joint bank account, where both parties need to be present in order to withdraw any money"},"content":{"rendered":"<p><P>\nConsider this code:\n<\/P>\n<PRE>\n<I>\/\/ Code in italics is wrong\n   foregroundThreadId = ::GetWindowThreadProcessId(::GetForegroundWindow(), 0); \n   myThreadId = GetCurrentThreadId(); <\/p>\n<p>   if (foregroundThreadId != myThreadId) \n   { \n       AttachThreadInput(foregroundThreadId, myThreadId, TRUE); \n       BringWindowToTop(myWindowHandle);<\/I>\n<\/PRE>\n<P>\nIf you try to step over the\n<CODE>Attach&shy;Thread&shy;Input<\/CODE>\ncall in the debugger,\nboth the debugger and the application being debugged will freeze.\nWhy is that?\n<\/P>\n<P>\nThis should look familiar because\nit&#8217;s basically\n<A HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2008\/08\/01\/8795860.aspx\">\nthe same code that I warned you about several years ago<\/A>.\nThe code grabs the current foreground window and attaches\nits input state to the current thread.\nNow you&#8217;re in trouble.\n<\/P>\n<P>\nRemember dual-signature bank accounts?\nThese were bank accounts that required the signatures of both\naccount holders in order to make a withdrawal.\nIt can work out fine\nif the two parties trust each other with a shared bank account\nand can coordinate their actions so that when one of them needs money,\nit can go to the other and say,\n&#8220;Hey, can you sign this withdrawal slip?\nI need some money.&#8221;\n(Another use case for dual-signature bank accounts was a parent\nwanting to monitor their child&#8217;s spending.)\n<\/P>\n<P>\n<CODE>Attach&shy;Thread&shy;Input<\/CODE>\ntells the window manager,\n&#8220;Please take these two threads and put all their money\nin a dual-signature bank account.&#8221;\n<\/P>\n<P>\nIn the case above, the code said,\n&#8220;See that <I>random person being served by the bank teller<\/I>?\nPlease take all my money and all his money and\nput them into a dual-signature bank account.&#8221;\n<\/P>\n<P>\nAs you can imagine, this is a bad idea,\nboth for you and for the other person.\nYou cannot withdraw any money until you can somehow\ntrack down that random person and get him to sign the withdrawal form.\nAnd it&#8217;s not like you have any relationship with that\nperson&mdash;you don&#8217;t even know his name!&mdash;so the only chance\nyou have is to go down to the bank and hang out there hoping that\nthe other guy will show up to make a withdrawal as part of his normal\ncourse of business,\nand then you can say,\n&#8220;Hey, you there!\nSign this for me, will ya?&#8221;\n<\/P>\n<P>\nThe other person is in a similar predicament.\nWhen he goes to the bank to make a withdrawal, the teller will say,\n&#8220;I&#8217;m sorry, sir, but your money is in a dual-signature account,\nand your withdrawal slip has only one signature on it.&#8221;\nHe&#8217;s stuck doing the same thing that you do:\nWhenever he wants to withdraw money, he has to go to the bank\nand hang around hoping that you will show up eventually.\n<\/P>\n<TABLE BORDER=\"0\">\n<TR>\n    <TD ALIGN=\"right\">bank account<\/TD>\n    <TD>&harr;<\/TD>\n    <TD>input queue<TD>\n<\/TR>\n<TR>\n    <TD ALIGN=\"right\">money<\/TD>\n    <TD>&harr;<\/TD>\n    <TD>input<TD>\n<\/TR>\n<TR>\n    <TD ALIGN=\"right\">go to the bank<\/TD>\n    <TD>&harr;<\/TD>\n    <TD>check the message queue<TD>\n<\/TR>\n<\/TABLE>\n<P>\nIn this case,\nwhat happened was that the code grabbed the debugger and said,\n&#8220;Okay, we now have a dual-signature bank account!&#8221;\nAnd now you&#8217;re stuck.\nThe debugger cannot withdraw any money\nbecause it is waiting for you to go to the bank.\nBut you can&#8217;t go to the bank because you&#8217;re broken into the debugger.\nResult: Nobody gets any money.\n<\/P>\n<P>\nThis is why you shouldn&#8217;t grab random people in the bank and unilaterally\ncreate dual-signature bank accounts with them.\n<\/P>\n<P>\n<B>Reminder<\/B>:\nAttaching input queues is not a Get Out of Jail Free card.\n<A HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/06\/07\/10424279.aspx\">\nIt&#8217;s a\n<I>Get Into the Same Jail<\/I> card<\/A>.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Consider this code: \/\/ Code in italics is wrong foregroundThreadId = ::GetWindowThreadProcessId(::GetForegroundWindow(), 0); myThreadId = GetCurrentThreadId(); if (foregroundThreadId != myThreadId) { AttachThreadInput(foregroundThreadId, myThreadId, TRUE); BringWindowToTop(myWindowHandle); If you try to step over the Attach&shy;Thread&shy;Input call in the debugger, both the debugger and the application being debugged will freeze. Why is that? This should look familiar because [&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-4043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Consider this code: \/\/ Code in italics is wrong foregroundThreadId = ::GetWindowThreadProcessId(::GetForegroundWindow(), 0); myThreadId = GetCurrentThreadId(); if (foregroundThreadId != myThreadId) { AttachThreadInput(foregroundThreadId, myThreadId, TRUE); BringWindowToTop(myWindowHandle); If you try to step over the Attach&shy;Thread&shy;Input call in the debugger, both the debugger and the application being debugged will freeze. Why is that? This should look familiar because [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/4043","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=4043"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/4043\/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=4043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=4043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=4043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}