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