{"id":96395,"date":"2017-06-14T07:00:00","date_gmt":"2017-06-14T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96395"},"modified":"2019-03-13T01:12:51","modified_gmt":"2019-03-13T08:12:51","slug":"20170614-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170614-00\/?p=96395","title":{"rendered":"Creating a manual-reset event from WaitOnAddress"},"content":{"rendered":"<p>Last time, we <!-- backref: Creating a semaphore from WaitOnAddress -->created a semaphore with a maximum count from <code>Wait&shy;On&shy;Address<\/code><\/a>. Related to semaphores are events, so let&#8217;s do a manual-reset event. <\/p>\n<pre>\nstruct ALT_MEVENT\n{\n  LONG State;\n};\n\nvoid InitializeAltManualEvent(ALT_MEVENT* Event,\n                              bool InitialState)\n{\n  Semaphore-&gt;State = InitialState;\n}\n\nvoid SetAltManualEvent(ALT_MEVENT* Event)\n{\n if (InterlockedCompareExchange(&amp;Event-&gt;State,\n                                true, false) == false) {\n  WakeByAddressAll(&amp;Event-&gt;State);\n }\n}\n\nvoid ResetAltManualEvent(ALT_MEVENT* Event)\n{\n InterlockedCompareExchange(&amp;Event-&gt;State,\n                            false, true);\n}\n\nvoid WaitForAltManualEvent(ALT_MEVENT* Event)\n{\n while (!Event-&gt;State) {\n  LONG Waiting = 0;\n  WaitOnAddress(&amp;Event-&gt;State,\n                &amp;Waiting,\n                sizeof(Waiting),\n                INFINITE);\n }\n}\n<\/pre>\n<p>To set the event, we try to transition it from <code>false<\/code> to <code>true<\/code>. If that succeeds, then we wake anybody who was waiting for the event. (If it fails, then it means that the event was already set, so there is nothing to do.) Similarly, to reset the event, we try to transition it from <code>true<\/code> to <code>false<\/code>. In this case, there is no need to signal that the value changed because there will never be anyone waiting for the state to change to <code>false<\/code>. <\/p>\n<p>To wait for the event, we check whether it is currently set. If not, then we use <code>Wait&shy;On&shy;Address<\/code> to wait for its state to change. When we think its state may have changed, we go back and check. <\/p>\n<p>Pretty simple. Next time, the auto-reset event. <\/p>\n<p><b>Bonus chatter<\/b>: Although this usage pattern doesn&#8217;t have anybody waiting for the state to change to <code>false<\/code>, you can imagine a case where you want some type of synchronization object that signals when something becomes unavailable. For example, you might want one side to run as long as the event is signaled, and the other side to run as long as the event is unsignaled. The traditional way is to have a pair of events, and alternately signal them. But with <code>Wait&shy;On&shy;Address<\/code>, we can combine them into a single synchronization object. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>A diversion, in the form of a different exercise.<\/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-96395","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A diversion, in the form of a different exercise.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96395","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=96395"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96395\/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=96395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}