03dbaf877ccb87d7b04472b2c570ceb21d9243f3
[iec.git] / src / type3_AndroidCloud / anbox-master / external / process-cpp-minimal / include / core / connection.h
1 /*
2  * Copyright © 2013 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Thomas Voß <thomas.voss@canonical.com>
17  */
18 #ifndef COM_UBUNTU_CONNECTION_H_
19 #define COM_UBUNTU_CONNECTION_H_
20
21 #include <functional>
22 #include <memory>
23 #include <mutex>
24
25 namespace core
26 {
27 class ScopedConnection;
28 /**
29  * @brief The Connection class models a signal-slot connection.
30  */
31 class Connection
32 {
33 public:    
34     typedef std::function<void(const std::function<void()>&)> Dispatcher;
35
36     /**
37      * @brief Checks if this instance corresponds to an active signal-slot connection.
38      * @return true iff the instance corresponds to an active signal-slot connection.
39      */
40     inline bool is_connected() const
41     {
42         if (!d)
43             return false;
44
45         return (d->disconnector ? true : false);
46     }
47
48     /**
49      * @brief End a signal-slot connection.
50      */
51     inline void disconnect()
52     {
53         if (d)
54             d->disconnect();
55     }
56
57     /**
58      * @brief Installs a dispatcher for this signal-slot connection.
59      * @param dispatcher The dispatcher to be used for signal emissions.
60      */
61     inline void dispatch_via(const Dispatcher& dispatcher)
62     {
63         if (d && d->dispatcher_installer)
64             d->dispatcher_installer(dispatcher);
65     }
66
67 private:
68     friend class ScopedConnection;
69
70     typedef std::function<void()> Disconnector;
71     typedef std::function<void(const Dispatcher&)> DispatcherInstaller;
72
73     template<typename ... Arguments> friend class Signal;
74
75     inline Connection(const Disconnector& disconnector,
76                       const DispatcherInstaller& installer)
77         : d(std::make_shared<Private>(disconnector, installer))
78     {
79     }
80
81     inline bool operator<(const Connection& rhs) const
82     {
83         return d < rhs.d;
84     }
85
86     inline void reset()
87     {
88         if (d)
89             d->reset();
90     }
91
92     struct Private
93     {
94         Private(const Connection::Disconnector& disconnector,
95                 const Connection::DispatcherInstaller& dispatcher_installer)
96             : disconnector(disconnector),
97               dispatcher_installer(dispatcher_installer)
98         {
99         }
100
101         inline void reset()
102         {
103             std::lock_guard<std::mutex> lg(guard);
104             reset_locked();
105         }
106
107         inline void reset_locked()
108         {
109             static const Connection::Disconnector empty_disconnector{};
110             static const Connection::DispatcherInstaller empty_dispatcher_installer{};
111
112             disconnector = empty_disconnector;
113             dispatcher_installer = empty_dispatcher_installer;
114         }
115
116         inline void disconnect()
117         {
118             static const Connection::Disconnector empty_disconnector{};
119
120             std::lock_guard<std::mutex> lg(guard);
121
122             if (disconnector)
123                 disconnector();
124
125             reset_locked();
126         }
127
128         std::mutex guard;
129         Connection::Disconnector disconnector;
130         Connection::DispatcherInstaller dispatcher_installer;
131     };
132
133     // The whole class is implicitly shared and we thus forward our complete
134     // shared state to a private structure that is lifetime-managed by a shared_ptr.
135     std::shared_ptr<Private> d;
136 };
137
138 /**
139  * @brief Scoped helper class to map signal-slot connection mgmt. to RAII.
140  */
141 class ScopedConnection
142 {
143 public:
144     /**
145      * @brief Constructs an instance for an existing signal-slot connection.
146      * @param c The existing signal-slot connection.
147      */
148     inline ScopedConnection(const Connection& c) : connection(c)
149     {
150     }
151
152     inline ScopedConnection(ScopedConnection&& rhs) : connection(std::move(rhs.connection))
153     {
154     }
155
156     ScopedConnection(const ScopedConnection&) = delete;
157
158     /**
159      * @brief Disconnects the signal-slot connection.
160      */
161     inline ~ScopedConnection() noexcept(true)
162     {
163         try
164         {
165             connection.disconnect();
166         } catch(...)
167         {
168         }
169     }
170
171     inline ScopedConnection& operator=(ScopedConnection&& rhs)
172     {
173         connection = std::move(rhs.connection);
174         return *this;
175     }
176
177     ScopedConnection& operator=(const ScopedConnection&) = delete;
178     bool operator==(const ScopedConnection&) = delete;
179
180     inline bool operator<(const ScopedConnection& rhs) const
181     {
182         return connection < rhs.connection;
183     }
184
185 private:
186     Connection connection;
187 };
188 }
189
190 #endif // COM_UBUNTU_CONNECTION_H_