<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en" xmlns="http://www.w3.org/2005/Atom"><title>Recent changes to feature-requests</title><link href="https://sourceforge.net/p/asio/feature-requests/" rel="alternate"/><link href="https://sourceforge.net/p/asio/feature-requests/feed.atom" rel="self"/><id>https://sourceforge.net/p/asio/feature-requests/</id><updated>2024-09-07T11:08:54.067000Z</updated><subtitle>Recent changes to feature-requests</subtitle><entry><title>#22 Add timeout to receive_from(). </title><link href="https://sourceforge.net/p/asio/feature-requests/22/?limit=25#4ffb" rel="alternate"/><published>2024-09-07T11:08:54.067000Z</published><updated>2024-09-07T11:08:54.067000Z</updated><author><name>Lockywolf</name><uri>https://sourceforge.net/u/lockywolf/</uri></author><id>https://sourceforge.net404ed65753c9cb055aafc9e4687c2097ce0ba99a</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;I have done a bit of digging into the code.&lt;/p&gt;
&lt;p&gt;It seems that what is needed is to add a check for a timeout in &lt;code&gt;socket_ops.ipp&lt;/code&gt;, functions &lt;code&gt;sync_recv&lt;/code&gt;, &lt;code&gt;sync_recvfrom&lt;/code&gt;, &lt;code&gt;sync_recvmsg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Instead of having something like &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(;;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Try to complete the operation without blocking.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;signed_size_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;socket_ops&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bufs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Check if operation succeeded.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Check for EOF.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream_oriented&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;asio&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;eof&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Operation failed.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user_set_non_blocking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;asio&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;would_block&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;asio&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;try_again&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Wait for socket to become ready.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket_ops&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;poll_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;have something like &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;setsockopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SOL_SOCKET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SO_RCVTIMEO&lt;/span&gt;&lt;span class="p"&gt;,(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;timeval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;timeval&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;starttime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;starttime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Try to complete the operation without blocking.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;signed_size_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;socket_ops&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bufs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Check if operation succeeded.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Check for EOF.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream_oriented&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;asio&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;eof&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Operation failed.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user_set_non_blocking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;asio&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;would_block&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;asio&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;try_again&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Wait for socket to become ready.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket_ops&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;poll_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The socket option would guarantee that the loop would check condition at least once.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>#21 Configure flags while creating sockets.</title><link href="https://sourceforge.net/p/asio/feature-requests/21/?limit=25#520c" rel="alternate"/><published>2024-09-07T10:59:23.786000Z</published><updated>2024-09-07T10:59:23.786000Z</updated><author><name>Lockywolf</name><uri>https://sourceforge.net/u/lockywolf/</uri></author><id>https://sourceforge.netfc34e30bbea237e2164d925dc6d0ec8957c6d0e6</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;That is a great idea.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>Add timeout to receive_from(). </title><link href="https://sourceforge.net/p/asio/feature-requests/22/" rel="alternate"/><published>2024-09-06T00:28:51.078000Z</published><updated>2024-09-06T00:28:51.078000Z</updated><author><name>Lockywolf</name><uri>https://sourceforge.net/u/lockywolf/</uri></author><id>https://sourceforge.net27e60be367647cb331222892a4c9a3f31a46529f</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;The default example for the synchronous UDP datetime server has a chance to lock indefinitely if a datagram never arrives. Since UDP is inherently unreliable, this is not a "rare unexpected exotic obscurity", it's one of the reasons why UDP might be used.&lt;/p&gt;
&lt;p&gt;This problems is not present for TCP, since TCP has built-in failure mechanisms when a "connection" breaks. But an UDP socket doesn't have to be "connected" even in a limited UDP sense.&lt;/p&gt;
&lt;p&gt;I would like to ask that a timeout argument is added to the "receive_from" procedure.&lt;/p&gt;
&lt;p&gt;The same effect can be achieved using:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cp"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="cp"&gt;]&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;io_context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;detach&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;recv_length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;async_receive_from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;boost&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;asio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;recv_buf&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sender_endpoint&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                                                   &lt;/span&gt;&lt;span class="nt"&gt;boost&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;asio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;use_future&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;recv_length&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;wait_for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;chrono&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;seconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;5&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;future_status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recv_buf&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;recv_length&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However , this requires switching from "receive_from" to "async_receive_from" and spawning a thread, which is a giant over-kill for a simple synchronous application which is happy with losing a packet that might be outdated anyway.&lt;/p&gt;
&lt;p&gt;In plain C sockets this can be achieved by setting SO_RCVTIMEO on a socket and adding a check in the main reading loop.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>Configure flags while creating sockets.</title><link href="https://sourceforge.net/p/asio/feature-requests/21/" rel="alternate"/><published>2018-06-28T11:33:03.683000Z</published><updated>2018-06-28T11:33:03.683000Z</updated><author><name>Bhargava Srinarasi</name><uri>https://sourceforge.net/u/thelonelysaint/</uri></author><id>https://sourceforge.netb740f6908bd4aa135c891583fb59fa717cb3910c</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;On Windows, when we create tcp sockets, asio library creates a Windows socket via WSASocket in asio/detail/impl/socket_ops.ipp.&lt;/p&gt;
&lt;p&gt;WSASocket function has an option to provide some flags which changes some properties of the socket being created e.g., whether the socket is inheritable by the process' children. More details &lt;a class="" href="https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsasocketa" rel="nofollow"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It would be helpful if asio library provides an option to configure this flag.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>Ability to check that we're on a specific strand</title><link href="https://sourceforge.net/p/asio/feature-requests/20/" rel="alternate"/><published>2012-12-12T14:51:17Z</published><updated>2012-12-12T14:51:17Z</updated><author><name>Anonymous</name><uri>https://sourceforge.net/u/userid-None/</uri></author><id>https://sourceforge.neta0477d71fcd69544f7a899bf122a30909f30767e</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;It would be great to be able to code assertions into our methods that the code is being called as expected. This can also serve as useful documentation fo developers. For example:&lt;/p&gt;
&lt;p&gt;class Foo {&lt;br /&gt;
public:&lt;br /&gt;
Foo(asio::strand&amp;amp; strand) &lt;br /&gt;
: strand_(strand) {&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;void foo() {&lt;br /&gt;
assert(strand_.running()); &lt;br /&gt;
...&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;private:&lt;br /&gt;
asio::strand&amp;amp; strand_;&lt;br /&gt;
};&lt;/p&gt;
&lt;p&gt;strand::running() would return true if the strand is running in the current thread. The assertion states that foo must be called from strand_.&lt;/p&gt;
&lt;p&gt;This information is already maintained by the strand implementation. strand::dispatch() needs to know if the currently thread is executing the strand already so that it can decide whether to execute the handler immediately (on the current thread) or post it to a queue of handlers.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>support for MSG_DONTWAIT to save a few system calls</title><link href="https://sourceforge.net/p/asio/feature-requests/19/" rel="alternate"/><published>2012-09-04T08:19:58Z</published><updated>2012-09-04T08:19:58Z</updated><author><name>bastiaan</name><uri>https://sourceforge.net/u/darquan2000/</uri></author><id>https://sourceforge.net59b622d16cec8b712e3e1dfd550fa8e304e94cf6</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;We have a use case with a tcp connection pool, where we want to do a quick check if a connection is still valid before re-using it.&lt;/p&gt;
&lt;p&gt;We currently basically do it as follows (using the boost version of asio):&lt;/p&gt;
&lt;p&gt;boost::asio::ip::tcp::socket &amp;amp; s = get_socket();&lt;br /&gt;
s.non_blocking(true);&lt;br /&gt;
char buf[1];&lt;br /&gt;
s.receive(boost::asio::buffer(buf, sizeof(buf)), s.message_peek);&lt;br /&gt;
s.non_blocking(false);&lt;/p&gt;
&lt;p&gt;This nicely reports a connection that was closed by the peer, in which case we can reconnect. However, it uses a number of additional system calls to set the socket to non-blocking and back to blocking that could be eliminated on Linux, and maybe also on other OSes.&lt;/p&gt;
&lt;p&gt;Linux supports MSG_DONTWAIT. It would be nice if asio could also support this flag, if it is available. Then we could do:&lt;/p&gt;
&lt;p&gt;boost::asio::ip::tcp::socket &amp;amp; s = get_socket();&lt;br /&gt;
char buf[1];&lt;br /&gt;
s.receive(boost::asio::buffer(buf, sizeof(buf)), s.message_dontwait | s.message_peek);&lt;/p&gt;
&lt;p&gt;This would eliminate the system calls to set the socket to blocking / non-blocking.&lt;/p&gt;
&lt;p&gt;We have tried:&lt;/p&gt;
&lt;p&gt;boost::asio::ip::tcp::socket &amp;amp; s = get_socket();&lt;br /&gt;
char buf[1];&lt;br /&gt;
s.receive(boost::asio::buffer(buf, sizeof(buf)), MSG_DONTWAIT | s.message_peek);&lt;/p&gt;
&lt;p&gt;This however blocks the program. For example, the above code goes down to socket_ops::sync_recv, which has:&lt;/p&gt;
&lt;p&gt;// Operation failed.&lt;br /&gt;
if ((state &amp;amp; user_set_non_blocking)&lt;br /&gt;
|| (ec != boost::asio::error::would_block&lt;br /&gt;
&amp;amp;&amp;amp; ec != boost::asio::error::try_again))&lt;br /&gt;
return 0;&lt;/p&gt;
&lt;p&gt;But for MSG_DONTWAIT to work, sync_recv would need:&lt;/p&gt;
&lt;p&gt;// Operation failed.&lt;br /&gt;
if ((state &amp;amp; user_set_non_blocking)&lt;br /&gt;
|| (flags &amp;amp; MSG_DONTWAIT)&lt;br /&gt;
|| (ec != boost::asio::error::would_block&lt;br /&gt;
&amp;amp;&amp;amp; ec != boost::asio::error::try_again))&lt;br /&gt;
return 0;&lt;/p&gt;
&lt;p&gt;With this patch, the receive call with MSG_DONTWAIT works as expected. In socket_ops.ipp, more functions similar to sync_recv could add support MSG_DONTWAIT in this way.&lt;/p&gt;
&lt;p&gt;It would be nice to be able to use MSG_DONTWAIT with the asio API. If necessary we can go more low-level through s.native_handle().&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>iovec -&gt; buffer</title><link href="https://sourceforge.net/p/asio/feature-requests/18/" rel="alternate"/><published>2011-03-01T02:10:43Z</published><updated>2011-03-01T02:10:43Z</updated><author><name>nickfajones</name><uri>https://sourceforge.net/u/nickfajones/</uri></author><id>https://sourceforge.net1e737749d028be30e0e5a4e5606a770513b7c05a</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;The following patch allows one to use struct iovec directly as the value_type of a mutable/const buffer sequence.&lt;/p&gt;
&lt;p&gt;This need arose from the desire to use an old buffer interface, that was compatible with the readv/writev system calls, and thus provided access to its internal storage via arrays of iovecs (and a length of course)  With this patch, the buffer object is easily represented with a mutable/const buffer sequence class that provides &amp;amp;struct iovec[0] as begin() and &amp;amp;struct iovec[iov_count] as end()&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>Support of C++0x move semantic</title><link href="https://sourceforge.net/p/asio/feature-requests/17/" rel="alternate"/><published>2011-01-31T18:39:50Z</published><updated>2011-01-31T18:39:50Z</updated><author><name>Marat Abrarov</name><uri>https://sourceforge.net/u/mabrarov/</uri></author><id>https://sourceforge.net448bf6086519ab0504b03bc71a231075a4397aad</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;Any plans of using C++0x move semantic in Boost.Asio?&lt;br /&gt;
Usage of C++0x move semantic (already implemented in MSVC 10, GCC, ICC 12) can significantly reduce calls to handlers' copy constructors replacing most of them with calls to handlers' move constructors – especially at custom memory allocation support (I mean creation of local handler’s copy on the stack) – move constructors usually have resource-steal semantic which doesn’t throw (or throw rarely comparing to copy constructor).&lt;br /&gt;
Compare copy constructor and move constructor of boost::shared_ptr which is often used with Boost.Asio. It is the most often called function when using “shared_from_this()”-approach and its usage of CAS can significantly degrade performance in multi-threaded application (at modern multi-core/multi-processor systems).&lt;br /&gt;
It would be very interesting to compare performance (take “echo_server” project from &lt;a href="https://sourceforge.net/projects/asio-samples/\"&gt;https://sourceforge.net/projects/asio-samples/\&lt;/a&gt;) of different versions of Boost.Asio – without move semantic support and with it.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>Delay SSL initialization</title><link href="https://sourceforge.net/p/asio/feature-requests/16/" rel="alternate"/><published>2009-07-21T08:49:00Z</published><updated>2009-07-21T08:49:00Z</updated><author><name>Anonymous</name><uri>https://sourceforge.net/u/userid-None/</uri></author><id>https://sourceforge.net483be03a4eac968a5cc5f9c2e2bd43ff9bad6ac1</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;When SSL header are included, ASIO tries to initialize SSL on application startup (class openssl_init). This approach makes impossible delayed loading of SSL dll's (/DELAYLOAD option with MSVC linker), which would allow to deliver an application without SSL dll's, if SSL-related features are not really used.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>DCCP support</title><link href="https://sourceforge.net/p/asio/feature-requests/15/" rel="alternate"/><published>2009-04-14T06:11:58Z</published><updated>2009-04-14T06:11:58Z</updated><author><name>Alexander Dubov</name><uri>https://sourceforge.net/u/oakad/</uri></author><id>https://sourceforge.netadfb63e9faf1420dba3e0637fb6e0184b94f0229</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;DCCP is a connected datagram protocol (IPPROTO_DCCP) which provides connection management in situations where UDP will be too low-level, but full overhead of TCP is not required. It also makes firewall configuration for datagram based protocols considerably easier.&lt;/p&gt;&lt;/div&gt;</summary></entry></feed>