Wie man boost :: asio überlistet, um nur Move-Handler zuzulassen
In einem RPC-Kommunikationsprotokoll sende ich nach dem Aufrufen einer Methode "Erledigt" -Nachrichten an den Anrufer zurück. Da die Methoden gleichzeitig aufgerufen werden, wird der Puffer mit der Antwort (astd::string
) muss durch einen Mutex geschützt werden. Was ich versuche zu erreichen, ist das Folgende:
void connection::send_response()
{
// block until previous response is sent
std::unique_lock<std::mutex> locker(response_mutex_);
// prepare response
response_ = "foo";
// send response back to caller. move the unique_lock into the binder
// to keep the mutex locked until asio is done sending.
asio::async_write(stream_,
asio::const_buffers_1(response_.data(), response_.size()),
std::bind(&connection::response_sent, shared_from_this(),
_1, _2, std::move(locker))
);
}
void connection::response_sent(const boost::system::error_code& err, std::size_t len)
{
if (err) handle_error(err);
// the mutex is unlocked when the binder is destroyed
}
Dies kann jedoch nicht kompiliert werden, daboost::asio
erfordertHandler, die CopyConstructible sein sollen.
Das Problem kann umgangen werden (wenn auch nicht sehr elegant), indem stattdessen die folgende gemeinsam genutzte Schließfachklasse verwendet wirdunique_lock
:
template <typename Mutex>
class shared_lock
{
public:
shared_lock(Mutex& m)
: p_(&m, std::mem_fn(&Mutex::unlock))
{ m.lock(); }
private:
std::shared_ptr<Mutex> p_;
};
Was ist die Begründung dahinter?boost::asio
Nur-Zug-Handler nicht zulassen?