{"id":104955,"date":"2021-03-12T07:00:00","date_gmt":"2021-03-12T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104955"},"modified":"2021-03-12T07:17:33","modified_gmt":"2021-03-12T15:17:33","slug":"20210312-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210312-00\/?p=104955","title":{"rendered":"Creating other types of synchronization objects that can be used with co_await, part 4: The manual-reset event"},"content":{"rendered":"<p>Now that we&#8217;ve finished <a title=\"Creating other types of synchronization objects that can be used with co_await, part 3: Parallel resumption\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210311-00\/?p=104949\"> our library for building awaitable synchronization objects<\/a>, let&#8217;s actually use it.<\/p>\n<p>The introduction to this part of the series began with a demonstrate of a one-shot event. So let&#8217;s take it a step further and make it a resettable event.<\/p>\n<pre>struct awaitable_manual_reset_event_state :\r\n    async_helpers::awaitable_state&lt;awaitable_manual_reset_event_state&gt;\r\n{\r\n    <span style=\"color: blue;\">awaitable_manual_reset_event_state(bool initial)\r\n    : signaled(initial) {}<\/span>\r\n\r\n    std::atomic&lt;bool&gt; signaled;\r\n\r\n    bool fast_claim(extra_await_data const&amp;) const noexcept\r\n    {\r\n        return signaled.load(std::memory_order_acquire);\r\n    }\r\n\r\n    bool claim(extra_await_data const&amp;) const noexcept\r\n    {\r\n        return signaled.load(std::memory_order_relaxed);\r\n    }\r\n\r\n    void set(node_list&amp; list) noexcept\r\n    {\r\n        signaled.store(true, std::memory_order_relaxed);\r\n        resume_all(list);\r\n    }\r\n};\r\n\r\nstruct awaitable_manual_reset_event\r\n    : async_helpers::awaitable_sync_object&lt;\r\n        awaitable_manual_reset_event_state&gt;\r\n{\r\n    <span style=\"color: blue;\">awaitable_manual_reset_event(bool initial = false) :\r\n        awaitable_sync_object(initial) { }<\/span>\r\n\r\n    void set() noexcept\r\n    {\r\n        action_impl(&amp;state::set);\r\n    }\r\n\r\n    <span style=\"color: blue;\">void reset() noexcept\r\n    {\r\n        get_state().signaled.store(false,\r\n            std::memory_order_release);\r\n    }<\/span>\r\n};\r\n<\/pre>\n<p>The manual reset event is basically the same as the one-shot event, except that you can also specify the initial signal state, and you can reset it as well as set it. The reset is done with release semantics, so that anything which was dependent upon the release will observe the changes that occurred prior to the release. (I&#8217;m not sure how you could actually rely on this, since the release doesn&#8217;t signal anything, and all awaits will block on an unsignaled event, but I&#8217;m doing it just in case.)<\/p>\n<p>Well, that was a bit anticlimactic. That&#8217;s okay, we&#8217;ll make up for it next time, when we look at auto-reset events.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The asynchronous manual reset event.<\/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-104955","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The asynchronous manual reset event.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104955","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=104955"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104955\/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=104955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}