3 * MICO --- an Open Source CORBA implementation
4 * Copyright (C) 1998 Frank Pilhofer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * For more information, visit the MICO Home Page at
21 * http://www.mico.org/
24 #ifndef __POA_IMPL_H__
25 #define __POA_IMPL_H__
28 #include <mico/impl.h>
31 #include <mico/security/odm_impl.h>
35 * Template definition for Policy objects must be outside
36 * a "struct" (namespace)
39 template<class T, class V>
42 virtual public MICO::Policy_impl
48 POA_Policy (CORBA::PolicyType t, V val)
49 : MICO::Policy_impl(t), _value (val) {};
50 V value () { return _value; };
52 CORBA::Policy_ptr copy ()
54 return new POA_Policy<T,V> (policy_type(), _value);
59 * ----------------------------------------------------------------------
61 * All in the MICOPOA Namespace
63 * ----------------------------------------------------------------------
71 class POACurrent_impl;
74 * Remove all POA options from the command line so that we can delay
75 * the actual POA initialization until a POA is actually needed.
80 CORBA::Boolean parse (CORBA::ORB_ptr, int &, char *[]);
81 const char * operator[] (const char *);
84 std::map<std::string, std::string, std::less<std::string> > options;
87 extern MICO_EXPORT POAOptions poaopts;
90 * ----------------------------------------------------------------------
94 * ----------------------------------------------------------------------
97 typedef POA_Policy<PortableServer::ThreadPolicy, PortableServer::ThreadPolicyValue> ThreadPolicy_impl;
98 typedef POA_Policy<PortableServer::LifespanPolicy, PortableServer::LifespanPolicyValue> LifespanPolicy_impl;
99 typedef POA_Policy<PortableServer::IdUniquenessPolicy, PortableServer::IdUniquenessPolicyValue> IdUniquenessPolicy_impl;
100 typedef POA_Policy<PortableServer::IdAssignmentPolicy, PortableServer::IdAssignmentPolicyValue> IdAssignmentPolicy_impl;
101 typedef POA_Policy<PortableServer::ImplicitActivationPolicy, PortableServer::ImplicitActivationPolicyValue> ImplicitActivationPolicy_impl;
102 typedef POA_Policy<PortableServer::ServantRetentionPolicy, PortableServer::ServantRetentionPolicyValue> ServantRetentionPolicy_impl;
103 typedef POA_Policy<PortableServer::RequestProcessingPolicy, PortableServer::RequestProcessingPolicyValue> RequestProcessingPolicy_impl;
106 * ----------------------------------------------------------------------
108 * POAManager interface
110 * ----------------------------------------------------------------------
113 class POAManager_impl : virtual public PortableServer::POAManager
116 // typedef vector<PortableServer::POA_ptr> POAPtrVec;
120 std::vector<PortableServer::POA_ptr> managed;
122 MICOMT::Mutex managed_lock;
124 void change_state (State,
125 CORBA::Boolean = FALSE,
126 CORBA::Boolean = FALSE);
130 virtual ~POAManager_impl ();
133 void hold_requests (CORBA::Boolean);
134 void discard_requests (CORBA::Boolean);
135 void deactivate (CORBA::Boolean, CORBA::Boolean);
138 // begin-mico-extension
139 void add_managed_poa (PortableServer::POA_ptr);
140 void del_managed_poa (PortableServer::POA_ptr);
141 // end-mico-extension
145 * ----------------------------------------------------------------------
149 * ----------------------------------------------------------------------
153 * Keeps an Object Id as a vector of octets so that we can compare
154 * them faster than using a CORBA sequence. We can then use this
155 * ObjectId as the key in a STL map, which should be implemented
162 ObjectId (const ObjectId &, bool = true);
163 ObjectId (const PortableServer::ObjectId &);
164 ObjectId (const char *, CORBA::ULong, bool = true);
167 ObjectId & operator= (const ObjectId &);
168 CORBA::Boolean operator== (const ObjectId &);
169 bool operator< (const ObjectId &) const;
172 const char * get_data (CORBA::ULong &) const;
173 const PortableServer::ObjectId & get_id ();
176 PortableServer::ObjectId * id ();
181 CORBA::ULong idlength;
182 PortableServer::ObjectId * oid;
186 * Generating and examining Object References
188 * An Object Reference encapsulates the POA's identity (IP address,
189 * PID, fully qualified name) and a unique identifier for the object
193 class POAObjectReference {
195 POAObjectReference (POA_impl *,
196 const PortableServer::ObjectId &,
198 PortableServer::Servant = NULL);
199 POAObjectReference (POA_impl *, CORBA::Object_ptr);
200 POAObjectReference (const POAObjectReference &);
201 ~POAObjectReference ();
205 POAObjectReference & operator= (const CORBA::Object_ptr);
206 POAObjectReference & operator= (const POAObjectReference &);
209 const ObjectId & get_oid ();
210 CORBA::Object_ptr get_ref ();
211 void set_ref (CORBA::Object_ptr);
212 const PortableServer::ObjectId & get_id ();
215 CORBA::Object_ptr ref ();
216 PortableServer::ObjectId * id ();
218 // which POA do we belong to?
219 const char * poa_name ();
220 bool in_poa (const char *);
221 bool in_descendant_poa (const char *, const char *);
222 char * next_descendant_poa (const char *, const char *);
225 MICOMT::Mutex _ref_lock;
228 bool decompose_ref ();
243 MICOPOA::ObjectId oid;
244 CORBA::Object_ptr obj;
245 PortableServer::Servant servant;
249 * Data structure for our Active Object Map.
251 * We maintain two maps so that we can search efficiently for Object Ids
257 struct DeletionRecord {
260 MICOMT::CondVar condition;
262 DeletionRecord(MICOMT::Mutex* m)
263 : cnt(0), signal(0), condition(m)
267 struct ObjectRecord {
268 ObjectRecord (POAObjectReference *,
269 PortableServer::Servant = NULL);
272 CORBA::Boolean active;
273 CORBA::Long invoke_cnt;
274 DeletionRecord * delref;
276 POAObjectReference * por;
277 PortableServer::Servant serv;
280 typedef std::map<ObjectId, ObjectRecord *, std::less<ObjectId> > IdMap;
281 typedef IdMap::iterator iterator;
292 ObjectRecord * pop ();
294 ObjectRecord * add (POAObjectReference *, PortableServer::Servant);
295 ObjectRecord * del (const ObjectId &);
296 ObjectRecord * del (const PortableServer::ObjectId &);
298 bool exists (const ObjectId &);
299 bool exists (const PortableServer::ObjectId &);
300 bool exists (const POAObjectReference &);
301 bool exists (PortableServer::Servant);
303 ObjectRecord * find (const ObjectId &);
304 ObjectRecord * find (const PortableServer::ObjectId &);
305 ObjectRecord * find (const POAObjectReference &);
306 ObjectRecord * find (POA_impl *, CORBA::Object_ptr);
307 ObjectRecord * find (PortableServer::Servant);
310 typedef std::map<PortableServer::Servant, std::vector<ObjectRecord *>,
311 std::less<PortableServer::Servant> > SvMap;
318 * Unique Id generator. Can an ULong as Id be too weak? Sure!
321 class UniqueIdGenerator {
323 UniqueIdGenerator ();
324 UniqueIdGenerator (const char *);
325 ~UniqueIdGenerator ();
330 void state (const char *);
339 * ----------------------------------------------------------------------
343 * ----------------------------------------------------------------------
350 class POA_impl : public PortableServer::POA,
351 public CORBA::ObjectAdapter
355 * InvocationRecord to queue incoming invocations
358 class InvocationRecord;
359 typedef InvocationRecord *InvocationRecord_ptr;
360 typedef ObjVar<InvocationRecord> InvocationRecord_var;
362 class InvocationRecord : public CORBA::ServerlessObject {
364 InvocationRecord (CORBA::ORBMsgId,
365 POAObjectReference *,
367 CORBA::Principal_ptr);
368 ~InvocationRecord ();
370 void exec (POA_impl *);
372 CORBA::ORBMsgId id ();
373 CORBA::ORBRequest * get_or ();
374 POAObjectReference * get_por ();
375 CORBA::ServerRequestBase_ptr make_req (POA_impl *,
376 PortableServer::Servant);
377 CORBA::ServerRequest_ptr make_dyn_req (POA_impl *);
379 static InvocationRecord_ptr _duplicate (InvocationRecord_ptr o)
385 static InvocationRecord_ptr _nil ()
391 CORBA::ORBMsgId orbid;
392 POAObjectReference * por;
393 CORBA::ORBRequest * req;
394 CORBA::Principal_ptr pr;
395 CORBA::ServerRequestBase_ptr svr;
403 PortableServer::ThreadPolicy_var thread_policy;
404 PortableServer::LifespanPolicy_var lifespan_policy;
405 PortableServer::IdUniquenessPolicy_var id_uniqueness_policy;
406 PortableServer::IdAssignmentPolicy_var id_assignment_policy;
407 PortableServer::ImplicitActivationPolicy_var implicit_activation_policy;
408 PortableServer::ServantRetentionPolicy_var servant_retention_policy;
409 PortableServer::RequestProcessingPolicy_var request_processing_policy;
415 std::string name; // name relative to parent
416 std::string fqn; // fully qualified name
417 std::string oaid; // Unique Identifier
418 static std::string oaprefix; // Prefix for Unique Names
421 PortableServer::POAManager_ptr manager;
422 PortableServer::Servant default_servant;
423 PortableServer::ServantManager_var servant_manager;
424 static MICOMT::Mutex S_servant_manager_lock;
425 PortableServer::AdapterActivator_var adapter_activator;
431 static std::string impl_name;
432 static CORBA::IOR poamed_ior;
433 static CORBA::POAMediator_var poamed;
434 static CORBA::Boolean ever_been_active;
441 MICOMT::RWLock destroy_lock_;
442 CORBA::ULong unique_id;
445 ObjectMap ActiveObjectMap;
446 MICOMT::Mutex ObjectActivationLock;
448 std::vector<InvocationRecord_ptr> InvocationQueue;
449 PortableServer::POAManager::State state;
454 MICOMT::Mutex serialize_invoke;
455 static MICOMT::Mutex S_global_invoke_lock;
458 * Map of our children
461 typedef std::map<std::string, POA_impl *, std::less<std::string> > POAMap;
463 void register_child (const char *, POA_impl *);
464 void unregister_child (const char *);
472 static void register_poa (const char *, POA_impl *);
473 static void unregister_poa (const char *);
475 static POAMap AllPOAs;
476 static UniqueIdGenerator poauid;
477 static UniqueIdGenerator idfactory;
483 static POACurrent_impl * current;
486 #ifdef HAVE_SSL // ###ras
488 MICOSODM::Manager_impl* odm_manager_;
490 MICOSODM::Factory_impl* odm_factory_;
498 void set_policies (const CORBA::PolicyList &);
501 POA_impl * _find_POA (const char *, CORBA::Boolean);
504 * Constructor for my children
507 POA_impl (const char *,
508 PortableServer::POAManager_ptr,
509 const CORBA::PolicyList &,
515 * private object activation and deactivation
517 PortableServer::ObjectId * __activate_object (PortableServer::Servant);
518 void remove_object (const PortableServer::ObjectId & id);
521 POA_impl (CORBA::ORB_ptr);
522 virtual ~POA_impl ();
525 * POA creation and destruction
528 PortableServer::POA_ptr create_POA (const char *,
529 PortableServer::POAManager_ptr,
530 const CORBA::PolicyList &);
531 PortableServer::POA_ptr find_POA (const char *,
533 void destroy (CORBA::Boolean, CORBA::Boolean);
540 PortableServer::POA_ptr the_parent ();
541 PortableServer::POAManager_ptr the_POAManager ();
542 PortableServer::AdapterActivator_ptr the_activator ();
543 PortableServer::POAList * the_children ();
544 void the_activator (PortableServer::AdapterActivator_ptr);
545 CORBA::OctetSeq* id();
548 * Factories for Policy objects
551 PortableServer::ThreadPolicy_ptr create_thread_policy (PortableServer::ThreadPolicyValue);
552 PortableServer::LifespanPolicy_ptr create_lifespan_policy (PortableServer::LifespanPolicyValue);
553 PortableServer::IdUniquenessPolicy_ptr create_id_uniqueness_policy (PortableServer::IdUniquenessPolicyValue);
554 PortableServer::IdAssignmentPolicy_ptr create_id_assignment_policy (PortableServer::IdAssignmentPolicyValue);
555 PortableServer::ImplicitActivationPolicy_ptr create_implicit_activation_policy (PortableServer::ImplicitActivationPolicyValue);
556 PortableServer::ServantRetentionPolicy_ptr create_servant_retention_policy (PortableServer::ServantRetentionPolicyValue);
557 PortableServer::RequestProcessingPolicy_ptr create_request_processing_policy (PortableServer::RequestProcessingPolicyValue);
560 * ServantManager registration
563 PortableServer::ServantManager_ptr get_servant_manager ();
564 void set_servant_manager (PortableServer::ServantManager_ptr);
567 * Default servant registration
570 PortableServer::Servant get_servant ();
571 void set_servant (PortableServer::Servant);
574 * object activation and deactivation
577 PortableServer::ObjectId * activate_object (PortableServer::Servant);
578 void activate_object_with_id (const PortableServer::ObjectId &,
579 PortableServer::Servant);
581 void deactivate_object (const PortableServer::ObjectId &);
584 * Reference creation operations
587 CORBA::Object_ptr create_reference (const char *);
588 CORBA::Object_ptr create_reference_with_id (const PortableServer::ObjectId &,
592 * Perform activation upon _this();
595 CORBA::Object_ptr activate_for_this (PortableServer::Servant);
601 CORBA::IOR * ior_template ();
604 * Identity mapping operations
607 PortableServer::ObjectId * servant_to_id (PortableServer::Servant);
608 CORBA::Object_ptr servant_to_reference (PortableServer::Servant);
609 PortableServer::Servant reference_to_servant (CORBA::Object_ptr);
610 PortableServer::ObjectId * reference_to_id (CORBA::Object_ptr);
611 PortableServer::Servant id_to_servant (const PortableServer::ObjectId &);
612 CORBA::Object_ptr id_to_reference (const PortableServer::ObjectId &);
615 * POA Manager callback
618 void poa_manager_callback (PortableServer::POAManager::State,
619 CORBA::Boolean, CORBA::Boolean);
622 * Service for colocated stubs
625 PortableServer::Servant preinvoke (CORBA::Object_ptr);
629 * ObjectAdapter Interface
632 const char * get_oaid () const;
633 CORBA::Boolean has_object (CORBA::Object_ptr);
634 CORBA::Boolean is_local () const;
637 CORBA::Principal_ptr get_principal (CORBA::Object_ptr);
638 #endif /* USE_CSL2 */
640 CORBA::Boolean invoke (CORBA::ORBMsgId,
643 CORBA::Principal_ptr,
644 CORBA::Boolean = TRUE);
645 CORBA::Boolean bind (CORBA::ORBMsgId, const char *,
646 const CORBA::ORB::ObjectTag &,
648 CORBA::Boolean locate (CORBA::ORBMsgId, CORBA::Object_ptr);
649 CORBA::Object_ptr skeleton (CORBA::Object_ptr);
651 void cancel (CORBA::ORBMsgId);
652 void shutdown (CORBA::Boolean);
654 void answer_invoke (CORBA::ORBMsgId, CORBA::Object_ptr,
656 CORBA::InvokeStatus);
660 virtual void register_ODM_factory(ObjectDomainMapping::Factory_ptr fry);
661 virtual ObjectDomainMapping::Manager_ptr get_ODM();
662 #endif /* USE_CSL2 */
665 * Helper functions for OA interface
668 void builtin_is_a (InvocationRecord_ptr, PortableServer::Servant);
669 void builtin_interface (InvocationRecord_ptr, PortableServer::Servant);
670 void builtin_component (InvocationRecord_ptr, PortableServer::Servant);
671 void builtin_non_existent (InvocationRecord_ptr, PortableServer::Servant);
672 bool builtin_invoke (InvocationRecord_ptr, PortableServer::Servant);
674 bool is_builtin (InvocationRecord_ptr);
675 void local_invoke (InvocationRecord_ptr);
676 void perform_invoke (InvocationRecord_ptr);
680 * ----------------------------------------------------------------------
684 * ----------------------------------------------------------------------
687 class POACurrent_impl : public PortableServer::Current
692 struct CurrentState {
694 CurrentState (PortableServer::POA_ptr,
695 POAObjectReference *,
696 PortableServer::Servant);
697 CurrentState (const CurrentState &);
699 PortableServer::POA_ptr poa;
700 POAObjectReference * por;
701 PortableServer::Servant serv;
705 typedef std::vector<CurrentState> CurrentStateStack;
709 CurrentStateStack* state_stack_;
710 #else // HAVE_THREADS
711 MICOMT::Thread::ThreadKey current_key_;
712 #endif // HAVE_THREADS
715 POACurrent_impl (CORBA::ORB_ptr);
718 PortableServer::POA_ptr get_POA ();
719 PortableServer::ObjectId * get_object_id ();
720 CORBA::Object_ptr get_reference();
721 PortableServer::Servant get_servant();
722 // begin-mico-extension
723 CORBA::Boolean iscurrent ();
724 POAObjectReference * get_por ();
726 void set (PortableServer::POA_ptr, POAObjectReference *,
727 PortableServer::Servant);
732 // In single thread mode, only one POA can be active at any given time
733 // a stack of POA/Currents is OK here, because nested invocation are not possible
735 CurrentStateStack* get_current()
736 { return state_stack_; }
738 void set_current(CurrentStateStack* stack)
739 { state_stack_ = stack; }
741 #else // HAVE_THREADS
743 // In multi threaded mode, more than one POA can be active (doing invocations),
744 // but there can be only one active Object per thread
746 CurrentStateStack* get_current()
747 { return static_cast<CurrentStateStack *>(MICOMT::Thread::get_specific(current_key_)); }
749 void set_current(CurrentStateStack* current)
750 { MICOMT::Thread::set_specific(current_key_, current); }
752 #endif // HAVE_THREADS
753 // end-mico-extension
756 } // namespace MICOPOA