diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index 0e98a4d0d..414e3d3c5 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -37,6 +37,7 @@ set(TDUTILS_SOURCE td/utils/port/FileFd.cpp td/utils/port/IPAddress.cpp td/utils/port/path.cpp + td/utils/port/PollFlags.cpp td/utils/port/ServerSocketFd.cpp td/utils/port/signals.cpp td/utils/port/sleep.cpp @@ -54,7 +55,6 @@ set(TDUTILS_SOURCE td/utils/port/detail/KQueue.cpp td/utils/port/detail/NativeFd.cpp td/utils/port/detail/Poll.cpp - td/utils/port/detail/PollableFd.cpp td/utils/port/detail/Select.cpp td/utils/port/detail/ThreadIdGuard.cpp td/utils/port/detail/WineventPoll.cpp @@ -100,6 +100,7 @@ set(TDUTILS_SOURCE td/utils/port/platform.h td/utils/port/Poll.h td/utils/port/PollBase.h + td/utils/port/PollFlags.h td/utils/port/RwMutex.h td/utils/port/ServerSocketFd.h td/utils/port/signals.h diff --git a/tdutils/td/utils/port/detail/PollableFd.cpp b/tdutils/td/utils/port/PollFlags.cpp similarity index 79% rename from tdutils/td/utils/port/detail/PollableFd.cpp rename to tdutils/td/utils/port/PollFlags.cpp index d2e91d048..4aaffce46 100644 --- a/tdutils/td/utils/port/detail/PollableFd.cpp +++ b/tdutils/td/utils/port/PollFlags.cpp @@ -4,13 +4,10 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "td/utils/port/detail/PollableFd.h" - -#if TD_POSIX_PORT -#include -#endif +#include "td/utils/port/PollFlags.h" namespace td { + bool PollFlagsSet::write_flags(PollFlags flags) { if (flags.empty()) { return false; @@ -18,9 +15,11 @@ bool PollFlagsSet::write_flags(PollFlags flags) { auto old_flags = to_write_.fetch_or(flags.raw(), std::memory_order_relaxed); return (flags.raw() & ~old_flags) != 0; } + bool PollFlagsSet::write_flags_local(PollFlags flags) { return flags_.add_flags(flags); } + bool PollFlagsSet::flush() const { if (to_write_.load(std::memory_order_relaxed) == 0) { return false; @@ -33,19 +32,40 @@ bool PollFlagsSet::flush() const { } return flags_ != old_flags; } + PollFlags PollFlagsSet::read_flags() const { flush(); return flags_; } + PollFlags PollFlagsSet::read_flags_local() const { return flags_; } + void PollFlagsSet::clear_flags(PollFlags flags) { flags_.remove_flags(flags); } + void PollFlagsSet::clear() { to_write_ = 0; flags_ = {}; } +StringBuilder &operator<<(StringBuilder &sb, PollFlags flags) { + sb << "["; + if (flags.can_read()) { + sb << "R"; + } + if (flags.can_write()) { + sb << "W"; + } + if (flags.can_close()) { + sb << "C"; + } + if (flags.has_pending_error()) { + sb << "E"; + } + return sb << "]"; +} + } // namespace td diff --git a/tdutils/td/utils/port/PollFlags.h b/tdutils/td/utils/port/PollFlags.h new file mode 100644 index 000000000..cbea2cc0d --- /dev/null +++ b/tdutils/td/utils/port/PollFlags.h @@ -0,0 +1,122 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +class PollFlags { + public: + using Raw = int32; + bool can_read() const { + return has_flags(Read()); + } + bool can_write() const { + return has_flags(Write()); + } + bool can_close() const { + return has_flags(Close()); + } + bool has_pending_error() const { + return has_flags(Error()); + } + void remove_flags(PollFlags flags) { + remove_flags(flags.raw()); + } + bool add_flags(PollFlags flags) { + auto old_flags = flags_; + add_flags(flags.raw()); + return old_flags != flags_; + } + bool has_flags(PollFlags flags) const { + return has_flags(flags.raw()); + } + + bool empty() const { + return flags_ == 0; + } + Raw raw() const { + return flags_; + } + static PollFlags from_raw(Raw raw) { + return PollFlags(raw); + } + PollFlags() = default; + + bool operator==(const PollFlags &other) const { + return flags_ == other.flags_; + } + bool operator!=(const PollFlags &other) const { + return !(*this == other); + } + PollFlags operator|(const PollFlags other) const { + return from_raw(raw() | other.raw()); + } + + static PollFlags Write() { + return PollFlags(Flag::Write); + } + static PollFlags Error() { + return PollFlags(Flag::Error); + } + static PollFlags Close() { + return PollFlags(Flag::Close); + } + static PollFlags Read() { + return PollFlags(Flag::Read); + } + static PollFlags ReadWrite() { + return Read() | Write(); + } + + private: + enum class Flag : Raw { Write = 0x001, Read = 0x002, Close = 0x004, Error = 0x008, None = 0 }; + Raw flags_{static_cast(Flag::None)}; + + explicit PollFlags(Raw raw) : flags_(raw) { + } + explicit PollFlags(Flag flag) : PollFlags(static_cast(flag)) { + } + + PollFlags &add_flags(Raw flags) { + flags_ |= flags; + return *this; + } + PollFlags &remove_flags(Raw flags) { + flags_ &= ~flags; + return *this; + } + bool has_flags(Raw flags) const { + return (flags_ & flags) == flags; + } +}; + +StringBuilder &operator<<(StringBuilder &sb, PollFlags flags); + +class PollFlagsSet { + public: + // write flags from any thread + // this is the only function that should be called from other threads + bool write_flags(PollFlags flags); + + bool write_flags_local(PollFlags flags); + bool flush() const; + + PollFlags read_flags() const; + PollFlags read_flags_local() const; + void clear_flags(PollFlags flags); + void clear(); + + private: + mutable std::atomic to_write_{0}; + mutable PollFlags flags_; +}; + +} // namespace td diff --git a/tdutils/td/utils/port/detail/PollableFd.h b/tdutils/td/utils/port/detail/PollableFd.h index 3982667ca..eb7ec8fd0 100644 --- a/tdutils/td/utils/port/detail/PollableFd.h +++ b/tdutils/td/utils/port/detail/PollableFd.h @@ -8,138 +8,14 @@ #include "td/utils/format.h" #include "td/utils/List.h" -#include "td/utils/MovableValue.h" #include "td/utils/Observer.h" #include "td/utils/port/detail/NativeFd.h" +#include "td/utils/port/PollFlags.h" #include "td/utils/SpinLock.h" -#include "td/utils/Status.h" #include namespace td { -class ObserverBase; - -class PollFlags { - public: - using Raw = int32; - bool can_read() const { - return has_flags(Read()); - } - bool can_write() const { - return has_flags(Write()); - } - bool can_close() const { - return has_flags(Close()); - } - bool has_pending_error() const { - return has_flags(Error()); - } - void remove_flags(PollFlags flags) { - remove_flags(flags.raw()); - } - bool add_flags(PollFlags flags) { - auto old_flags = flags_; - add_flags(flags.raw()); - return old_flags != flags_; - } - bool has_flags(PollFlags flags) const { - return has_flags(flags.raw()); - } - - bool empty() const { - return flags_ == 0; - } - Raw raw() const { - return flags_; - } - static PollFlags from_raw(Raw raw) { - return PollFlags(raw); - } - PollFlags() = default; - - bool operator==(const PollFlags &other) const { - return flags_ == other.flags_; - } - bool operator!=(const PollFlags &other) const { - return !(*this == other); - } - PollFlags operator|(const PollFlags other) const { - return from_raw(raw() | other.raw()); - } - - static PollFlags Write() { - return PollFlags(Flag::Write); - } - static PollFlags Error() { - return PollFlags(Flag::Error); - } - static PollFlags Close() { - return PollFlags(Flag::Close); - } - static PollFlags Read() { - return PollFlags(Flag::Read); - } - static PollFlags ReadWrite() { - return Read() | Write(); - } - - private: - enum class Flag : Raw { Write = 0x001, Read = 0x002, Close = 0x004, Error = 0x008, None = 0 }; - Raw flags_{static_cast(Flag::None)}; - - explicit PollFlags(Raw raw) : flags_(raw) { - } - explicit PollFlags(Flag flag) : PollFlags(static_cast(flag)) { - } - - PollFlags &add_flags(Raw flags) { - flags_ |= flags; - return *this; - } - PollFlags &remove_flags(Raw flags) { - flags_ &= ~flags; - return *this; - } - bool has_flags(Raw flags) const { - return (flags_ & flags) == flags; - } -}; - -inline StringBuilder &operator<<(StringBuilder &sb, PollFlags flags) { - sb << "["; - if (flags.can_read()) { - sb << "R"; - } - if (flags.can_write()) { - sb << "W"; - } - if (flags.can_close()) { - sb << "C"; - } - if (flags.has_pending_error()) { - sb << "E"; - } - return sb << "]"; -} - -class PollFlagsSet { - public: - // write flags from any thread - // this is the only function that should be called from other threads - bool write_flags(PollFlags flags); - - bool write_flags_local(PollFlags flags); - bool flush() const; - - PollFlags read_flags() const; - PollFlags read_flags_local() const; - void clear_flags(PollFlags flags); - void clear(); - - private: - mutable std::atomic to_write_{0}; - mutable PollFlags flags_; -}; class PollableFdInfo; class PollableFdInfoUnlock {