00001 // Policy_Set.cpp,v 1.17 2006/04/19 08:55:30 jwillemsen Exp 00002 00003 #include "tao/Policy_Set.h" 00004 #include "tao/Environment.h" 00005 #include "tao/SystemException.h" 00006 #include "tao/debug.h" 00007 00008 #if !defined (__ACE_INLINE__) 00009 # include "tao/Policy_Set.i" 00010 #endif /* ! __ACE_INLINE__ */ 00011 00012 00013 ACE_RCSID (tao, 00014 Policy_Set, 00015 "Policy_Set.cpp,v 1.17 2006/04/19 08:55:30 jwillemsen Exp") 00016 00017 00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00019 00020 TAO_Policy_Set::TAO_Policy_Set (TAO_Policy_Scope scope) 00021 : scope_ (scope) 00022 { 00023 for (unsigned int i = 0; i < TAO_CACHED_POLICY_MAX_CACHED; ++i) 00024 this->cached_policies_[i] = 0; 00025 } 00026 00027 TAO_Policy_Set::~TAO_Policy_Set (void) 00028 { 00029 ACE_DECLARE_NEW_CORBA_ENV; 00030 ACE_TRY 00031 { 00032 this->cleanup_i (ACE_ENV_SINGLE_ARG_PARAMETER); 00033 ACE_TRY_CHECK; 00034 } 00035 ACE_CATCHANY 00036 { 00037 // Ignore exceptions... 00038 } 00039 ACE_ENDTRY; 00040 } 00041 00042 TAO_Policy_Set::TAO_Policy_Set (const TAO_Policy_Set &rhs) 00043 : scope_ (rhs.scope_) 00044 { 00045 // Initialize the cache. 00046 for (int i = 0; i < TAO_CACHED_POLICY_MAX_CACHED; ++i) 00047 { 00048 this->cached_policies_[i] = 0; 00049 } 00050 00051 // Copy over the policy list. 00052 this->policy_list_.length (rhs.policy_list_.length ()); 00053 00054 ACE_TRY_NEW_ENV 00055 { 00056 for (CORBA::ULong i = 0; i < rhs.policy_list_.length (); ++i) 00057 { 00058 CORBA::Policy_ptr policy = rhs.policy_list_[i]; 00059 00060 if (CORBA::is_nil (policy)) 00061 { 00062 continue; 00063 } 00064 00065 CORBA::Policy_var copy = 00066 policy->copy (ACE_ENV_SINGLE_ARG_PARAMETER); 00067 ACE_CHECK; 00068 00069 // Add the "cacheable" policies into the cache. 00070 if (copy->_tao_cached_type () != TAO_CACHED_POLICY_UNCACHED) 00071 { 00072 this->cached_policies_[copy->_tao_cached_type ()] = 00073 copy.ptr (); 00074 } 00075 00076 this->policy_list_[i] = copy._retn (); 00077 } 00078 00079 ACE_TRY_CHECK; 00080 } 00081 ACE_CATCHANY 00082 { 00083 if (TAO_debug_level > 4) 00084 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, 00085 "TAO_Policy_Set::TAO_Policy_Set"); 00086 00087 // "Try" to make this recoverable as we must have run out of memory. 00088 this->policy_list_.length (0); 00089 } 00090 ACE_ENDTRY; 00091 } 00092 00093 void 00094 TAO_Policy_Set::copy_from (TAO_Policy_Set *source 00095 ACE_ENV_ARG_DECL) 00096 { 00097 if (source == 0) 00098 { 00099 return; 00100 } 00101 00102 this->cleanup_i (ACE_ENV_SINGLE_ARG_PARAMETER); 00103 ACE_CHECK; 00104 00105 for (CORBA::ULong i = 0; i < source->policy_list_.length (); ++i) 00106 { 00107 CORBA::Policy_ptr policy = source->policy_list_[i]; 00108 00109 if (CORBA::is_nil (policy)) 00110 { 00111 continue; 00112 } 00113 00114 if (! this->compatible_scope (policy->_tao_scope())) 00115 { 00116 ACE_THROW (CORBA::NO_PERMISSION ()); 00117 } 00118 00119 CORBA::Policy_var copy = 00120 policy->copy (ACE_ENV_SINGLE_ARG_PARAMETER); 00121 ACE_CHECK; 00122 00123 CORBA::ULong const length = this->policy_list_.length (); 00124 this->policy_list_.length (length + 1); 00125 00126 // Add the "cacheable" policies into the cache. 00127 if (copy->_tao_cached_type () != TAO_CACHED_POLICY_UNCACHED) 00128 { 00129 this->cached_policies_[copy->_tao_cached_type ()] = copy.ptr (); 00130 } 00131 00132 this->policy_list_[length] = copy._retn (); 00133 } 00134 } 00135 00136 void 00137 TAO_Policy_Set::cleanup_i (ACE_ENV_SINGLE_ARG_DECL) 00138 { 00139 const CORBA::ULong len = this->policy_list_.length (); 00140 // Cleanup the policy list. 00141 for (CORBA::ULong i = 0; i < len; ++i) 00142 { 00143 this->policy_list_[i]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); 00144 ACE_CHECK; 00145 this->policy_list_[i] = CORBA::Policy::_nil (); 00146 } 00147 00148 this->policy_list_.length (0); 00149 00150 // Cleanup the cache. 00151 for (CORBA::ULong j = 0; j < TAO_CACHED_POLICY_MAX_CACHED; ++j) 00152 { 00153 this->cached_policies_[j] = 0; 00154 } 00155 } 00156 00157 // @@ !!! Add comments regarding Policy lifetimes, etc. 00158 void 00159 TAO_Policy_Set::set_policy_overrides (const CORBA::PolicyList &policies, 00160 CORBA::SetOverrideType set_add 00161 ACE_ENV_ARG_DECL) 00162 { 00163 // @@ The spec does not say what to do on this case. 00164 if (set_add != CORBA::SET_OVERRIDE && set_add != CORBA::ADD_OVERRIDE) 00165 { 00166 ACE_THROW (CORBA::BAD_PARAM ()); 00167 } 00168 00169 if (set_add == CORBA::SET_OVERRIDE) 00170 { 00171 this->cleanup_i (ACE_ENV_SINGLE_ARG_PARAMETER); 00172 ACE_CHECK; 00173 } 00174 00175 // Flag, indicating whether we have already overridden 00176 // RTCORBA::ServerProtocolPolicy during this call. 00177 bool server_protocol_set = false; 00178 00179 const CORBA::ULong plen = policies.length (); 00180 00181 for (CORBA::ULong i = 0; i < plen; ++i) 00182 { 00183 CORBA::Policy_ptr policy = policies[i]; 00184 00185 if (CORBA::is_nil (policy)) 00186 { 00187 continue; 00188 } 00189 00190 const CORBA::PolicyType policy_type = 00191 policy->policy_type (ACE_ENV_SINGLE_ARG_PARAMETER); 00192 ACE_CHECK; 00193 00194 if (policy_type == TAO_RT_SERVER_PROTOCOL_POLICY_TYPE) 00195 { 00196 // Only one ServerProtocolPolicy should be included in a 00197 // given PolicyList (section 4.15.2 of RTCORBA 1.0, i.e., 00198 // ptc/99-05-03). 00199 // User-caused exceptional conditions can leave the Policy 00200 // Manager in an inconsistent state. It is the 00201 // responsibility of the user to return it to consistent state. 00202 if (server_protocol_set) 00203 { 00204 ACE_THROW (CORBA::INV_POLICY ()); 00205 } 00206 00207 server_protocol_set = true; 00208 } 00209 00210 this->set_policy (policy ACE_ENV_ARG_PARAMETER); 00211 ACE_CHECK; 00212 } 00213 } 00214 00215 void 00216 TAO_Policy_Set::set_policy (const CORBA::Policy_ptr policy 00217 ACE_ENV_ARG_DECL) 00218 { 00219 if (! this->compatible_scope (policy->_tao_scope())) 00220 { 00221 ACE_THROW (CORBA::NO_PERMISSION ()); 00222 } 00223 00224 const CORBA::PolicyType policy_type = 00225 policy->policy_type (ACE_ENV_SINGLE_ARG_PARAMETER); 00226 ACE_CHECK; 00227 00228 CORBA::Policy_var copy = policy->copy (ACE_ENV_SINGLE_ARG_PARAMETER); 00229 ACE_CHECK; 00230 00231 CORBA::ULong j = 0; 00232 const CORBA::ULong length = this->policy_list_.length (); 00233 00234 while (j != length) 00235 { 00236 CORBA::ULong current = 00237 this->policy_list_[j]->policy_type (ACE_ENV_SINGLE_ARG_PARAMETER); 00238 ACE_CHECK; 00239 00240 if (current == policy_type) 00241 { 00242 this->policy_list_[j]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); 00243 ACE_CHECK; 00244 00245 this->policy_list_[j] = copy.ptr (); 00246 break; 00247 } 00248 00249 ++j; 00250 } 00251 00252 if (j == length) 00253 { 00254 this->policy_list_.length (length + 1); 00255 this->policy_list_[j] = copy.ptr (); 00256 } 00257 00258 // If this is a policy that gets accessed on the critical path, 00259 // save a pointer to it in the cache. 00260 TAO_Cached_Policy_Type cached_policy_type = policy->_tao_cached_type (); 00261 00262 if (cached_policy_type != TAO_CACHED_POLICY_UNCACHED) 00263 { 00264 this->cached_policies_[cached_policy_type] = copy.ptr (); 00265 } 00266 00267 // Transfer ownership to the policy list. 00268 (void) copy._retn (); 00269 } 00270 00271 CORBA::PolicyList * 00272 TAO_Policy_Set::get_policy_overrides (const CORBA::PolicyTypeSeq &types 00273 ACE_ENV_ARG_DECL) 00274 { 00275 const CORBA::ULong slots = types.length (); 00276 CORBA::PolicyList *policy_list_ptr; 00277 00278 if (slots == 0) 00279 { 00280 // Copy our own policy list. 00281 ACE_NEW_THROW_EX (policy_list_ptr, 00282 CORBA::PolicyList (this->policy_list_), 00283 CORBA::NO_MEMORY ()); 00284 ACE_CHECK_RETURN (0); 00285 00286 return policy_list_ptr; 00287 } 00288 00289 ACE_NEW_THROW_EX (policy_list_ptr, 00290 CORBA::PolicyList (slots), 00291 CORBA::NO_MEMORY ()); 00292 ACE_CHECK_RETURN (0); 00293 00294 CORBA::PolicyList_var policy_list (policy_list_ptr); 00295 policy_list->length (slots); 00296 CORBA::ULong n = 0; 00297 00298 for (CORBA::ULong j = 0; j < slots; ++j) 00299 { 00300 const CORBA::ULong slot = types[j]; 00301 const CORBA::ULong length = this->policy_list_.length (); 00302 00303 for (CORBA::ULong i = 0; i < length; ++i) 00304 { 00305 const CORBA::ULong current = 00306 this->policy_list_[i]->policy_type (ACE_ENV_SINGLE_ARG_PARAMETER); 00307 ACE_CHECK_RETURN (0); 00308 00309 if (current != slot) 00310 { 00311 continue; 00312 } 00313 00314 policy_list[n++] = 00315 CORBA::Policy::_duplicate (this->policy_list_[i]); 00316 break; 00317 } 00318 } 00319 00320 policy_list->length (n); // Truncate buffer if necessary. 00321 00322 return policy_list._retn (); 00323 } 00324 00325 CORBA::Policy_ptr 00326 TAO_Policy_Set::get_policy (CORBA::PolicyType type 00327 ACE_ENV_ARG_DECL) 00328 { 00329 const CORBA::ULong length = this->policy_list_.length (); 00330 00331 for (CORBA::ULong i = 0; i < length; ++i) 00332 { 00333 const CORBA::ULong current = 00334 this->policy_list_[i]->policy_type (ACE_ENV_SINGLE_ARG_PARAMETER); 00335 ACE_CHECK_RETURN (0); 00336 00337 if (current != type) 00338 { 00339 continue; 00340 } 00341 00342 return CORBA::Policy::_duplicate (this->policy_list_[i]); 00343 } 00344 00345 return CORBA::Policy::_nil (); 00346 } 00347 00348 CORBA::Policy_ptr 00349 TAO_Policy_Set::get_cached_const_policy (TAO_Cached_Policy_Type type) const 00350 { 00351 if (type != TAO_CACHED_POLICY_UNCACHED 00352 && type < TAO_CACHED_POLICY_MAX_CACHED) 00353 { 00354 return this->cached_policies_[type]; 00355 } 00356 00357 return CORBA::Policy::_nil (); 00358 } 00359 00360 CORBA::Policy_ptr 00361 TAO_Policy_Set::get_cached_policy (TAO_Cached_Policy_Type type 00362 ACE_ENV_ARG_DECL_NOT_USED) 00363 { 00364 if (type != TAO_CACHED_POLICY_UNCACHED 00365 && type < TAO_CACHED_POLICY_MAX_CACHED) 00366 { 00367 return CORBA::Policy::_duplicate (this->cached_policies_[type]); 00368 } 00369 00370 return CORBA::Policy::_nil (); 00371 } 00372 00373 TAO_END_VERSIONED_NAMESPACE_DECL