/* Copyright (c) 2022, 2024, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is designed to work with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have either included with the program or referenced in the documentation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef BINLOG_ATOMIC_BCG_TICKET_H #define BINLOG_ATOMIC_BCG_TICKET_H #include #include #include #include "sql/binlog/group_commit/atomic_bgc_ticket_guard.h" #include "sql/binlog/group_commit/bgc_ticket.h" #include "sql/memory/aligned_atomic.h" namespace binlog { class AtomicBgcTicketGuard; class BgcTicket; /// @brief Implements atomic ops on BgcTicket object /// @details Impl based on Aligned_atomic /// @see Bgc_ticket_manager class AtomicBgcTicket { public: virtual ~AtomicBgcTicket() = default; // Remove copy-move semantics AtomicBgcTicket(AtomicBgcTicket const &) = delete; AtomicBgcTicket(AtomicBgcTicket &&) = delete; AtomicBgcTicket &operator=(AtomicBgcTicket const &) = delete; AtomicBgcTicket &operator=(AtomicBgcTicket &&) = delete; /// @brief Copying ctor /// @param[in] src Pattern to copy from /// @details AtomicBgcTicket is created based on src BgcTicket object AtomicBgcTicket(const BgcTicket &src); /// @brief Copying ctor /// @param[in] src Pattern to copy from /// @details AtomicBgcTicket is created based on src ValueType object explicit AtomicBgcTicket(const BgcTicket::ValueType &src); friend class AtomicBgcTicketGuard; friend class BgcTicket; /// @brief Creates the "lock" that is held for the returned /// AtomicBgcTicketGuard object lifetime /// @param[in] inc_next_before_release Before "release" operation, ticket /// value is set to the value+1 in case inc_next_before_acquire is equal false /// and inc_next_before_release is equal to true AtomicBgcTicketGuard scoped_lock(bool inc_next_before_release = false); /// @brief Creates the "lock" that is held for the returned /// AtomicBgcTicketGuard object lifetime AtomicBgcTicketGuard scoped_lock(const BgcTicket &next_value); /// @brief Stream operator impl for AtomicBgcTicket class /// @param[in] os Reference to stream obj /// @param[in] arg Constant reference to AtomicBgcTicket object /// @returns Reference to changed stream obj friend std::ostream &operator<<(std::ostream &os, const AtomicBgcTicket &arg); /// @brief Ticket mutator, atomic store op /// @param[in] value Sets atomically m_ticket internal variable to "value" void store(const BgcTicket &value); /// @brief Ticket accessor, atomic load op /// @returns BGC Ticket obtained during the atomic load op BgcTicket load() const; protected: /// @brief Sets ticket synchronization value to "in use". Only one thread is /// allowed to get into the critical section that starts with the "set_in_use" /// op and ends with the "set_used" /// @param[in] inc_next_before_acquire During the "acquire" operation, ticket /// value is set to the value+1 in case inc_next_before_acquire is equal to /// true. /// @param[in] inc_next_before_release Before "release" operation, ticket /// value is set to the value+1 in case inc_next_before_acquire is equal /// false. /// @returns previous ticket value (obtained before acquire op) and next /// ticket value (set before release op) std::pair set_in_use( bool inc_next_before_acquire = false, bool inc_next_before_release = false); /// @brief Sets ticket synchronization value to "used/free". Only one thread /// is allowed to get into the critical section that starts with the /// "set_in_use" op and ends with the "set_used" /// @param[in] next_value Next ticket value set during the "release" op. void set_used(const BgcTicket &next_value); memory::Aligned_atomic m_ticket; ///< internal ticket representation }; } // namespace binlog #endif // BINLOG_ATOMIC_BCG_TICKET_H