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