RemoteReferenceCount.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2017, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX
19 * @author Raphael Grimm( raphael dor grimm at kit dot edu)
20 * @date 2017
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#pragma once
25
26#include <atomic>
27#include <functional>
28#include <map>
29#include <mutex>
30#include <queue>
31#include <set>
32#include <string>
33#include <thread>
34
35#include <IceUtil/UUID.h>
36
37#include <ArmarXCore/interface/core/RemoteReferenceCount.h>
38
39#include "logging/Logging.h"
40
41//internal base impl
42namespace armarx
43{
44 class ArmarXManager;
46} // namespace armarx
47
48namespace armarx::detail
49{
50 class RemoteReferenceCountControlBlockManagementInterface : virtual public Ice::Object
51 {
52 public:
54
55 void
57 {
58 countingActivated_ = true;
59 }
60
61 bool
63 {
64 return countingActivated_;
65 }
66
67 bool
69 {
70 return countReachedZero_;
71 }
72
73 Ice::ObjectPrx
74 getProxy() const
75 {
76 return selfProxy;
77 }
78
80 const std::string& id);
81
83
84 protected:
85 friend class ::armarx::RemoteReferenceCountControlBlockManager;
86 /**
87 * @brief Returns the next timepoint when this ControlBlock should be checked.
88 * If the returned time is in the past and counting was activated, this Block
89 * is removed from counting and onCountReachedZero is called.
90 * @return
91 */
92 virtual IceUtil::Time nextCheckTimePoint() = 0;
93 virtual void onCountReachedZero() = 0;
94
95 void countReachedZero();
96
98 Ice::ObjectPrx selfProxy;
99
100 std::mutex mtx;
101 IceUtil::Time lastTimeReachedZero;
102
103 const std::string id;
104
105 private:
106 std::atomic_bool countingActivated_{false};
107 std::atomic_bool countReachedZero_{false};
108 };
109
112} // namespace armarx::detail
113
114//internal base impl AbstractRemoteReferenceCountControlBlock
115namespace armarx::detail
116{
118 virtual public RemoteReferenceCountControlBlockInterface,
120 {
121 public:
123 RemoteReferenceCounterBasePtr getReferenceCounter();
124
125 void heartbeat(const std::string& counterId,
126 const Ice::Current& = Ice::emptyCurrent) final override;
127 void addCounter(const std::string& counterId,
128 const Ice::Current& = Ice::emptyCurrent) final override;
129 void removeCounter(const std::string& counterId,
130 const Ice::Current& = Ice::emptyCurrent) final override;
131
132 protected:
134 const std::string& id,
135 IceUtil::Time deletionDelay,
136 IceUtil::Time orphantDeletionDelay,
137 long heartBeatMs);
138
139 private:
140 IceUtil::Time nextCheckTimePoint() final override;
141
142 std::map<std::string, IceUtil::Time> counterIds;
143 const IceUtil::Time deletionDelay;
144 const IceUtil::Time orphantDeletionDelay;
145 const long heartBeatMs;
146 };
147} // namespace armarx::detail
148
149//internal base impl AbstractSimpleRemoteReferenceCountControlBlock
150namespace armarx::detail
151{
153 virtual public SimpleRemoteReferenceCountControlBlockInterface,
155 {
156 public:
158 SimpleRemoteReferenceCounterBasePtr getReferenceCounter();
159
160 void addCounter(const std::string& counterId, const Ice::Current&) final override;
161 void removeCounter(const std::string& counterId, const Ice::Current&) final override;
162
163 protected:
165 const std::string& id,
166 IceUtil::Time deletionDelay);
167
168 private:
169 IceUtil::Time nextCheckTimePoint() final override;
170
171 std::set<std::string> counterIds;
172 const IceUtil::Time deletionDelay;
173 };
174} // namespace armarx::detail
175
176//impl RemoteReferenceCountControlBlock
177namespace armarx
178{
179 template <class FunctionType = std::function<void(void)>, class DataType = void>
180 class RemoteReferenceCountControlBlock :
182 {
183 RemoteReferenceCountControlBlock(const ArmarXManagerPtr& manager,
184 const std::string& id,
185 FunctionType f,
186 DataType d,
187 IceUtil::Time deletionDelay,
188 IceUtil::Time orphantDeletionDelay,
189 long heartBeatMs) :
192 id,
193 deletionDelay,
194 orphantDeletionDelay,
195 heartBeatMs),
196 data{std::move(d)},
197 function{std::move(f)}
198 {
199 }
200
201 DataType data;
202 FunctionType function;
203
204 void
205 onCountReachedZero() final override
206 {
207 function(data);
208 }
209 friend class ArmarXManager;
210 using ArmarXManagerPtr = IceUtil::Handle<ArmarXManager>;
211 };
212
213 template <class FunctionType>
214 class RemoteReferenceCountControlBlock<FunctionType, void> :
216 {
217 RemoteReferenceCountControlBlock(const ArmarXManagerPtr& manager,
218 const std::string& id,
219 FunctionType f,
220 IceUtil::Time deletionDelay,
221 IceUtil::Time orphantDeletionDelay,
222 long heartBeatMs) :
225 id,
226 deletionDelay,
227 orphantDeletionDelay,
228 heartBeatMs),
229 function{std::move(f)}
230 {
231 }
232
233 FunctionType function;
234
235 void
236 onCountReachedZero() final override
237 {
238 function();
239 }
240 friend class ArmarXManager;
241 using ArmarXManagerPtr = IceUtil::Handle<ArmarXManager>;
242 };
243
244 template <class FunctionType, class DataType = void>
247} // namespace armarx
248
249//impl SimpleRemoteReferenceCountControlBlock
250namespace armarx
251{
252 template <class FunctionType = std::function<void(void)>, class DataType = void>
253 class SimpleRemoteReferenceCountControlBlock :
255 {
256 SimpleRemoteReferenceCountControlBlock(const ArmarXManagerPtr& manager,
257 const std::string& id,
258 FunctionType f,
259 DataType d,
260 IceUtil::Time deletionDelay) :
263 data{std::move(d)},
264 function{std::move(f)}
265 {
266 }
267
268 DataType data;
269 FunctionType function;
270
271 void
272 onCountReachedZero() final override
273 {
274 function(data);
275 }
276 friend class ArmarXManager;
277 using ArmarXManagerPtr = IceUtil::Handle<ArmarXManager>;
278 };
279
280 template <class FunctionType>
281 class SimpleRemoteReferenceCountControlBlock<FunctionType, void> :
283 {
284 SimpleRemoteReferenceCountControlBlock(const ArmarXManagerPtr& manager,
285 const std::string& id,
286 FunctionType f,
287 IceUtil::Time deletionDelay) :
290 function{std::move(f)}
291 {
292 }
293
294 FunctionType function;
295
296 void
297 onCountReachedZero() final override
298 {
299 function();
300 }
301 friend class ArmarXManager;
302 using ArmarXManagerPtr = IceUtil::Handle<ArmarXManager>;
303 };
304
305 template <class FunctionType, class DataType = void>
308} // namespace armarx
309
310//impl manager
311namespace armarx
312{
314 {
315 public:
316 RemoteReferenceCountControlBlockManager(IceUtil::Time period) : period{period}
317 {
318 }
319
324
325 static const Ice::Long DefaultDeletionDelayMs;
326 static const Ice::Long DefaultOrphantDeletionDelayMs;
327
329 void stop();
330
331 private:
332 void manage();
333
334 const IceUtil::Time period;
335 using PqEntry = std::pair<IceUtil::Time,
337
338 struct PqEntryCompare
339 {
340 bool
341 operator()(const PqEntry& lhs, const PqEntry& rhs) const
342 {
343 return std::make_pair(lhs.first, lhs.second.get()) >
344 std::make_pair(rhs.first, rhs.second.get());
345 }
346 };
347
348 struct RRCBMIPtr
349 {
350 bool
351 operator()(
352 const detail::RemoteReferenceCountControlBlockManagementInterfacePtr& lhs,
353 const detail::RemoteReferenceCountControlBlockManagementInterfacePtr& rhs) const
354 {
355 return lhs.get() < rhs.get();
356 }
357 };
358
359 std::mutex stateMutex;
360 std::set<detail::RemoteReferenceCountControlBlockManagementInterfacePtr, RRCBMIPtr>
361 pendingForActivation;
362 std::priority_queue<PqEntry, std::vector<PqEntry>, PqEntryCompare> rrccbs;
363 std::thread thread;
364 std::atomic_bool shutdown{false};
365 };
366} // namespace armarx
Main class of an ArmarX process.
void add(detail::RemoteReferenceCountControlBlockManagementInterfacePtr ptr)
AbstractRemoteReferenceCountControlBlock(const ArmarXManagerPtr &manager, const std::string &id, IceUtil::Time deletionDelay, IceUtil::Time orphantDeletionDelay, long heartBeatMs)
void heartbeat(const std::string &counterId, const Ice::Current &=Ice::emptyCurrent) final override
void removeCounter(const std::string &counterId, const Ice::Current &=Ice::emptyCurrent) final override
void addCounter(const std::string &counterId, const Ice::Current &=Ice::emptyCurrent) final override
void addCounter(const std::string &counterId, const Ice::Current &) final override
void removeCounter(const std::string &counterId, const Ice::Current &) final override
AbstractSimpleRemoteReferenceCountControlBlock(const ArmarXManagerPtr &manager, const std::string &id, IceUtil::Time deletionDelay)
RemoteReferenceCountControlBlockManagementInterface(const ArmarXManagerPtr &manager, const std::string &id)
virtual IceUtil::Time nextCheckTimePoint()=0
Returns the next timepoint when this ControlBlock should be checked.
IceUtil::Handle< detail::RemoteReferenceCountControlBlockManagementInterface > RemoteReferenceCountControlBlockManagementInterfacePtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< ArmarXManager > ArmarXManagerPtr
IceUtil::Handle< RemoteReferenceCountControlBlock< FunctionType, DataType > > RemoteReferenceCountControlBlockPtr
IceUtil::Handle< SimpleRemoteReferenceCountControlBlock< FunctionType, DataType > > SimpleRemoteReferenceCountControlBlockPtr