Commit 18988295 authored by Sébastien Blin's avatar Sébastien Blin
Browse files

multiplexed_socket: avoid incorrect buffer in setOnRecv

setOnRecv must lock socketsMutex. Generally it,s the case because onAccept
will be ready right away and still locked, however if onChannelReady_ retrigger
the callback, setOnRecv will be used without socketsMutex locked.

Retrigger in a thread and always lock socketsMutex to be sure.

Change-Id: If44d240e113585a5ce3320b8f17feaaaa8be8515
parent eebf8601
......@@ -724,21 +724,27 @@ MultiplexedSocket::waitForData(const uint16_t& channel,
void
MultiplexedSocket::setOnRecv(const uint16_t& channel, GenericSocket<uint8_t>::RecvCb&& cb)
{
std::deque<uint8_t> recv;
{
// NOTE: here socketsMtx is already locked via onAccept
std::lock_guard<std::mutex> lk(pimpl_->channelCbsMtx_);
pimpl_->channelCbs_[channel] = cb;
auto dataIt = pimpl_->channelDatas_.find(channel);
if (dataIt != pimpl_->channelDatas_.end() && dataIt->second) {
std::lock_guard<std::mutex> lk(dataIt->second->mutex);
recv = std::move(dataIt->second->buf);
// Re run on ioPool, socketsMtx can be locked here (via onAccept), so retrigger
// to avoid double lock
dht::ThreadPool::io().run([w = weak(), channel, cb = std::move(cb)]() {
if (auto shared = w.lock()) {
std::lock_guard<std::mutex> lkSockets(shared->pimpl_->socketsMutex);
std::deque<uint8_t> recv;
{
std::lock_guard<std::mutex> lk(shared->pimpl_->channelCbsMtx_);
shared->pimpl_->channelCbs_[channel] = cb;
auto dataIt = shared->pimpl_->channelDatas_.find(channel);
if (dataIt != shared->pimpl_->channelDatas_.end() && dataIt->second) {
std::lock_guard<std::mutex> lk(dataIt->second->mutex);
recv = std::move(dataIt->second->buf);
}
}
if (!recv.empty() && cb) {
cb(&recv[0], recv.size());
}
}
}
if (!recv.empty() && cb) {
cb(&recv[0], recv.size());
}
});
}
void
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment