{"id":1981,"date":"2014-02-12T13:00:17","date_gmt":"2014-02-12T13:00:17","guid":{"rendered":"http:\/\/writeasync.net\/?p=1981"},"modified":"2014-02-11T09:58:56","modified_gmt":"2014-02-11T09:58:56","slug":"porting-inputqueue-to-c","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=1981","title":{"rendered":"Porting InputQueue to C++"},"content":{"rendered":"<p>In the <a href=\"http:\/\/writeasync.net\/?p=1901\" title=\"Async in C++ with the PPL\">previous post<\/a>, I gave a brief intro to the PPL and the basic constructs for writing async C++ code. In this post, I will discuss the highlights of how I ported the <a href=\"http:\/\/writeasync.net\/?p=1511\" title=\"InputQueue, the non-BlockingCollection\">InputQueue sample<\/a> to C++ using the PPL and TDD. The code is available on GitHub: <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commits\/master\/projects\/NativeQueueSample\">NativeQueueSample commit history<\/a>.<\/p>\n<p>My C++ TDD tool of choice is the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh598953.aspx\">Microsoft Unit Testing Framework for C++<\/a>. The main selling point is its smooth integration with Visual Studio &#8212; even the Express edition. You just create a Native Unit Test Project, create a wrapping TEST_CLASS and some TEST_METHOD functions and you&#8217;re done. Note that with the Express edition, you cannot set the tests to run automatically after each build. However, you can do as I did and create a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/h7dhf0ty.aspx\">Post-Build Event<\/a> to run the tests. You won&#8217;t get the nice integration with Test Explorer but I like it better than manually triggering tests. The command line should look something like this: <code>\"$(VSInstallDir)Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe\" \"$(TargetPath)\" \/Platform:x64 \/inIsolation<\/code><\/p>\n<p>The first thing to watch out for when writing unit tests for async C++ code: don&#8217;t double fault! I learned this the hard way when the test runner inexplicably hung after running my very first test:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nTEST_METHOD(Dequeue_completes_after_enqueue)\r\n{\r\n    InputQueue&lt;wstring&gt; queue;\r\n\r\n    task&lt;wstring&gt; task = queue.DequeueAsync();\r\n\r\n    Assert::IsFalse(task.is_done());\r\n\r\n    queue.Enqueue(wstring(L&quot;a&quot;));\r\n\r\n    Assert::IsTrue(task.is_done());\r\n    Assert::AreEqual(wstring(L&quot;a&quot;), task.get());\r\n}\r\n<\/pre>\n<p>Seems simple enough. However, my implementation code, being just a stub, looked like this:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid Enqueue(T item)\r\n{\r\n    throw std::runtime_error(&quot;Not implemented.&quot;);\r\n}\r\n\r\nconcurrency::task&lt;T&gt; DequeueAsync()\r\n{\r\n    return concurrency::task_from_exception&lt;T&gt;(runtime_error(&quot;Not implemented.&quot;));\r\n}\r\n<\/pre>\n<p>It turns out that the first <code>Assert::IsFalse<\/code> was failing (expected, since I&#8217;m completing <code>DequeueAsync<\/code> immediately with an exception), which ended up throwing an exception (expected for any assertion failure), which ended up unwinding the stack and destroying the <code>task<\/code> object, which ended up failing due to the fact that the original exception was unobserved. To avoid this, I came up with an <code>AssertTaskPending<\/code> helper:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ntemplate &lt;typename T&gt;\r\ntask&lt;T&gt; &amp; AssertTaskPending(task&lt;T&gt; &amp; task)\r\n{\r\n    if (task.is_done())\r\n    {\r\n        \/\/ Before asserting, force rethrow of exception if task finished with error.\r\n        \/\/ Otherwise, we run the risk of a &quot;double fault&quot; due to an unobserved task\r\n        \/\/ error, which can end up hanging the VS test executor.\r\n        Logger::WriteMessage(L&quot;Task completed unexpectedly.&quot;);\r\n        task.get();\r\n    }\r\n\r\n    Assert::IsFalse(task.is_done());\r\n    return task;\r\n}\r\n<\/pre>\n<p>Ensuring that we call <code>get()<\/code> before asserting will avoid the issue.<\/p>\n<p>The unit tests ended up looking quite similar to the C# implementation. The actual implementation code, however, had a few minor differences worth pointing out.<\/p>\n<p>To properly represent the case where there is no pending dequeue operation, I needed to make it possible to have a <code>null<\/code> value for the <code>task_completion_event<\/code>. In modern C++, this suggests the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh279674.aspx\">use of smart pointers<\/a> &#8212; specifically, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee410601.aspx\"><code>unique_ptr<\/code><\/a> since there is only a single owner of the resource (the <code>InputQueue<\/code> itself).<\/p>\n<p>C++ has deterministic destruction. Unlike the C# implementation where we had to implement <code>IDisposable<\/code> and do some handling of still-active tasks, the chained destruction of <code>InputQueue<\/code>&#8216;s <code>task_completion_event<\/code> conveniently takes care of all of this automatically. Note that tasks that are canceled in this fashion throw <a href=\"hh750106\"><code>task_canceled<\/code><\/a>.<\/p>\n<p>Despite these minor details, <code>InputQueue<\/code> in C++ is largely identical to its managed counterpart. In the next post, I will talk about some thread-safety considerations and the integration test.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post, I gave a brief intro to the PPL and the basic constructs for writing async C++ code. In this post, I will discuss the highlights of how I ported the InputQueue sample to C++ using the&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,101,41],"tags":[],"class_list":["post-1981","post","type-post","status-publish","format-standard","hentry","category-async","category-native","category-tdd"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/1981","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1981"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/1981\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1981"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1981"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1981"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}