hpp-corbaserver 4.14.0
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>
39
40namespace hpp {
41namespace 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
88template <typename T>
89struct hpp_traits {};
90
93 public:
94 virtual Server::ServantKey getServantKey() const = 0;
95};
96
101template <typename T>
103 public:
105
106 typedef shared_ptr<T> TShPtr_t;
107 typedef weak_ptr<T> TWkPtr_t;
108
109 virtual TShPtr_t get() const = 0;
110
111 virtual Server::ServantKey getServantKey() const { return get().get(); }
112
113 protected:
114 AbstractServantBase(Server* server) : server_(server) {}
115
117};
118
119template <typename T, typename _Storage>
121 public:
122 typedef _Storage Storage;
125 typedef weak_ptr<typename Storage::element_type> StorageElementWkPtr_t;
126 typedef shared_ptr<typename Storage::element_type> StorageElementShPtr_t;
127
128 virtual ~ServantBase() {}
129
130 virtual TShPtr_t get() const {
132 if (wk.expired()) {
133 // Object expired. Remove the servant and throw.
134 objectExpired();
135 }
136 return wk.lock();
137 }
138
141 if (wk.expired()) {
142 // Object expired. Remove the servant and throw.
143 objectExpired();
144 }
145 return wk.lock();
146 }
147
148 const Storage& getS() const { return wrappedObject_; }
149
151 void persistantStorage(bool persistant) {
152 if (persistant)
153 p_ = get();
154 else
155 p_.reset();
156 }
157
159 bool persistantStorage() const { return p_; }
160
161 void deleteThis() {
162 persistantStorage(false);
163
164 // Object expired. Try to remove the server.
165 PortableServer::Servant servant =
166 dynamic_cast<PortableServer::Servant>(this);
167 if (servant == NULL)
168 throw Error("The object was deleted. I could not delete the servant.");
169 this->server_->removeServant(servant);
170 // Deactivate object
171 PortableServer::ObjectId_var objectId =
172 this->server_->poa()->servant_to_id(servant);
173 this->server_->poa()->deactivate_object(objectId.in());
174 }
175
176 protected:
177 ServantBase(Server* server, const Storage& _s)
178 : AbstractServantBase<T>(server), wrappedObject_(_s) {
179 persistantStorage(true);
180 }
181
183
184 private:
185 void objectExpired() const {
186 // Object expired. Try to remove the server.
187 PortableServer::Servant servant =
188 dynamic_cast<PortableServer::Servant>(const_cast<ServantBase*>(this));
189 if (servant == NULL)
190 throw Error("The object was deleted. I could not delete the servant.");
191 this->server_->removeServant(servant);
192 // Deactivate object
193 PortableServer::ObjectId_var objectId =
194 this->server_->poa()->servant_to_id(servant);
195 this->server_->poa()->deactivate_object(objectId.in());
196 throw Error("The object has been deleted. I delete the servant.");
197 }
198
199 TShPtr_t p_;
200};
201
217template <typename T, typename Base>
219 public:
220 typedef weak_ptr<T> ptr_t;
221
223
224 AbstractStorage(const ptr_t& _element) : element(_element) {}
225 operator shared_ptr<T>() const { return element.lock(); }
226 operator weak_ptr<T>() const { return element; }
227 long use_count() const { return element.use_count(); }
228
229 // Mimic shared_ptr<D> interface:
230 typedef T element_type;
231 operator bool() const { return use_count() > 0; }
232};
233
234typedef PortableServer::Servant_var<PortableServer::ServantBase>
236
237template <typename S, typename P>
238PortableServer::Servant_var<S> reference_to_servant(Server* server,
239 const P& p) {
240 PortableServer::Servant s = server->poa()->reference_to_servant(p);
241 if (s == NULL) throw Error("The servant is not located here");
242 return dynamic_cast<S*>(s);
243}
244
247template <typename T, typename P>
249 ServantBase_var s = server->poa()->reference_to_servant(p);
250 if (s.in() == NULL) throw Error("The servant is not located here");
251 return dynamic_cast<AbstractServantBase<T>*>(s.in());
252}
253
263template <typename P, typename S>
264P makeServant(Server* server, S* s) {
265 Server::ServantKey servantKey = s->getServantKey();
266 S* servant = dynamic_cast<S*>(server->getServant(servantKey));
267 if (servant != NULL) {
268 delete s;
269 return servant->_this();
270 }
271
272 PortableServer::Servant_var<S> d(s);
273 // ObjectId_var object is here to delete the servantId.
274 PortableServer::ObjectId_var servantId = server->poa()->activate_object(d);
275 (void)servantId;
276
277 server->addServantKeyAndServant(servantKey, d.in());
278 return d->_this();
279}
280
282namespace details {
284template <typename U, typename V, template <typename> class StorageTpl>
285struct storage_cast_impl {
286 static StorageTpl<U> run(const StorageTpl<V>& o) {
287 return o.template cast<U>();
288 }
289};
290
292template <typename U, typename V>
293struct storage_cast_impl<U, V, shared_ptr> {
294 static shared_ptr<U> run(const shared_ptr<V>& o) {
295 return dynamic_pointer_cast<U>(o);
296 }
297};
298
300template <typename U, typename V>
301struct storage_cast_impl<U, V, weak_ptr> {
302 static weak_ptr<U> run(const weak_ptr<V>& o) {
303 return dynamic_pointer_cast<U>(o.lock());
304 }
305};
306} // namespace details
308
310template <typename U, typename V, template <typename> class StorageTpl>
311static StorageTpl<U> storage_cast(const StorageTpl<V>& o) {
312 return details::storage_cast_impl<U, V, StorageTpl>::run(o);
313}
314
317template <typename T, typename P>
318auto reference_to_object(Server* server, const P& p) {
319 ServantBase_var s = server->poa()->reference_to_servant(p);
320 if (s.in() == NULL) throw Error("The servant is not located here");
321 typedef typename hpp_traits<T>::Base TBase;
323 dynamic_cast<AbstractServantBase<TBase>*>(s.in());
324 if (asb == NULL) throw Error("Not an object of the correct type.");
325 auto ret = storage_cast<T>(asb->get());
326 if (!ret) throw Error("Object is not of the correct type.");
327 return ret;
328}
329
333template <typename ServantBaseType>
335 public:
336 typedef typename ServantBaseType::Storage Storage;
337 typedef typename ServantBaseType::Object_var Object_var;
338
340
341 virtual Object_var servant(Server* server, const Storage& obj) = 0;
342
346 size_type depth() const { return depth_; }
347
348 private:
349 size_type depth_;
350};
351
352template <typename ServantBaseType, typename ServantType>
353struct ServantFactory : ServantFactoryBase<ServantBaseType> {
354 typedef typename ServantBaseType::Object_var Object_var;
355 typedef typename ServantBaseType::Storage StorageBase;
356
358 : ServantFactoryBase<ServantBaseType>(depth) {}
359
360 virtual Object_var servant(Server* s, const StorageBase& o) {
361 typedef typename ServantType::Storage Storage;
362 Storage u = storage_cast<typename Storage::element_type>(o);
363 Object_var ret;
364 if (u.use_count() > 0)
365 ret = makeServant<Object_var>(s, new ServantType(s, u));
366 return ret;
367 }
368};
369
370template <typename ServantBaseType>
371std::vector<ServantFactoryBase<ServantBaseType>*>& objectDowncasts();
372
373template <typename ServantBaseType>
375 typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
376 typedef typename vector_t::iterator iterator;
377
378 vector_t& vec = objectDowncasts<ServantBaseType>();
379 size_type d = object->depth();
380 for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
381 if (d >= (*_obj)->depth()) {
382 vec.insert(_obj, object);
383 return;
384 }
385 }
386 vec.push_back(object);
387}
388
391template <typename ServantBaseType, typename ReturnType>
392typename ReturnType::Object_var makeServantDownCast(
393 Server* server, const typename ServantBaseType::Storage& t) {
394 typedef typename ServantBaseType::Object_var BaseObject_var;
395 typedef typename ReturnType::Object_var Object_var;
396 BaseObject_var servant;
397 assert(CORBA::Object_Helper::is_nil(servant.in()));
398
399 typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
400 typedef typename vector_t::iterator iterator;
401
402 vector_t& vec = objectDowncasts<ServantBaseType>();
403 for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
404 servant = (*_obj)->servant(server, t);
405 if (!CORBA::Object_Helper::is_nil(servant.in())) {
406 // Cast to child type.
407 return Object_var(ReturnType::Object::_narrow(servant._retn()));
408 }
409 }
410 return Object_var();
411}
412
413template <typename ServantBaseType>
414typename ServantBaseType::Object_var makeServantDownCast(
415 Server* server, const typename ServantBaseType::Storage& t) {
416 // TODO
417 // return makeServantDownCast <ServantBaseType, ServantBaseType> (server, t);
418 typedef typename ServantBaseType::Object_var Object_var;
419 Object_var servant;
420 assert(CORBA::Object_Helper::is_nil(servant.in()));
421
422 typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
423 typedef typename vector_t::iterator iterator;
424
425 vector_t& vec = objectDowncasts<ServantBaseType>();
426 for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
427 servant = (*_obj)->servant(server, t);
428 if (!CORBA::Object_Helper::is_nil(servant.in())) break;
429 }
430
431 return servant;
432}
433
434template <typename OutType, typename InnerBaseType,
435 typename InnerType = InnerBaseType>
438
440
441 template <typename InContainer>
442 inline OutType* operator()(const InContainer& input) {
443 std::size_t len = std::distance(input.begin(), input.end());
444 OutType* seq = new OutType();
445 seq->length((CORBA::ULong)len);
446
447 std::size_t i = 0;
448 typename InContainer::const_iterator it = input.begin();
449 while (it != input.end()) {
450 (*seq)[(CORBA::ULong)i] =
451 makeServantDownCast<InnerBaseType, InnerType>(wrappedObject_, *it)
452 ._retn();
453 ++it;
454 ++i;
455 }
456 return seq;
457 }
458};
459
461} // end of namespace corbaServer.
462} // end of namespace hpp.
463
472#define HPP_CORBASERVER_ADD_DOWNCAST_OBJECT(ServantType, BaseServantType, \
473 depth) \
474 struct HPP_CORE_DLLAPI __InitializerClass_##ServantType { \
475 __InitializerClass_##ServantType() { \
476 ::hpp::corbaServer::addDowncastObjects<BaseServantType>( \
477 new ::hpp::corbaServer::ServantFactory<BaseServantType, \
478 ServantType>(depth)); \
479 } \
480 }; \
481 HPP_CORBASERVER_DLLLOCAL __InitializerClass_##ServantType \
482 __instance_##ServantType;
483
484#endif // HPP_CORBASERVER_SERVANT_BASE_HH
Definition: servant-base.hh:102
weak_ptr< T > TWkPtr_t
Definition: servant-base.hh:107
virtual ~AbstractServantBase()
Definition: servant-base.hh:104
shared_ptr< T > TShPtr_t
Definition: servant-base.hh:106
AbstractServantBase(Server *server)
Definition: servant-base.hh:114
Server * server_
Definition: servant-base.hh:116
virtual TShPtr_t get() const =0
virtual Server::ServantKey getServantKey() const
Definition: servant-base.hh:111
Abstract class used to avoid duplication of the servants.
Definition: servant-base.hh:92
virtual Server::ServantKey getServantKey() const =0
Definition: servant-base.hh:218
long use_count() const
Definition: servant-base.hh:227
weak_ptr< T > ptr_t
Definition: servant-base.hh:220
T element_type
Definition: servant-base.hh:230
ptr_t element
Definition: servant-base.hh:222
AbstractStorage(const ptr_t &_element)
Definition: servant-base.hh:224
Definition: servant-base.hh:120
void deleteThis()
Definition: servant-base.hh:161
bool persistantStorage() const
See persistantStorage(bool)
Definition: servant-base.hh:159
virtual ~ServantBase()
Definition: servant-base.hh:128
const Storage & getS() const
Definition: servant-base.hh:148
_Storage Storage
Definition: servant-base.hh:122
Storage wrappedObject_
Definition: servant-base.hh:182
ServantBase(Server *server, const Storage &_s)
Definition: servant-base.hh:177
weak_ptr< typename Storage::element_type > StorageElementWkPtr_t
Definition: servant-base.hh:125
shared_ptr< typename Storage::element_type > StorageElementShPtr_t
Definition: servant-base.hh:126
void persistantStorage(bool persistant)
Set to true if the servant should take ownership of this object.
Definition: servant-base.hh:151
StorageElementShPtr_t getT() const
Definition: servant-base.hh:139
virtual TShPtr_t get() const
Definition: servant-base.hh:130
Definition: servant-base.hh:334
ServantBaseType::Object_var Object_var
Definition: servant-base.hh:337
size_type depth() const
Definition: servant-base.hh:346
ServantFactoryBase(const size_type &depth)
Definition: servant-base.hh:339
virtual Object_var servant(Server *server, const Storage &obj)=0
ServantBaseType::Storage Storage
Definition: servant-base.hh:336
Implementation of Hpp module Corba server.
Definition: server.hh:77
PortableServer::Servant getServant(ServantKey servantKey) const
void addServantKeyAndServant(ServantKey servantKey, PortableServer::Servant servant)
void removeServant(PortableServer::Servant servant)
PortableServer::POA_var poa()
Definition: server.hh:110
void * ServantKey
Definition: server.hh:157
Corba exception travelling through the Corba channel.
Definition: common.idl:27
ReturnType::Object_var makeServantDownCast(Server *server, const typename ServantBaseType::Storage &t)
Definition: servant-base.hh:392
PortableServer::Servant_var< S > reference_to_servant(Server *server, const P &p)
Definition: servant-base.hh:238
P makeServant(Server *server, S *s)
Definition: servant-base.hh:264
void addDowncastObjects(ServantFactoryBase< ServantBaseType > *const object)
Definition: servant-base.hh:374
PortableServer::Servant_var< PortableServer::ServantBase > ServantBase_var
Definition: servant-base.hh:235
std::vector< ServantFactoryBase< ServantBaseType > * > & objectDowncasts()
auto reference_to_object(Server *server, const P &p)
Definition: servant-base.hh:318
AbstractServantBase< T > * reference_to_servant_base(Server *server, const P &p)
Definition: servant-base.hh:248
pinocchio::vector_t vector_t
Definition: fwd.hh:112
pinocchio::size_type size_type
Definition: fwd.hh:115
Implement CORBA interface `‘Obstacle’'.
Definition: basic-server.hh:35
Definition: servant-base.hh:353
ServantBaseType::Storage StorageBase
Definition: servant-base.hh:355
ServantBaseType::Object_var Object_var
Definition: servant-base.hh:354
ServantFactory(const size_type &depth)
Definition: servant-base.hh:357
virtual Object_var servant(Server *s, const StorageBase &o)
Definition: servant-base.hh:360
Definition: servant-base.hh:89
Definition: servant-base.hh:436
OutType * operator()(const InContainer &input)
Definition: servant-base.hh:442
Server * wrappedObject_
Definition: servant-base.hh:437
vectorToSeqServant(Server *_s)
Definition: servant-base.hh:439