hpp-corbaserver: include/hpp/corbaserver/servant-base.hh Source File

hpp-corbaserver 9.0.2 Corba server for Humanoid Path Planner applications

Loading...
Searching...
No Matches
servant-base.hh
Go to the documentation of this file.
1// Copyright (C) 2019 by Joseph Mirabel, LAAS-CNRS.
2//
3
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//
11// 2. Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26// DAMAGE.
27//
28// This software is provided "as is" without warranty of any kind,
29// either expressed or implied, including but not limited to the
30// implied warranties of fitness for a particular purpose.
31//
32// See the COPYING file for more information.
33
34#ifndef HPP_CORBASERVER_SERVANT_BASE_HH
35#define HPP_CORBASERVER_SERVANT_BASE_HH
36
37#include <hpp/common-idl.hh>
38#include <hpp/corbaserver/server.hh>
39
40 namespace hpp {
41 namespace corbaServer {
72
73#define SERVANT_BASE_TYPEDEFS(idlObj, hppObj) \
74 protected: \
75 using ::hpp::corbaServer::AbstractServantBase<hppObj>::server_; \
76 \
77 public: \
78 typedef _Base Base; \
79 typedef _Storage Storage; \
80 typedef idlObj Object; \
81 typedef idlObj##_ptr Object_ptr; \
82 typedef idlObj##_var Object_var; \
83 typedef ::hpp::corbaServer::ServantBase<hppObj, _Storage> _ServantBase; \
84 using _ServantBase::get; \
85 using _ServantBase::getT; \
86 using _ServantBase::getS
87
88 template <typename T>
89 struct hpp_traits {};
90
92 class AbstractServantKey {
93 public:
94 virtual Server::ServantKey getServantKey() const = 0;
95
96 virtual bool expired() const = 0;
97};
98
103 template <typename T>
104 class AbstractServantBase : AbstractServantKey {
105 public:
106 virtual ~AbstractServantBase() {}
107
108 typedef shared_ptr<T> TShPtr_t;
109 typedef weak_ptr<T> TWkPtr_t;
110
111 virtual TShPtr_t get() const = 0;
112
113 virtual Server::ServantKey getServantKey() const { return get().get(); }
114
115 protected:
116 AbstractServantBase(Server* server) : server_(server) {}
117
118 Server* server_;
119};
120
121 template <typename T, typename _Storage>
122 class ServantBase : public AbstractServantBase<T> {
123 public:
124 typedef _Storage Storage;
125 using typename AbstractServantBase<T>::TShPtr_t;
126 using typename AbstractServantBase<T>::TWkPtr_t;
127 typedef weak_ptr<typename Storage::element_type> StorageElementWkPtr_t;
128 typedef shared_ptr<typename Storage::element_type> StorageElementShPtr_t;
129
130 virtual ~ServantBase() {}
131
132 virtual TShPtr_t get() const {
133 TWkPtr_t wk((StorageElementWkPtr_t)wrappedObject_);
134 if (wk.expired()) {
135 // Object expired. Remove the servant and throw.
136 objectExpired();
137 }
138 return wk.lock();
139 }
140
141 bool expired() const final {
142 TWkPtr_t wk((StorageElementWkPtr_t)wrappedObject_);
143 return wk.expired();
144 }
145
146 StorageElementShPtr_t getT() const {
147 StorageElementWkPtr_t wk((StorageElementWkPtr_t)wrappedObject_);
148 if (wk.expired()) {
149 // Object expired. Remove the servant and throw.
150 objectExpired();
151 }
152 return wk.lock();
153 }
154
155 const Storage& getS() const { return wrappedObject_; }
156
158 void persistantStorage(bool persistant) {
159 if (persistant)
160 p_ = get();
161 else
162 p_.reset();
163 }
164
166 bool persistantStorage() const { return p_; }
167
168 void deleteThis() {
169 persistantStorage(false);
170
171 // Object expired. Try to remove the server.
172 PortableServer::Servant servant =
173 dynamic_cast<PortableServer::Servant>(this);
174 if (servant == NULL)
175 throw Error("The object was deleted. I could not delete the servant.");
176 this->server_->removeServant(servant);
177 // Deactivate object
178 PortableServer::ObjectId_var objectId =
179 this->server_->poa()->servant_to_id(servant);
180 this->server_->poa()->deactivate_object(objectId.in());
181 }
182
183 bool deleteIfExpired() {
184 if (expired()) {
185 deleteThis();
186 return true;
187 }
188 return false;
189 }
190
191 protected:
192 ServantBase(Server* server, const Storage& _s)
193 : AbstractServantBase<T>(server), wrappedObject_(_s) {
194 persistantStorage(true);
195 }
196
197 Storage wrappedObject_;
198
199 private:
200 void objectExpired() const {
201 // Object expired. Try to remove the server.
202 PortableServer::Servant servant =
203 dynamic_cast<PortableServer::Servant>(const_cast<ServantBase*>(this));
204 if (servant == NULL)
205 throw Error("The object was deleted. I could not delete the servant.");
206 this->server_->removeServant(servant);
207 // Deactivate object
208 PortableServer::ObjectId_var objectId =
209 this->server_->poa()->servant_to_id(servant);
210 this->server_->poa()->deactivate_object(objectId.in());
211 throw Error("The object has been deleted. I delete the servant.");
212 }
213
214 TShPtr_t p_;
215};
216
232 template <typename T, typename Base>
233 class AbstractStorage {
234 public:
235 typedef weak_ptr<T> ptr_t;
236
237 ptr_t element;
238
239 AbstractStorage(const ptr_t& _element) : element(_element) {}
240 operator shared_ptr<T>() const { return element.lock(); }
241 operator weak_ptr<T>() const { return element; }
242 long use_count() const { return element.use_count(); }
243
244 // Mimic shared_ptr<D> interface:
245 typedef T element_type;
246 operator bool() const { return use_count() > 0; }
247};
248
249 typedef PortableServer::Servant_var<PortableServer::ServantBase>
250 ServantBase_var;
251
252 template <typename S, typename P>
253PortableServer::Servant_var<S> reference_to_servant(Server* server,
254 const P& p) {
255 PortableServer::Servant s = server->poa()->reference_to_servant(p);
256 if (s == NULL) throw Error("The servant is not located here");
257 return dynamic_cast<S*>(s);
258}
259
262 template <typename T, typename P>
263 AbstractServantBase<T>* reference_to_servant_base(Server* server, const P& p) {
264 ServantBase_var s = server->poa()->reference_to_servant(p);
265 if (s.in() == NULL) throw Error("The servant is not located here");
266 return dynamic_cast<AbstractServantBase<T>*>(s.in());
267}
268
278 template <typename P, typename S>
279 P makeServant(Server* server, S* s) {
280 Server::ServantKey servantKey = s->getServantKey();
281 S* servant = dynamic_cast<S*>(server->getServant(servantKey));
282 if (servant != NULL) {
283 delete s;
284 return servant->_this();
285 }
286
287 PortableServer::Servant_var<S> d(s);
288 // ObjectId_var object is here to delete the servantId.
289 PortableServer::ObjectId_var servantId = server->poa()->activate_object(d);
290 (void)servantId;
291
292 server->addServantKeyAndServant(servantKey, d.in());
293 return d->_this();
294}
295
297 namespace details {
299 template <typename U, typename V, template <typename> class StorageTpl>
300 struct storage_cast_impl {
301 static StorageTpl<U> run(const StorageTpl<V>& o) {
302 return o.template cast<U>();
303 }
304};
305
307 template <typename U, typename V>
308 struct storage_cast_impl<U, V, shared_ptr> {
309 static shared_ptr<U> run(const shared_ptr<V>& o) {
310 return dynamic_pointer_cast<U>(o);
311 }
312};
313
315 template <typename U, typename V>
316 struct storage_cast_impl<U, V, weak_ptr> {
317 static weak_ptr<U> run(const weak_ptr<V>& o) {
318 return dynamic_pointer_cast<U>(o.lock());
319 }
320};
321} // namespace details
323
325 template <typename U, typename V, template <typename> class StorageTpl>
326 static StorageTpl<U> storage_cast(const StorageTpl<V>& o) {
327 return details::storage_cast_impl<U, V, StorageTpl>::run(o);
328}
329
332 template <typename T, typename P>
333 auto reference_to_object(Server* server, const P& p) {
334 ServantBase_var s = server->poa()->reference_to_servant(p);
335 if (s.in() == NULL) throw Error("The servant is not located here");
336 typedef typename hpp_traits<T>::Base TBase;
337 AbstractServantBase<TBase>* asb =
338 dynamic_cast<AbstractServantBase<TBase>*>(s.in());
339 if (asb == NULL) throw Error("Not an object of the correct type.");
340 auto ret = storage_cast<T>(asb->get());
341 if (!ret) throw Error("Object is not of the correct type.");
342 return ret;
343}
344
348 template <typename ServantBaseType>
349 class ServantFactoryBase {
350 public:
351 typedef typename ServantBaseType::Storage Storage;
352 typedef typename ServantBaseType::Object_var Object_var;
353
354 ServantFactoryBase(const size_type& depth) : depth_(depth) {}
355
356 virtual Object_var servant(Server* server, const Storage& obj) = 0;
357
361 size_type depth() const { return depth_; }
362
363 private:
364 size_type depth_;
365};
366
367 template <typename ServantBaseType, typename ServantType>
368 struct ServantFactory : ServantFactoryBase<ServantBaseType> {
369 typedef typename ServantBaseType::Object_var Object_var;
370 typedef typename ServantBaseType::Storage StorageBase;
371
372 ServantFactory(const size_type& depth)
373 : ServantFactoryBase<ServantBaseType>(depth) {}
374
375 virtual Object_var servant(Server* s, const StorageBase& o) {
376 typedef typename ServantType::Storage Storage;
377 Storage u = storage_cast<typename Storage::element_type>(o);
378 Object_var ret;
379 if (u.use_count() > 0)
380 ret = makeServant<Object_var>(s, new ServantType(s, u));
381 return ret;
382 }
383};
384
385 template <typename ServantBaseType>
386std::vector<ServantFactoryBase<ServantBaseType>*>& objectDowncasts();
387
388 template <typename ServantBaseType>
389 void addDowncastObjects(ServantFactoryBase<ServantBaseType>* const object) {
390 typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
391 typedef typename vector_t::iterator iterator;
392
393 vector_t& vec = objectDowncasts<ServantBaseType>();
394 size_type d = object->depth();
395 for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
396 if (d >= (*_obj)->depth()) {
397 vec.insert(_obj, object);
398 return;
399 }
400 }
401 vec.push_back(object);
402}
403
406 template <typename ServantBaseType, typename ReturnType>
407 typename ReturnType::Object_var makeServantDownCast(
408 Server* server, const typename ServantBaseType::Storage& t) {
409 typedef typename ServantBaseType::Object_var BaseObject_var;
410 typedef typename ReturnType::Object_var Object_var;
411 BaseObject_var servant;
412 assert(CORBA::Object_Helper::is_nil(servant.in()));
413
414 typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
415 typedef typename vector_t::iterator iterator;
416
417 vector_t& vec = objectDowncasts<ServantBaseType>();
418 for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
419 servant = (*_obj)->servant(server, t);
420 if (!CORBA::Object_Helper::is_nil(servant.in())) {
421 // Cast to child type.
422 return Object_var(ReturnType::Object::_narrow(servant._retn()));
423 }
424 }
425 return Object_var();
426}
427
428 template <typename ServantBaseType>
429 typename ServantBaseType::Object_var makeServantDownCast(
430 Server* server, const typename ServantBaseType::Storage& t) {
431 // TODO
432 // return makeServantDownCast <ServantBaseType, ServantBaseType> (server, t);
433 typedef typename ServantBaseType::Object_var Object_var;
434 Object_var servant;
435 assert(CORBA::Object_Helper::is_nil(servant.in()));
436
437 typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
438 typedef typename vector_t::iterator iterator;
439
440 vector_t& vec = objectDowncasts<ServantBaseType>();
441 for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
442 servant = (*_obj)->servant(server, t);
443 if (!CORBA::Object_Helper::is_nil(servant.in())) break;
444 }
445
446 return servant;
447}
448
449 template <typename OutType, typename InnerBaseType,
450 typename InnerType = InnerBaseType>
451 struct vectorToSeqServant {
452 Server* wrappedObject_;
453
454 vectorToSeqServant(Server* _s) : wrappedObject_(_s) {}
455
456 template <typename InContainer>
457 inline OutType* operator()(const InContainer& input) {
458 std::size_t len = std::distance(input.begin(), input.end());
459 OutType* seq = new OutType();
460 seq->length((CORBA::ULong)len);
461
462 std::size_t i = 0;
463 typename InContainer::const_iterator it = input.begin();
464 while (it != input.end()) {
465 (*seq)[(CORBA::ULong)i] =
466 makeServantDownCast<InnerBaseType, InnerType>(wrappedObject_, *it)
467 ._retn();
468 ++it;
469 ++i;
470 }
471 return seq;
472 }
473};
474
476} // end of namespace corbaServer.
477} // end of namespace hpp.
478
487#define HPP_CORBASERVER_ADD_DOWNCAST_OBJECT(ServantType, BaseServantType, \
488 depth) \
489 struct HPP_CORE_DLLAPI __InitializerClass_##ServantType { \
490 __InitializerClass_##ServantType() { \
491 ::hpp::corbaServer::addDowncastObjects<BaseServantType>( \
492 new ::hpp::corbaServer::ServantFactory<BaseServantType, \
493 ServantType>(depth)); \
494 } \
495 }; \
496 HPP_CORBASERVER_DLLLOCAL __InitializerClass_##ServantType \
497 __instance_##ServantType;
498
499#endif // HPP_CORBASERVER_SERVANT_BASE_HH
hpp::corbaServer::AbstractServantBase
Definition servant-base.hh:104
hpp::corbaServer::AbstractServantBase::TWkPtr_t
weak_ptr< T > TWkPtr_t
Definition servant-base.hh:109
hpp::corbaServer::AbstractServantBase::~AbstractServantBase
virtual ~AbstractServantBase()
Definition servant-base.hh:106
hpp::corbaServer::AbstractServantBase::TShPtr_t
shared_ptr< T > TShPtr_t
Definition servant-base.hh:108
hpp::corbaServer::AbstractServantBase::AbstractServantBase
AbstractServantBase(Server *server)
Definition servant-base.hh:116
hpp::corbaServer::AbstractServantBase::server_
Server * server_
Definition servant-base.hh:118
hpp::corbaServer::AbstractServantBase::get
virtual TShPtr_t get() const =0
hpp::corbaServer::AbstractServantBase::getServantKey
virtual Server::ServantKey getServantKey() const
Definition servant-base.hh:113
hpp::corbaServer::AbstractServantKey
Abstract class used to avoid duplication of the servants.
Definition servant-base.hh:92
hpp::corbaServer::AbstractServantKey::expired
virtual bool expired() const =0
hpp::corbaServer::AbstractServantKey::getServantKey
virtual Server::ServantKey getServantKey() const =0
hpp::corbaServer::AbstractStorage
Definition servant-base.hh:233
hpp::corbaServer::AbstractStorage::use_count
long use_count() const
Definition servant-base.hh:242
hpp::corbaServer::AbstractStorage::ptr_t
weak_ptr< T > ptr_t
Definition servant-base.hh:235
hpp::corbaServer::AbstractStorage::element_type
T element_type
Definition servant-base.hh:245
hpp::corbaServer::AbstractStorage::element
ptr_t element
Definition servant-base.hh:237
hpp::corbaServer::AbstractStorage::AbstractStorage
AbstractStorage(const ptr_t &_element)
Definition servant-base.hh:239
hpp::corbaServer::ServantBase
Definition servant-base.hh:122
hpp::corbaServer::ServantBase::deleteThis
void deleteThis()
Definition servant-base.hh:168
hpp::corbaServer::ServantBase::persistantStorage
bool persistantStorage() const
See persistantStorage(bool)
Definition servant-base.hh:166
hpp::corbaServer::ServantBase::~ServantBase
virtual ~ServantBase()
Definition servant-base.hh:130
hpp::corbaServer::ServantBase::getS
const Storage & getS() const
Definition servant-base.hh:155
hpp::corbaServer::ServantBase::Storage
_Storage Storage
Definition servant-base.hh:124
hpp::corbaServer::ServantBase::wrappedObject_
Storage wrappedObject_
Definition servant-base.hh:197
hpp::corbaServer::ServantBase::deleteIfExpired
bool deleteIfExpired()
Definition servant-base.hh:183
hpp::corbaServer::ServantBase::ServantBase
ServantBase(Server *server, const Storage &_s)
Definition servant-base.hh:192
hpp::corbaServer::ServantBase::StorageElementWkPtr_t
weak_ptr< typename Storage::element_type > StorageElementWkPtr_t
Definition servant-base.hh:127
hpp::corbaServer::ServantBase::StorageElementShPtr_t
shared_ptr< typename Storage::element_type > StorageElementShPtr_t
Definition servant-base.hh:128
hpp::corbaServer::ServantBase::expired
bool expired() const final
Definition servant-base.hh:141
hpp::corbaServer::ServantBase::persistantStorage
void persistantStorage(bool persistant)
Set to true if the servant should take ownership of this object.
Definition servant-base.hh:158
hpp::corbaServer::ServantBase::getT
StorageElementShPtr_t getT() const
Definition servant-base.hh:146
hpp::corbaServer::ServantBase::get
virtual TShPtr_t get() const
Definition servant-base.hh:132
hpp::corbaServer::ServantFactoryBase
Definition servant-base.hh:349
hpp::corbaServer::ServantFactoryBase::Object_var
ServantBaseType::Object_var Object_var
Definition servant-base.hh:352
hpp::corbaServer::ServantFactoryBase::depth
size_type depth() const
Definition servant-base.hh:361
hpp::corbaServer::ServantFactoryBase::ServantFactoryBase
ServantFactoryBase(const size_type &depth)
Definition servant-base.hh:354
hpp::corbaServer::ServantFactoryBase::servant
virtual Object_var servant(Server *server, const Storage &obj)=0
hpp::corbaServer::ServantFactoryBase::Storage
ServantBaseType::Storage Storage
Definition servant-base.hh:351
hpp::corbaServer::Server
Implementation of Hpp module Corba server.
Definition server.hh:78
hpp::corbaServer::Server::removeServant
void removeServant(PortableServer::Servant servant)
hpp::corbaServer::Server::poa
PortableServer::POA_var poa()
Definition server.hh:114
hpp::corbaServer::Server::ServantKey
void * ServantKey
Definition server.hh:161
common-idl.hh
hpp::Error
Corba exception travelling through the Corba channel.
Definition common.idl:27
hpp::corbaServer::makeServantDownCast
ReturnType::Object_var makeServantDownCast(Server *server, const typename ServantBaseType::Storage &t)
Definition servant-base.hh:407
hpp::corbaServer::reference_to_servant
PortableServer::Servant_var< S > reference_to_servant(Server *server, const P &p)
Definition servant-base.hh:253
hpp::corbaServer::makeServant
P makeServant(Server *server, S *s)
Definition servant-base.hh:279
hpp::corbaServer::addDowncastObjects
void addDowncastObjects(ServantFactoryBase< ServantBaseType > *const object)
Definition servant-base.hh:389
hpp::corbaServer::ServantBase_var
PortableServer::Servant_var< PortableServer::ServantBase > ServantBase_var
Definition servant-base.hh:250
hpp::corbaServer::objectDowncasts
std::vector< ServantFactoryBase< ServantBaseType > * > & objectDowncasts()
hpp::corbaServer::reference_to_object
auto reference_to_object(Server *server, const P &p)
Definition servant-base.hh:333
hpp::corbaServer::reference_to_servant_base
AbstractServantBase< T > * reference_to_servant_base(Server *server, const P &p)
Definition servant-base.hh:263
hpp::corbaServer::vector_t
pinocchio::vector_t vector_t
Definition fwd.hh:107
hpp::corbaServer::size_type
pinocchio::size_type size_type
Definition fwd.hh:110
hpp
Implement CORBA interface `‘Obstacle’'.
server.hh
hpp::corbaServer::ServantFactory
Definition servant-base.hh:368
hpp::corbaServer::ServantFactory::StorageBase
ServantBaseType::Storage StorageBase
Definition servant-base.hh:370
hpp::corbaServer::ServantFactory::Object_var
ServantBaseType::Object_var Object_var
Definition servant-base.hh:369
hpp::corbaServer::ServantFactory::ServantFactory
ServantFactory(const size_type &depth)
Definition servant-base.hh:372
hpp::corbaServer::ServantFactory::servant
virtual Object_var servant(Server *s, const StorageBase &o)
Definition servant-base.hh:375
hpp::corbaServer::hpp_traits
Definition servant-base.hh:89
hpp::corbaServer::vectorToSeqServant
Definition servant-base.hh:451
hpp::corbaServer::vectorToSeqServant::operator()
OutType * operator()(const InContainer &input)
Definition servant-base.hh:457
hpp::corbaServer::vectorToSeqServant::wrappedObject_
Server * wrappedObject_
Definition servant-base.hh:452
hpp::corbaServer::vectorToSeqServant::vectorToSeqServant
vectorToSeqServant(Server *_s)
Definition servant-base.hh:454