1 #include "tao/PI/PICurrent_Impl.h"
3 #if TAO_HAS_INTERCEPTORS == 1
5 #include "tao/ORB_Core.h"
7 #if !defined (__ACE_INLINE__)
8 # include "tao/PI/PICurrent_Impl.inl"
9 #endif /* __ACE_INLINE__ */
11 #include "tao/TAO_Server_Request.h"
12 #include "ace/Log_Msg.h"
13 #include "tao/debug.h"
14 #include "ace/CORBA_macros.h"
16 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
19 TAO::PICurrent_Impl::get_slot (PortableInterceptor::SlotId identifier
)
21 // No need to check validity of SlotId. It is validated before this
24 // The active slot table should never be a lazy copy of itself!
25 if ( (0 != this->lazy_copy_
)
26 && (&this->lazy_copy_
->current_slot_table () == &this->slot_table_
))
28 if (TAO_debug_level
> 0)
29 TAOLIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("TAO (%P|%t) Lazy copy of self detected at %N,%l\n")));
30 throw ::CORBA::INTERNAL ();
33 // Get the slot table that is currently active
34 PICurrent_Impl::Table
& table
= this->current_slot_table ();
37 if (identifier
< table
.size ())
39 ACE_NEW_THROW_EX (any
,
40 CORBA::Any (table
[identifier
]), // Make a copy.
42 CORBA::SystemException::_tao_minor_code (
45 CORBA::COMPLETED_NO
));
49 // In accordance with the Portable Interceptor specification,
50 // return an Any with a TCKind of tk_null. A default
51 // constructed Any has that TCKind.
52 ACE_NEW_THROW_EX (any
,
55 CORBA::SystemException::_tao_minor_code (
58 CORBA::COMPLETED_NO
));
65 TAO::PICurrent_Impl::set_slot (PortableInterceptor::SlotId identifier
,
66 const CORBA::Any
& data
)
68 // No need to check validity of SlotId. It is validated before this
71 // Break any existing ties that another PICurrent has with our table
72 // since our table is changing.
73 if (0 != this->impending_change_callback_
)
74 this->impending_change_callback_
->convert_from_lazy_to_real_copy ();
76 // Ensure that we have a real physical copy of the table before
77 // making any changes to it.
78 this->convert_from_lazy_to_real_copy ();
80 // If the slot table array isn't large enough, then increase its
81 // size. We're guaranteed not to exceed the number of allocated
82 // slots for the reason stated above.
83 if (identifier
>= this->slot_table_
.size ()
84 && this->slot_table_
.size (identifier
+ 1) != 0)
85 throw ::CORBA::INTERNAL ();
87 this->slot_table_
[identifier
] = CORBA::Any (data
);
91 TAO::PICurrent_Impl::take_lazy_copy (
92 TAO::PICurrent_Impl
* p
)
94 // Check that we are being told to actually change which table we are
95 // copying from. (If it is the same as before OR it would ultimately be
96 // the same table, we are already correctly setup and we do nothing.)
97 if ( (p
!= this->lazy_copy_
)
98 && ((0 == p
) || (&p
->current_slot_table () != &this->current_slot_table ()))
101 // Break any existing ties that another PICurrent has with our table
102 // since our table is changing.
103 if (0 != this->impending_change_callback_
)
104 this->impending_change_callback_
->convert_from_lazy_to_real_copy ();
106 // If we have previously logically copied another table, ensure it is
107 // told that we are no longer interested in it so that it will not
108 // call our conver_from_lazy_to_real_copy() when it changes/destructs.
109 if (0 != this->lazy_copy_
)
110 this->lazy_copy_
->set_callback_for_impending_change (0);
112 // Are we being asked to copy ourself (or nothing)
113 if ((0 == p
) || (this == p
))
115 this->lazy_copy_
= 0; // Use our own physical slot_table_
119 this->lazy_copy_
= p
;
121 // Must tell the newly copied PICurrent_Impl that we want to
122 // be told when/if it is going to be changed or destroyed.
123 this->lazy_copy_
->set_callback_for_impending_change (this);
128 TAO::PICurrent_Impl::~PICurrent_Impl ()
132 // We have YOUNGER stack members to REMOVE as well. HOWEVER we
133 // don't want the entry above us coming back down and trying
134 // to delete us again. (As we are currently doing just that.)
135 this->push_
->pop_
= 0;
139 else if (this->orb_core_
)
141 // Since there are no entries above us, we must be the top of
142 // the stack and since all are being deleted, the stack will
144 this->orb_core_
->set_tss_resource (this->tss_slot_
, 0);
147 // Break any existing ties that another PICurrent has with our table
148 // since our table will no longer exists once this destructor completes.
149 if (0 != this->impending_change_callback_
)
150 this->impending_change_callback_
->convert_from_lazy_to_real_copy ();
152 // If we have logically copied another table, ensure it is told about our
153 // demise so that it will not call our non-existent
154 // convert_from_lazy_to_real_copy() when it changes/destructs.
155 if (0 != this->lazy_copy_
)
156 this->lazy_copy_
->set_callback_for_impending_change (0);
160 // We have OLDER stack members to REMOVE as well. HOWEVER we
161 // don't want multiple adjustments of the stack head pointer from
162 // every older entry as they delete, as this requires multiple
163 // set_tss_resource updates which would be slow and unnecessary.
164 this->pop_
->orb_core_
= 0;
166 // We also don't want double deletions of what used to be above these
167 // since we have just completed the deletion of these ourselves.
168 this->pop_
->push_
= 0;
174 TAO::PICurrent_Impl::push ()
176 if (this->orb_core_
) // We have a stack to adjust
178 TAO::PICurrent_Impl
*const currentHead
=
179 static_cast<TAO::PICurrent_Impl
*> (
180 this->orb_core_
->get_tss_resource (this->tss_slot_
));
181 if (!currentHead
->push_
)
183 // Since there is nothing younger above us, we need to create
185 ACE_NEW_THROW_EX (currentHead
->push_
,
186 PICurrent_Impl (this->orb_core_
, this->tss_slot_
, currentHead
),
188 CORBA::SystemException::_tao_minor_code (
191 CORBA::COMPLETED_NO
));
193 this->orb_core_
->set_tss_resource (this->tss_slot_
, currentHead
->push_
);
196 throw ::CORBA::INTERNAL (); // Should only call push if we have a stack
200 TAO::PICurrent_Impl::pop ()
202 if (this->orb_core_
) // We have a stack to adjust
204 TAO::PICurrent_Impl
*const currentHead
=
205 static_cast<TAO::PICurrent_Impl
*> (
206 this->orb_core_
->get_tss_resource (this->tss_slot_
));
207 if (currentHead
->pop_
)
208 orb_core_
->set_tss_resource (tss_slot_
, currentHead
->pop_
);
210 throw ::CORBA::INTERNAL (); // Too many pop's
213 throw ::CORBA::INTERNAL (); // Should only call push if we have a stack
216 TAO_END_VERSIONED_NAMESPACE_DECL
218 #endif /* TAO_HAS_INTERCEPTORS == 1 */