title: Using boost::asio async model for socket reads, multiple threads
body: <p>I have a case where my app main thread (thread 1) must run unblocked.  It needs to receive streaming data over a socket...and the data will be continuously arriving over time from the remote server.  I have limited control over thread 1 (this is plugin type of software into a larger host application that is providing thread 1).  </p>
  
  <p>So, I get called on thread 1 with a pointer to a buffer in which to put the data.  If there is no incoming data from the socket, I can just write zeros.  There needs to be at least X bytes of data to fill the buffer I'm given.  If there is not at least X bytes in the socket buffer (more on this later), then again I can fill it with zeros.</p>
  
  <p>Due to the limited control I have over thread 1, I believe I must have a thread 2 to handle the socket interface (agree?).  Let say I create that thread and set it up much like the boost::asio async TCP <a href="http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp" rel="nofollow">server</a>.  Focusing on the incoming "read" side of this example, consider something like this where I've created an endless "reader" (until I kill io_socket or thread 2 or some such).</p>
  
  <pre><code>void do_read()
    {
      auto self(shared_from_this());
      socket_.async_read_some(boost::asio::buffer(data_, max_length),
          [this, self](boost::system::error_code ec, std::size_t length)
          {
            if (!ec)
            {
              do_read();
            }
          });
    }
  </code></pre>
  
  <p>It is piling data into data_ - a simple static array for the buffer.  Since I don't know exactly how much buffering will be required, I'm considering instead a vector type of implementation.  It seems the boost way to do this is to use the boost::asio::streambuf - which resizes and operates in a FIFO fashion (important because I want my incoming data to stay ordered).  It also has the concept of an input sequence and an output sequence.  My goal is to use this...where thread 2 will be putting data into the output sequence by way of the code above, and thread 1 will be reading data from the input sequence when runs and finds that it has more than X bytes.  The streambuf-internal copy from output to input is done with commit().  But my understanding is that the boost::asio::streambuf is not generally thread safe.  One could wrap all access to the streambuf (either input or output sequence) with a lock to solve the problem, but on the socket side...that lock would have to be held between async_read_some and do_read, because it accesses the streambuf at some point in between.  I think that will be state that thread 2 will be in "most of the time", and so the lock is very limiting on thread 1 (and again thread 1 cannot block so it would have to "try" the lock and rarely get it).</p>
  
  <p>It seems like boost::asio::streambuf should be safe for one thread to access the output sequence while another is accessing the input sequence (?).  I would expect the only point of contention to be commit().  If I had control over commit (and it is not clear that I do...I think possibly async_read does it automatically?) then I could just lock around commit.</p>
  
  <p>Is there any way to do what I am trying to do?  Admittedly, I'm possibly too focused on minimizing copies.  If I allow another copy, then it seems like another thread locked buffer/queue (thread_buf) could be created between thread 1 and 2...where do_read could lock, copy from streambuf to thread_buf, unlock, async_read...etc.  Thread 1 would do lock, if thread_buf has enough data copy it out, unlock.</p>