Note that there are some explanatory texts on larger screens.

plurals
  1. POstd::string messed up when using it as storage within (boost.)async_read_some
    primarykey
    data
    text
    <p>I am using async_read_some to read data from a port that is saved in a char[] called _data. Its buffer size is big enough for every request:</p> <pre><code>void start() { socket_.async_read_some(boost::asio::buffer(data_,BUFFERSIZE),make_custom_alloc_handler(allocator_,boost::bind(&amp;attentionSession::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); } void handle_read(const boost::system::error_code&amp; error, size_t bytes_transferred) { string ip = socket_.remote_endpoint().address().to_string(); log-&gt;processData(data_,ip,"memory"); strcpy(data_,""); } </code></pre> <p>processData adds some additional information (like timestamp etc.) to the request by copying it to another newly alloced char*. Then this char[] is sent to writeToMemory(char*) to append that char* to the std::string memoryBuffer:</p> <pre><code>void writeCacheToFile() { // This function writes buffer data to the log file char* temp = new char[memoryBuffer.length() + 1]; strcpy(temp, memoryBuffer.c_str()); writeToFile(temp); delete[] temp; memoryBuffer.clear(); } void writeToMemory(char* data) { int maxSize = 1024; // Checks if char* data would 'fit' into the pre-defined maxSize if ((strlen((const char*)data) + memoryBuffer.length()) &gt;= maxSize) { writeCacheToFile(); // If not the cache memoryBuffer is saved first } memoryBuffer.append((const char*) data); cout &lt;&lt; memoryBuffer.length() &lt;&lt; endl; } </code></pre> <p>It works but if there are constantly requests (bombarding it with requests) things get messed up. As you can see above in the writeToMemory() function I'll added a line to print out the current length of memoryBuffer and this is where I think it has somethings to do with thread safety of std::strings:</p> <pre><code>96 188 284 3639 94 190 286 2591 102 198 294 388 484 2591 96 2591 96 190 286 2591 </code></pre> <p>The length of each (processed by processData()) request is 96 characters. But here the length of memoryBuffer just rises and falls down - some lengths are even bigger than maxSize (1024 chars).</p> <p><strong>EDIT:</strong> Sam pointed out I should add some more code. This is how I start the io_service:</p> <pre><code>boost::asio::io_service ioService; boost::scoped_ptr&lt;boost::thread&gt; ioServiceThread; server_class server (ioService,PORT); // Create server instance ioServiceThread.reset (new boost::thread ( boost::bind ( &amp;boost::asio::io_service::run, &amp;ioService ) ) ); // Only one threaded io_service (to receive user inputs in main() function) </code></pre> <p>And this is the async_acceptor's function after completing a request:</p> <pre><code>typedef boost::shared_ptr&lt;session_class&gt; session_ptr; void handleAccept(session_ptr thisSession, const boost::system::error_code&amp; error) { if (!error) { thisSession-&gt;start(); // Calls the start() function above thisSession.reset(new session(ioService,LOGGING_CLASS)); acceptor.async_accept(thisSession-&gt;socket(),boost::bind(&amp;server_class::handleAccept, this, thisSession, PLACEHOLDER_ERROR)); } } </code></pre> <p>The session_class holds the functions start() and handle_read(x,y) mentioned above. LOGGING_CLASS provides the class to write log files (holds the functions writeCacheToFile() and writeToMemory(char*)). log (mentioned above) is a kind of this class.</p> <p><strong>EOE: END OF EDIT</strong></p> <p>If I try to fix outsource the caching part (appending received char* to std::string) with boost::threads it ends up with a totally mixed up memoryBuffer</p> <p>Is it really the thread safety of std::strings or something else I missed?</p> <p>Thanks for your help in advance! :)</p> <p>Paul</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload