mirror of
https://github.com/SChernykh/p2pool.git
synced 2025-04-02 12:19:04 +00:00
Fixed a data race when using UV loop data
This commit is contained in:
parent
210ae3f9df
commit
d6c9c931fd
6 changed files with 26 additions and 12 deletions
|
@ -76,7 +76,7 @@ private:
|
|||
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&client->m_shutdownAsync), nullptr);
|
||||
|
||||
delete GetLoopUserData(&client->m_loop, false);
|
||||
DeleteLoopUserData(&client->m_loop);
|
||||
}
|
||||
|
||||
void on_shutdown();
|
||||
|
|
|
@ -769,9 +769,7 @@ void p2pool::on_stop(uv_async_t* async)
|
|||
|
||||
init_signals(pool, false);
|
||||
|
||||
uv_loop_t* loop = uv_default_loop_checked();
|
||||
delete GetLoopUserData(loop, false);
|
||||
loop->data = nullptr;
|
||||
DeleteLoopUserData(uv_default_loop_checked());
|
||||
}
|
||||
|
||||
void p2pool::submit_block() const
|
||||
|
|
|
@ -121,7 +121,7 @@ private:
|
|||
RandomX_Hasher_RPC* server = reinterpret_cast<RandomX_Hasher_RPC*>(async->data);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&server->m_shutdownAsync), nullptr);
|
||||
|
||||
delete GetLoopUserData(&server->m_loop, false);
|
||||
DeleteLoopUserData(&server->m_loop);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -879,7 +879,7 @@ void TCPServer::on_shutdown(uv_async_t* async)
|
|||
uv_close(reinterpret_cast<uv_handle_t*>(&s->m_dropConnectionsAsync), nullptr);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&s->m_shutdownAsync), nullptr);
|
||||
|
||||
delete GetLoopUserData(&s->m_loop, false);
|
||||
DeleteLoopUserData(&s->m_loop);
|
||||
|
||||
s->m_numHandles = 0;
|
||||
uv_walk(&s->m_loop, [](uv_handle_t*, void* n) { (*reinterpret_cast<uint32_t*>(n))++; }, &s->m_numHandles);
|
||||
|
|
26
src/util.cpp
26
src/util.cpp
|
@ -667,14 +667,30 @@ bool is_localhost(const std::string& host)
|
|||
|
||||
UV_LoopUserData* GetLoopUserData(uv_loop_t* loop, bool create)
|
||||
{
|
||||
UV_LoopUserData* data = reinterpret_cast<UV_LoopUserData*>(loop->data);
|
||||
static_assert(sizeof(std::atomic<UV_LoopUserData*>) <= sizeof(void*), "loop->data size mismatch");
|
||||
static_assert(alignof(std::atomic<UV_LoopUserData*>) <= alignof(void*), "loop->data alignment mismatch");
|
||||
|
||||
if (!data && create) {
|
||||
data = new UV_LoopUserData(loop);
|
||||
loop->data = data;
|
||||
std::atomic<UV_LoopUserData*>& data = reinterpret_cast<std::atomic<UV_LoopUserData*>&>(loop->data);
|
||||
|
||||
UV_LoopUserData* result = data.load();
|
||||
|
||||
if (!result && create) {
|
||||
UV_LoopUserData* new_data = new UV_LoopUserData(loop);
|
||||
|
||||
if (data.compare_exchange_strong(result, new_data)) {
|
||||
result = new_data;
|
||||
} else {
|
||||
delete new_data;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DeleteLoopUserData(uv_loop_t* loop)
|
||||
{
|
||||
std::atomic<UV_LoopUserData*>& data = reinterpret_cast<std::atomic<UV_LoopUserData*>&>(loop->data);
|
||||
delete data.exchange(nullptr);
|
||||
}
|
||||
|
||||
#ifdef WITH_UPNP
|
||||
|
|
|
@ -94,7 +94,6 @@ struct UV_LoopUserData
|
|||
|
||||
~UV_LoopUserData()
|
||||
{
|
||||
m_loop->data = nullptr;
|
||||
uv_mutex_destroy(&m_callbacksLock);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_async), [](uv_handle_t* h) { delete reinterpret_cast<uv_async_t*>(h); });
|
||||
for (const UV_LoopCallbackBase* cb : m_callbacks) {
|
||||
|
@ -123,6 +122,7 @@ struct UV_LoopUserData
|
|||
};
|
||||
|
||||
UV_LoopUserData* GetLoopUserData(uv_loop_t* loop, bool create = true);
|
||||
void DeleteLoopUserData(uv_loop_t* loop);
|
||||
|
||||
template<typename T>
|
||||
bool CallOnLoop(uv_loop_t* loop, T&& callback)
|
||||
|
|
Loading…
Reference in a new issue