X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fexternal%2Fprocess-cpp-minimal%2Finclude%2Fcore%2Fsignal.h;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fexternal%2Fprocess-cpp-minimal%2Finclude%2Fcore%2Fsignal.h;h=690d236a0d483ef1b64cc3ca7d101f4fa8f891d9;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/external/process-cpp-minimal/include/core/signal.h b/src/type3_AndroidCloud/anbox-master/external/process-cpp-minimal/include/core/signal.h new file mode 100644 index 0000000..690d236 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/external/process-cpp-minimal/include/core/signal.h @@ -0,0 +1,297 @@ +/* + * Copyright © 2013 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License version 3, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authored by: Thomas Voß + */ +#ifndef COM_UBUNTU_SIGNAL_H_ +#define COM_UBUNTU_SIGNAL_H_ + +#include + +#include +#include +#include +#include +#include + +namespace core +{ +/** + * @brief A signal class that observers can subscribe to. + * @tparam Arguments List of argument types passed on to observers when the signal is emitted. + */ +template +class Signal +{ +public: + /** + * @brief Slot is the function type that observers have to provide to connect to this signal. + */ + typedef std::function Slot; + +private: + struct SlotWrapper + { + void operator()(Arguments... args) + { + dispatcher(std::bind(slot, args...)); + } + + Slot slot; + Connection::Dispatcher dispatcher; + Connection connection; + }; + +public: + /** + * @brief Signal constructs a new instance. Never throws. + */ + inline Signal() noexcept(true) : d(new Private()) + { + } + + inline ~Signal() + { + std::lock_guard lg(d->guard); + for (auto slot : d->slot_list) + slot.connection.reset(); + } + + // Copy construction, assignment and equality comparison are disabled. + Signal(const Signal&) = delete; + Signal& operator=(const Signal&) = delete; + bool operator==(const Signal&) const = delete; + + /** + * @brief Connects the provided slot to this signal instance. + * + * Calling this method is thread-safe and synchronized with any + * other connect, signal emission or disconnect calls. + * + * @param slot The function to be called when the signal is emitted. + * @return A connection object corresponding to the signal-slot connection. + */ + inline Connection connect(const Slot& slot) const + { + // Helpers to initialize an invalid connection. + static const Connection::Disconnector empty_disconnector{}; + static const Connection::DispatcherInstaller empty_dispatcher_installer{}; + + // The default dispatcher immediately executes the function object + // provided as argument on whatever thread is currently running. + static const Connection::Dispatcher default_dispatcher + = [](const std::function& handler) { handler(); }; + + Connection conn{empty_disconnector, empty_dispatcher_installer}; + + std::lock_guard lg(d->guard); + + auto result = d->slot_list.insert( + d->slot_list.end(), + SlotWrapper{slot, default_dispatcher, conn}); + + // We implicitly share our internal state with the connection here + // by passing in our private bits contained in 'd' to the std::bind call. + // This admittedly uncommon approach allows us to cleanly manage connection + // and signal lifetimes without the need to mark everything as mutable. + conn.d->disconnector = std::bind( + &Private::disconnect_slot_for_iterator, + d, + result); + conn.d->dispatcher_installer = std::bind( + &Private::install_dispatcher_for_iterator, + d, + std::placeholders::_1, + result); + + return conn; + } + + /** + * @brief operator () emits the signal with the provided parameters. + * + * Please note that signal emissions might not be delivered immediately to + * registered slots, depending on whether the respective connection is dispatched + * via a queueing dispatcher. For that reason, the lifetime of the arguments has to + * exceed the scope of the call to this operator and its surrounding scope. + * + * @param args The arguments to be passed on to registered slots. + */ + inline void operator()(Arguments... args) + { + std::lock_guard lg(d->guard); + for(auto slot : d->slot_list) + { + slot(args...); + } + } + +private: + struct Private + { + typedef std::list SlotList; + + inline void disconnect_slot_for_iterator(typename SlotList::iterator it) + { + std::lock_guard lg(guard); + slot_list.erase(it); + } + + inline void install_dispatcher_for_iterator(const Connection::Dispatcher& dispatcher, + typename SlotList::iterator it) + { + std::lock_guard lg(guard); + it->dispatcher = dispatcher; + } + + std::mutex guard; + SlotList slot_list; + }; + std::shared_ptr d; +}; + +/** + * @brief A signal class that observers can subscribe to, + * template specialization for signals without arguments. + */ +template<> +class Signal +{ +public: + /** + * @brief Slot is the function type that observers have to provide to connect to this signal. + */ + typedef std::function Slot; + +private: + struct SlotWrapper + { + void operator()() + { + dispatcher(slot); + } + + Slot slot; + Connection::Dispatcher dispatcher; + Connection connection; + }; + +public: + /** + * @brief Signal constructs a new instance. Never throws. + */ + inline Signal() noexcept(true) : d(new Private()) + { + } + + inline ~Signal() + { + std::lock_guard lg(d->guard); + for (auto slot : d->slot_list) + slot.connection.reset(); + } + + // Copy construction, assignment and equality comparison are disabled. + Signal(const Signal&) = delete; + Signal& operator=(const Signal&) = delete; + bool operator==(const Signal&) const = delete; + + /** + * @brief Connects the provided slot to this signal instance. + * + * Calling this method is thread-safe and synchronized with any + * other connect, signal emission or disconnect calls. + * + * @param slot The function to be called when the signal is emitted. + * @return A connection object corresponding to the signal-slot connection. + */ + inline Connection connect(const Slot& slot) const + { + // Helpers to initialize an invalid connection. + static const Connection::Disconnector empty_disconnector{}; + static const Connection::DispatcherInstaller empty_dispatcher_installer{}; + + // The default dispatcher immediately executes the function object + // provided as argument on whatever thread is currently running. + static const Connection::Dispatcher default_dispatcher + = [](const std::function& handler) { handler(); }; + + Connection conn{empty_disconnector, empty_dispatcher_installer}; + + std::lock_guard lg(d->guard); + + auto result = d->slot_list.insert( + d->slot_list.end(), + SlotWrapper{slot, default_dispatcher, conn}); + + // We implicitly share our internal state with the connection here + // by passing in our private bits contained in 'd' to the std::bind call. + // This admittedly uncommon approach allows us to cleanly manage connection + // and signal lifetimes without the need to mark everything as mutable. + conn.d->disconnector = std::bind( + &Private::disconnect_slot_for_iterator, + d, + result); + conn.d->dispatcher_installer = std::bind( + &Private::install_dispatcher_for_iterator, + d, + std::placeholders::_1, + result); + + return conn; + } + + /** + * @brief operator () emits the signal. + * + * Please note that signal emissions might not be delivered immediately to + * registered slots, depending on whether the respective connection is dispatched + * via a queueing dispatcher. + */ + inline void operator()() + { + std::lock_guard lg(d->guard); + for(auto slot : d->slot_list) + { + slot(); + } + } + +private: + struct Private + { + typedef std::list SlotList; + + inline void disconnect_slot_for_iterator(typename SlotList::iterator it) + { + std::lock_guard lg(guard); + slot_list.erase(it); + } + + inline void install_dispatcher_for_iterator(const Connection::Dispatcher& dispatcher, + typename SlotList::iterator it) + { + std::lock_guard lg(guard); + it->dispatcher = dispatcher; + } + + std::mutex guard; + SlotList slot_list; + }; + std::shared_ptr d; +}; +} + +#endif // COM_UBUNTU_SIGNAL_H_