I am facing the following problem:
I have a RpcExecutor
class. This class:
- sends rpc requests
- receives rpc responses
I keep everything asynchronous (through boost.asio). Every time a request is sent, a write handler will be invoked that modifies a map:
async_write(...., [this, ...](error_code ec, size_t bytesTransferred) {
//
pendingRequests_.insert(requestId, move(myPromise));
};
I start to listen in the same socket, with async_read_until
, and replies come, possibly out of order. I also need to modify pendingRequests_
from this hanlder:
async_read(... [this, ...](error_code ec, size_t bytesTransferred) {
...
pendingRequests_.at(requestId).set_value(...);
pendingRequests_.erase(requestId);
});
My class looks like this:
class RpcExecutor {
private:
std::unique_ptr<std::map<std::uint64_t, MyPromise>> pendingRequests_;
...
};
In order to make sure that the initialization of pendingRequests_
, the reading and the writing of pendingRequests_
are done through the same thread (I did check it is the case), I have the following restrictions applied:
- there is a single
asio::run()
thread running, which is a different thread fromRpcExecutor
instance. - I initialize the
pendingRequests_
pointed-to object inside aboost::asio::post(myIoContext, ...)
, meaning that it is initialized in the same thread whereasio::run
is executed. - The
async_read
handler andasync_write
handler are executed in the same thread asio_context::run
, which is the same thread asboost::asio::post
.
All in all:
boost::asio::post
,async_read
handler andasync_write
handler are executed in the same thread.RpcExecutor
class instance is created in another thread.
Result
async_read
andasync_write
handler do not see the same memory address forpendingRequests_
.
Questions
- How should I initialize a
map
that I can use from my handlers thread taking into account thatRpcExecutor
class instance is in another thread? Even if I initialize the pointed-to element in the same thread asasio::context::run
viapost
, the handlers still see different addresses for the object. - Do I need mutexes of any kind? I want, actually, to do all reads/writes from a single thread, even if not the same thread as
RpcExecutor
class instance, which holds thependingTasks_
member variable.