ruipacheco ruipacheco - 11 days ago 6
C++ Question

How can I notify my user that a read hasn't been completed yet?

I have a class that encapsulates all the business logic related to using Asio to read and write to a generic stream socket. I'd like to add a flag so my users know if they can retrieve data from a getter or whether we're still waiting for the backend.

How is this normally done? Set a flag to busy after the write and do the read in the background in a separate thread? The flag would be something similar to PQisBusy

Answer

Don't know if you are looking for an asynchronous solution such as using a callback or a polling method. From the question it seems you are looking for a polling method since you want a flag that users can check to see if the data is fully ready. In that case just define a variable and function in your class, .h file:

#include <atomic>
#include <thread>    

class MySocket
{
public:
   ~MySocket();
   bool IsReady();
   void StartDataGather();    
private:
   void GatherDataThread();
   static std::atomic<bool> _isReady;
   std::thread _thread;
}

In your .cpp file:

#include "MySocket.h"

static std::atomic<bool> MySocket::_isReady(false); // Default flag to false.

MySocket::~MySocket()
{
    // Make sure to kill the thread if this class is destroyed.
    if (_thread.joinable())
        _thread.join();
}

bool MySocket::IsReady() { return _isReady; }

void MySocket::StartDataGather()
{
    _isReady = false; // Reset flag.

    // If your gather thread is running then stop it or wait for it
    // to finish before starting it again.
    if(_thread.joinable())
        _thread.join();

    // Start the background thread to gather data.
    _thread = std::thread(GatherDataThread());
}

void MySocket::GatherDataThread()
{
    // This is your thread that gathers data.
    // Once all of the data is gathered, do the following:
    _isReady = true;
}

To use this method from outside of your client class do the following:

MySocket mySock;

mySock.StartDataGather();

while(!mySock.IsReady())
{
    // Do some other code here until data is ready.
    // Once the MySocket::GatherDataThread() finishes it will
    // set _isReady = true which will cause mySock.IsReady() to
    // return true.
}

You now have a flag that others can check and it is thread safe because of the std::atomic<> template. The following uses C++ 11 or newer -std=c++11.

Comments