<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>Merge most of Networking TS into C++ Working Draft</title>
  <style type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">Merge most of Networking TS into C++ Working Draft</h1>
</header>
<table>
<tbody>
<tr class="odd">
<td>Doc. No.:</td>
<td>D1259R1</td>
</tr>
<tr class="even">
<td>Date:</td>
<td>2018-11-04</td>
</tr>
<tr class="odd">
<td>Reply to:</td>
<td>Detlef Vollmann, dv@vollmann.ch</td>
</tr>
<tr class="even">
<td>Audience:</td>
<td>SG1, LEWG, WG21</td>
</tr>
</tbody>
</table>
<h1 id="merge-most-of-networking-ts-into-c-working-draft">Merge most of Networking TS into C++ Working Draft</h1>
<h2 id="introduction">Introduction</h2>
<p>The Networking TS grew out of Boost::ASIO and has got a lot of usage experience as part of Boost and in standalone implementations of the TS. Most of the Networking TS is uncontroversial.</p>
<p>One specific part of the Networking TS however clashes with the executor work in SG1. The executor work from SG1 is not yet ready to be merged into the C++ working paper. So this part of the Networking TS should not be merged. But most of the Networking TS can work without an explicitly specified executor model. This paper proposes to merge the executor independent parts of the Networking TS into the C++ working paper and solve any open issues on the Networking TS inside the C++ working paper.</p>
<h2 id="functionality-to-be-merged">Functionality to be Merged</h2>
<p>Without the executor parts not all of the functionality of the TS will be available from the specification in the C++ WD.</p>
<p>This section tries to provide an overview of what functionality is merged and what is left out.</p>
<h3 id="summary">Summary</h3>
<p>The Networking TS can be viewed as three separate parts:</p>
<ul>
<li>the actual networking, consisting e.g. of the sockets and IP protocol,</li>
<li>a model for asynchronous operations based on continuations, and</li>
<li>an interface for executors to run the continuations on.</li>
</ul>
<p>This proposal merges all of the actual networking part, most of the continuation part (not <code>uses_future</code>) and nothing of the executor part.</p>
<p>Defining own execution contexts (based on <code>io_context</code>) is not available with the proposed subset and using <code>strand</code> is also not possible, but all of the networking operations (synchronous and asynchronous) are merged.</p>
<h3 id="details">Details</h3>
<p>I have myself not worked with any implementation of the Networking TS but with <code>boost::asio</code> and Chris Kohlhoff’s ASIO implementation available at <a href="http://github.com/chriskohlhoff/asio" class="uri">http://github.com/chriskohlhoff/asio</a> (because they provide useful additional functionality for Posix systems). Of the real applications (not toy projects to try some features) most would be possible with the proposed subset, but not all of them.</p>
<p>But to look at the features in more detail, I’ll use the examples from Chris in his <a href="http://github.com/chriskohlhoff/asio">github repo</a>.</p>
<h3 id="get_executor"><code>get_executor</code></h3>
<p>When looking though Chris’ examples most of them work completely within the subset to be merged. Of those examples that don’t work without change most would fail because the use of <code>get_executor()</code>. Some of the calls to <code>get_executor()</code> are probably just out of habit (e.g. in the constructor of <code>server</code> in cpp03/porthopper/server.cpp), others are to avoid storing a reference or pointer to the <code>io_context</code> in an object if it’s already stored inside of e.g. an <code>acceptor</code> subobject anyway. These examples could simply be rewritten not to use <code>get_executor()</code> without change in functionality (though at the cost of an additional pointer inside the objects).</p>
<p>Calls that can’t be rewritten without affecting the functionality are the cases where there actually are multiple executors and it’s important to pick the right one. Probably the only important case here is <code>strand</code>.</p>
<h3 id="strand"><code>strand</code></h3>
<p>The Networking TS provides a class <code>strand</code> to serialize specific I/O operations based on <code>io_context</code> if <code>io_context</code> itself uses multiple threads.</p>
<p><code>strand</code> is used in several examples. One of them is a multithreaded HTTP server in cpp03/http/server3. (Please note that the actual interface for <code>strand</code> differ between Chris’ implementation and the Networking TS, but the semantics are the same).</p>
<p><code>strand</code> is an executor and as such not part of the proposed subset.</p>
<h3 id="post"><code>post</code></h3>
<p>As being part of the main executor interface, <code>post()</code> is also not part of the proposed subset.</p>
<p>From a network perspective <code>post()</code> can be used to execute arbitrary functions asynchronously. One example that uses this is cpp03/chat/chat_client.cpp, which uses <code>post()</code> to put the actual function invocation in the queue at a more appropriate place. The example could be simply rewritten to not use <code>post()</code> without loss of functionality.</p>
<p>Another example is cpp03/serialization/connection.hpp, where <code>post()</code> is used to raise an error asynchronously.</p>
<h3 id="own-executor">Own executor</h3>
<p>The only example that uses a custom executor in a networking environment is invocation/prioritised_handlers.cpp. This is an example for which the executor interface of the Networking TS exists and therefore is not part of the proposed subset.</p>
<h3 id="breakdown">Breakdown</h3>
<p>Most examples just work, for others (<code>get_executor()</code>) some modifications are required. But of course, some functionality is not possible with the proposed subset.</p>
<p>The purpose of this proposal is to provide as much functionality as possible without interfering with any future executor interface in C++. <code>post()</code> and <code>get_executor()</code> in a minimal version would probably not cause any trouble for future executors.</p>
<p><code>strand</code> in it’s current form definitely interferes. While it’s a convenient mechanism to make network applications scalable on parallel hardware, essentially the same effect can be implemented manually. Should a convenient synchronization mechanism be required now, something like a stripped down version of <code>strand</code> inside <code>io_context</code> might be possible without having too much inconsistency in future versions of C++.</p>
<h2 id="wording-overview">Wording Overview</h2>
<p>The proposal is to merge the Networking TS into the C++ working paper with the following changes:</p>
<ul>
<li><p>Move the contents of the namespace <code>std::experimental</code> to namespace <code>std</code>.</p></li>
<li><p>Rename the headers <code>&lt;experimental/*&gt;</code> to <code>&lt;*&gt;</code>.</p></li>
<li><p>From table 3 remove <code>ExecutionContext</code> and <code>Executor</code>.</p></li>
<li>From header <code>&lt;netfwd&gt;</code> ([fwd.decl.synop]) remove:
<ul>
<li><code>executor_binder</code></li>
<li><code>executor_work_guard</code></li>
<li><code>system_executor</code></li>
<li><code>executor</code></li>
<li><code>strand</code>.</li>
</ul></li>
<li>From header <code>&lt;executor&gt;</code> ([async]) remove all but:
<ul>
<li><code>async_result</code>, but remove specializations with <code>use_future_t</code> and <code>packaged_task</code></li>
<li><code>async_completion</code></li>
<li><code>associated_allocator</code></li>
<li><code>associated_allocator_t</code></li>
<li><code>get_associated_allocator</code></li>
<li><code>fork_event</code></li>
<li><code>uses_allocator</code>.</li>
<li>Also remove the respective specifications.</li>
</ul></li>
</ul>
<ul>
<li>From [async.reqmts] remove:
<ul>
<li>[async.reqmts.executor]</li>
<li>[async.reqmts.executioncontext]</li>
<li>[async.reqmts.service]</li>
<li>[async.reqmts.async.assoc.exec]</li>
<li>[async.reqmts.async.io.exec]</li>
<li>[async.reqmts.async.handler.exec]</li>
<li>[async.reqmts.async.work]</li>
<li>[async.reqmts.async.completion]</li>
<li>[async.reqmts.async.exceptions]</li>
<li>[async.reqmts.async.composed].</li>
</ul></li>
<li><p>From [async.reqmts.async]p1 remove <code>Executor1</code>, <code>Executor2</code>, <code>ex1</code>, <code>ex2</code>, <code>work1</code> and <code>work2</code>.</p></li>
<li>From class <code>io_context</code> ([io__context]) remove:
<ul>
<li>the public base class <code>execution_context</code></li>
<li><code>executor_type</code></li>
<li><code>get_executor</code></li>
<li>paragraphs 1, 2, 4.1 and 4.2.</li>
</ul></li>
<li><p>In class <code>io_context</code> ([io__context]) change paragraph 6 remove <code>get_executor,</code> and “, and the <code>io_context::executor_type</code> copy constructors, member functions and comparison operators,”.</p></li>
<li><p>Remove [io__context.exec].</p></li>
<li>From <code>basic_waitable_timer</code> ([timer.waitable]),<br />
<code>basic_socket</code> ([socket.basic]),<br />
<code>basic_socket_acceptor</code> ([socket.acceptor]),<br />
and <code>ip::basic_resolver</code> ([internet.resolver]) remove:
<ul>
<li><code>executor_type</code></li>
<li><code>get_executor</code></li>
<li>from the constructors and assignment the postcondition about <code>get_executor</code></li>
</ul></li>
<li><p>From table 17 ([buffer.stream.reqmts.asyncreadstream]) and table 19 ([buffer.stream.reqmts.asyncwritestream]) remove the <code>get_executor</code> requirement.</p></li>
<li><p>In <code>basic_socket_acceptor</code> ([socket.acceptor]) in the <code>accept</code> functions that don’t take an <code>io_context&amp;</code> as argument replace in the Returns clause <code>get_executor().context()</code> with <code>io_context()</code>.</p></li>
</ul>
</body>
</html>
