{"id":97075,"date":"2017-09-25T07:00:00","date_gmt":"2017-09-25T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=97075"},"modified":"2019-03-13T01:18:13","modified_gmt":"2019-03-13T08:18:13","slug":"20170925-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170925-00\/?p=97075","title":{"rendered":"What happens if I wake a condition variable when nobody is waiting for it? Is the wake saved for the next thread that waits?"},"content":{"rendered":"<p>Suppose you call <a HREF=\"https:\/\/msdn.microsoft.com\/library\/windows\/desktop\/ms687080(v=vs.85).aspx\"><code>Wake&shy;Xxx&shy;Condition&shy;Variable<\/code><\/a> to wake a <code>CONDITION_<\/code><code>VARIABLE<\/code><\/a>, but nobody is waiting on the condition variable. What happens? In particular, is the wake saved for the next thread that waits, so the next call to <code>Sleep&shy;Condition&shy;Variable&shy;Xxx<\/code> returns immediately instead of waiting? <\/p>\n<p>The answer is, &#8220;It shouldn&#8217;t matter.&#8221; <\/p>\n<p>The <a HREF=\"https:\/\/msdn.microsoft.com\/library\/windows\/desktop\/ms682052(v=vs.85).aspx\">intended use pattern for a condition variable<\/a> is to do the following: <\/p>\n<ol>\n<li>Enter a lock.<\/li>\n<li>Check a condition.<\/li>\n<li>If the condition is false, then call     <code>Sleep&shy;Condition&shy;Variable&shy;Xxx<\/code>     and then go to step 2.     <\/li>\n<li>Perform an operation.<\/li>\n<li>Release the lock.<\/li>\n<\/ol>\n<p>And the code that establishes the condition (or at least changes the condition so it might be true for at least one waiter) calls <code>Wake&shy;Xxx&shy;Condition&shy;Variable<\/code>. <\/p>\n<p>If you follow this pattern, then it doesn&#8217;t matter whether a call to <code>Wake&shy;Xxx&shy;Condition&shy;Variable<\/code> is remembered when there are no waiting threads. According to the intended use pattern, a thread is expected to check the condition first, and only if the condition is false should the thread call <code>Sleep&shy;Condition&shy;Variable&shy;Xxx<\/code>. Whether the wake is remember or not is irrelevant because the waiting thread never actually waits! <\/p>\n<p>In other words, if you are counting on an unnecessary wake being saved and waking up a future sleep, then that means that you went to sleep before checking the condition. (Because if you had checked the condition, you would have avoided the sleep.) <a HREF=\"http:\/\/youreholdingitwrong.org\/\">You&#8217;re holding it wrong<\/a>. <\/p>\n<p>Conversely, if you didn&#8217;t expect the unnecessary wake to be remembered, but you got one anyway, well, that&#8217;s also permitted because condition variables are explicitly documented as subject to spurious wakes. Again, if you follow the intended use pattern, spurious wakes aren&#8217;t a problem (aside from performance) because the recommended pattern is to re-check the condition after the sleep wakes. If the wake were spurious, the check would fail, and you would go back to sleep. <\/p>\n<p>In summary, if you wake a condition variable when nobody is waiting for it, it is unspecified whether the wake is saved for the next thread that waits, and that&#8217;s okay, because if you follow the intended use pattern, it doesn&#8217;t matter. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>It shouldn&#8217;t matter.<\/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-97075","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It shouldn&#8217;t matter.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97075","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=97075"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97075\/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=97075"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=97075"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=97075"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}