{"id":21453,"date":"2008-07-28T10:00:00","date_gmt":"2008-07-28T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/07\/28\/how-can-sigint-be-safely-delivered-on-the-main-thread\/"},"modified":"2008-07-28T10:00:00","modified_gmt":"2008-07-28T10:00:00","slug":"how-can-sigint-be-safely-delivered-on-the-main-thread","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080728-00\/?p=21453","title":{"rendered":"How can SIGINT be safely delivered on the main thread?"},"content":{"rendered":"<p><P>\nCommenter\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/pages\/407234.aspx#524742\">\nAnotherMatt<\/A> wonders why Win32 console programs deliver console\nnotifications on a different thread.\nWhy doesn&#8217;t it deliver them on the main thread?\n<\/P>\n<P>\nActually, my question is the reverse.\nWhy does unix deliver it on the main thread?\nIt makes it\n<A HREf=\"https:\/\/www.securecoding.cert.org\/confluence\/display\/seccode\/SIG31-C.+Do+not+access+or+modify+shared+objects+in+signal+handlers\">\nnearly impossible to do anything of consequence\ninside the signal handler<\/A>.\nThe main thread might be inside the heap manager (holding the heap\ncritical section) when the signal is raised.\nIf the signal handler tried to access the heap, it would deadlock\nwith itself if you&#8217;re lucky, or just corrupt the heap if you aren&#8217;t.\n<\/P>\n<P>\nFor example, consider this signal handler:\n<\/P>\n<PRE>\nvoid catch_int(int sig_num)\n{\n    \/* re-set the signal handler again to catch_int, for next time *\/\n    signal(SIGINT, catch_int);\n    \/* and print the message *\/\n    printf(&#8220;Don&#8217;t do that&#8221;);\n    fflush(stdout);\n}\n<\/PRE>\n<P>\nWhat happens if the signal is raised while the main program is\nexecuting its own <CODE>fflush<\/CODE>, say after it had already\nflushed half the buffer?\nIf two threads called <CODE>fflush<\/CODE>, the second caller would\nwait for the first to complete.\nBut here, it&#8217;s all coming from within the same thread;\nthe second caller can&#8217;t wait for the first caller to return,\nsince the first caller can&#8217;t run until the second caller returns!\n<\/P>\n<P>\n(Note also that this signal handler potentially modifies <CODE>errno<\/CODE>,\nwhich can lead to &#8220;impossible&#8221; bugs in the main program.)\n<\/P>\n<P>\nWin32 doesn&#8217;t believe in interrupt user-mode code with other\nuser-mode code asynchronously because it makes it impossible to reason\nabout the state of the process.\nDelivering the console notification on a second\nthread means that if the second thread tries to access the heap\nwhile the first thread is inside the heap manager,\nthe second thread will dutifully wait for the heap to stabilize\nbefore it goes ahead and starts mucking with it.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Commenter AnotherMatt wonders why Win32 console programs deliver console notifications on a different thread. Why doesn&#8217;t it deliver them on the main thread? Actually, my question is the reverse. Why does unix deliver it on the main thread? It makes it nearly impossible to do anything of consequence inside the signal handler. The main thread [&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":[26],"class_list":["post-21453","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Commenter AnotherMatt wonders why Win32 console programs deliver console notifications on a different thread. Why doesn&#8217;t it deliver them on the main thread? Actually, my question is the reverse. Why does unix deliver it on the main thread? It makes it nearly impossible to do anything of consequence inside the signal handler. The main thread [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21453","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=21453"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21453\/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=21453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}