From 937a3192eb6d5fad2ccdb4294f91f5c6d7af53b8 Mon Sep 17 00:00:00 2001 From: Pavel Kruglov Date: Mon, 15 Feb 2021 22:54:23 +0300 Subject: [PATCH] Fix data race --- src/Common/Epoll.cpp | 24 ++++++++++++++++++------ src/Common/Epoll.h | 9 ++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/Common/Epoll.cpp b/src/Common/Epoll.cpp index 628bb45e796..d085315b1a0 100644 --- a/src/Common/Epoll.cpp +++ b/src/Common/Epoll.cpp @@ -21,9 +21,21 @@ Epoll::Epoll() : events_count(0) throwFromErrno("Cannot open epoll descriptor", DB::ErrorCodes::EPOLL_ERROR); } -Epoll::Epoll(Epoll && other) : epoll_fd(other.epoll_fd), events_count(other.events_count) +Epoll::Epoll(Epoll && other) { + epoll_fd = other.epoll_fd; other.epoll_fd = -1; + int count = other.events_count; + events_count = count; +} + +Epoll & Epoll::operator=(Epoll && other) +{ + epoll_fd = other.epoll_fd; + other.epoll_fd = -1; + int count = other.events_count; + events_count = count; + return *this; } void Epoll::add(int fd, void * ptr) @@ -35,18 +47,18 @@ void Epoll::add(int fd, void * ptr) else event.data.fd = fd; + ++events_count; + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1) throwFromErrno("Cannot add new descriptor to epoll", DB::ErrorCodes::EPOLL_ERROR); - - ++events_count; } void Epoll::remove(int fd) { + --events_count; + if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr) == -1) throwFromErrno("Cannot remove descriptor from epoll", DB::ErrorCodes::EPOLL_ERROR); - - --events_count; } size_t Epoll::getManyReady(int max_events, epoll_event * events_out, bool blocking, AsyncCallback async_callback) const @@ -54,7 +66,7 @@ size_t Epoll::getManyReady(int max_events, epoll_event * events_out, bool blocki if (events_count == 0) throw Exception("There is no events in epoll", ErrorCodes::LOGICAL_ERROR); - int ready_size = 0; + int ready_size; int timeout = blocking && !async_callback ? -1 : 0; do { diff --git a/src/Common/Epoll.h b/src/Common/Epoll.h index eb168c22a92..a7090bdb9b6 100644 --- a/src/Common/Epoll.h +++ b/src/Common/Epoll.h @@ -16,13 +16,12 @@ class Epoll public: Epoll(); - Epoll(const Epoll & other) = delete; - Epoll & operator=(const Epoll & other) = delete; + Epoll(const Epoll &) = delete; + Epoll & operator=(const Epoll &) = delete; + Epoll & operator=(Epoll && other); Epoll(Epoll && other); - Epoll & operator=(Epoll && other) = default; - /// Add new file descriptor to epoll. If ptr set to nullptr, epoll_event.data.fd = fd, /// otherwise epoll_event.data.ptr = ptr. void add(int fd, void * ptr = nullptr); @@ -47,7 +46,7 @@ public: private: int epoll_fd; - int events_count; + std::atomic events_count; }; }