{"id":97825,"date":"2018-01-18T07:00:00","date_gmt":"2018-01-18T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=97825"},"modified":"2019-03-13T01:02:44","modified_gmt":"2019-03-13T08:02:44","slug":"20180118-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20180118-00\/?p=97825","title":{"rendered":"A helper template function to wait for WaitOnAddress in a loop"},"content":{"rendered":"<p>The <code>Wait&shy;On&shy;Address<\/code> function suffers from the problem of <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20160826-00\/?p=94185\">spurious wake-ups<\/a>. This means that most uses of the <code>Wait&shy;On&shy;Address<\/code> function are of the form &#8220;while the value is bad, wait for it to change.&#8221; <\/p>\n<p>There is a subtlety here, because you have to  capture the value, then make your decision based on the captured value, and if you decide that you want to wait some more, you need to pass the captured value to <code>Wait&shy;On&shy;Address<\/code>. The extra capturing is necessary to avoid a race condition if you determine that the value is bad, but before you can call <code>Wait&shy;On&shy;Address<\/code>, the value becomes good. <\/p>\n<p>Here&#8217;s a simple helper function to encapsulate the loop: <\/p>\n<pre>\ntemplate&lt;typename T, typename TLambda&gt;\nvoid WaitForValueByAddress(T&amp; value, TLambda&amp;&amp; is_okay)\n{\n  auto capturedValue = value;\n  while (!is_okay(capturedValue)) {\n    WaitOnAddress(&amp;value, &amp;capturedValue, sizeof(value), INFINITE);\n    capturedValue = value;\n  }\n}\n<\/pre>\n<p>The assumption here is that <code>T<\/code> is a simple value type like <code>int32_t<\/code>. If you pass a funky class, then we&#8217;re going to be copying it, which is probably a bad idea given that the variable is going to be asynchronously modified (possibly while we are copying it). <\/p>\n<p>The predicate evaluates the value: Return <code>true<\/code> if it acceptable, or return <code>false<\/code> to reject it and wait some more. <\/p>\n<p>Here&#8217;s a sample usage: <\/p>\n<pre>\nint32_t someValue;\n\nvoid WaitForValueToBecomeZero()\n{\n  WaitForValueByAddress(someValue, [](auto&amp;&amp; v) { return v == 0; });\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Because this is what you always have to do.<\/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-97825","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Because this is what you always have to do.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97825","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=97825"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97825\/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=97825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=97825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=97825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}