Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / TAO / tao / Strategies / SCIOP_Endpoint.cpp
blob8a6b5c604d98c7ecdcf5b1864c106087e3454faa
1 #include "tao/Strategies/SCIOP_Endpoint.h"
3 #if TAO_HAS_SCIOP == 1
5 #include "tao/ORB_Constants.h"
6 #include "tao/debug.h"
8 #include "ace/os_include/os_netdb.h"
9 #include "ace/Synch_Traits.h"
10 #include "ace/Thread_Mutex.h"
11 #include "ace/OS_NS_string.h"
12 #include "ace/Log_Msg.h"
13 #include "ace/Synch.h"
14 #include "ace/OS_NS_stdio.h"
15 #include "tao/ORB_Core.h"
16 #include <cstring>
18 #if !defined (__ACE_INLINE__)
19 # include "tao/Strategies/SCIOP_Endpoint.inl"
20 #endif /* __ACE_INLINE__ */
22 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
24 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const ACE_INET_Addr &addr,
25 int use_dotted_decimal_addresses)
26 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE)
27 , host_ ()
28 , port_ (683) // default port (IANA assigned)
29 , object_addr_ (addr)
30 , object_addr_set_ (0)
31 , preferred_path_ ()
32 , is_encodable_ (true)
33 , next_ (0)
35 this->set (addr, use_dotted_decimal_addresses);
38 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host,
39 CORBA::UShort port,
40 const ACE_INET_Addr &addr,
41 CORBA::Short priority)
42 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE,
43 priority)
44 , host_ (host)
45 , port_ (port)
46 , object_addr_ (addr)
47 , object_addr_set_ (0)
48 , preferred_path_ ()
49 , is_encodable_ (true)
50 , next_ (0)
54 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint ()
55 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE)
56 , host_ ()
57 , port_ (683) // default port (IANA assigned)
58 , object_addr_ ()
59 , object_addr_set_ (0)
60 , preferred_path_ ()
61 , is_encodable_ (true)
62 , next_ (0)
66 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host,
67 CORBA::UShort port,
68 CORBA::Short priority)
69 : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE)
70 , host_ (host)
71 , port_ (port)
72 , object_addr_ ()
73 , object_addr_set_ (0)
74 , preferred_path_ ()
75 , is_encodable_ (true)
76 , next_ (0)
78 this->priority (priority);
81 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const TAO_SCIOP_Endpoint &rhs)
82 : TAO_Endpoint (rhs.tag_,
83 rhs.priority_)
84 , host_ (rhs.host_)
85 , port_ (rhs.port_)
86 , object_addr_ (rhs.object_addr_)
87 , object_addr_set_ (rhs.object_addr_set_)
88 , preferred_path_ (rhs.preferred_path_)
89 , is_encodable_ (rhs.is_encodable_)
90 , next_ (0)
94 int
95 TAO_SCIOP_Endpoint::set (const ACE_INET_Addr &addr,
96 int use_dotted_decimal_addresses)
98 char tmp_host[MAXHOSTNAMELEN + 1];
100 if (use_dotted_decimal_addresses
101 || addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
103 const char *tmp = addr.get_host_addr ();
104 if (tmp == 0)
106 if (TAO_debug_level > 0)
107 TAOLIB_DEBUG ((LM_DEBUG,
108 ACE_TEXT ("\n\nTAO (%P|%t) ")
109 ACE_TEXT ("SCIOP_Endpoint::set ")
110 ACE_TEXT ("- %p\n\n"),
111 ACE_TEXT ("cannot determine hostname")));
112 return -1;
114 else
115 this->host_ = tmp;
117 else
118 this->host_ = CORBA::string_dup (tmp_host);
120 this->port_ = addr.get_port_number();
122 return 0;
126 TAO_SCIOP_Endpoint::addr_to_string (char *buffer, size_t length)
128 size_t actual_len =
129 ACE_OS::strlen (this->host_.in ()) // chars in host name
130 + sizeof (':') // delimiter
131 + std::strlen ("65536") // max port
132 + sizeof ('\0');
134 if (length < actual_len)
135 return -1;
137 ACE_OS::sprintf (buffer, "%s:%d",
138 this->host_.in (), this->port_);
140 return 0;
143 const char *
144 TAO_SCIOP_Endpoint::host (const char *h)
146 this->host_ = h;
148 return this->host_.in ();
151 TAO_Endpoint *
152 TAO_SCIOP_Endpoint::next ()
154 return this->next_;
157 TAO_Endpoint *
158 TAO_SCIOP_Endpoint::duplicate ()
160 TAO_SCIOP_Endpoint *endpoint = 0;
162 // @@NOTE: Not at all exception safe
163 ACE_NEW_RETURN (endpoint,
164 TAO_SCIOP_Endpoint (*this),
167 return endpoint;
170 CORBA::Boolean
171 TAO_SCIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
173 TAO_Endpoint *endpt =
174 const_cast<TAO_Endpoint *> (other_endpoint);
176 TAO_SCIOP_Endpoint *endpoint =
177 dynamic_cast<TAO_SCIOP_Endpoint *> (endpt);
178 if (endpoint == 0)
179 return 0;
181 return (this->port_ == endpoint->port_
182 && (ACE_OS::strcmp(this->host(), endpoint->host()) == 0));
185 CORBA::ULong
186 TAO_SCIOP_Endpoint::hash ()
188 if (this->hash_val_ != 0)
189 return this->hash_val_;
192 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
193 guard,
194 this->addr_lookup_lock_,
195 this->hash_val_);
196 // .. DCL
197 if (this->hash_val_ != 0)
198 return this->hash_val_;
200 // A few comments about this optimization. The call below will
201 // deadlock if the object_addr_set is false. If you don't belive
203 if (!this->object_addr_set_)
205 // Set the object_addr first
206 (void) this->object_addr_i ();
209 this->hash_val_ =
210 this->object_addr_.get_ip_address () + this->port ();
213 return this->hash_val_;
216 const ACE_INET_Addr &
217 TAO_SCIOP_Endpoint::object_addr () const
219 // The object_addr_ is initialized here, rather than at IOR decode
220 // time for several reasons:
221 // 1. A request on the object may never be invoked.
222 // 2. The DNS setup may have changed dynamically.
223 // ...etc..
225 // Double checked locking optimization.
226 if (!this->object_addr_set_)
228 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
229 guard,
230 this->addr_lookup_lock_,
231 this->object_addr_);
233 if (!this->object_addr_set_)
235 (void) this->object_addr_i ();
239 return this->object_addr_;
242 void
243 TAO_SCIOP_Endpoint::object_addr_i () const
245 if (this->object_addr_.set (this->port_, this->host_.in ()) == -1)
247 // If this call fails, it most likely due a hostname
248 // lookup failure caused by a DNS misconfiguration. If
249 // a request is made to the object at the given host and
250 // port, then a CORBA::TRANSIENT() exception should be
251 // thrown.
253 // Invalidate the ACE_INET_Addr. This is used as a flag
254 // to denote that ACE_INET_Addr initialization failed.
255 this->object_addr_.set_type (-1);
257 else
259 this->object_addr_set_ = true;
263 CORBA::ULong
264 TAO_SCIOP_Endpoint::preferred_interfaces (TAO_ORB_Core *oc)
266 ACE_CString tmp (
267 oc->orb_params ()->preferred_interfaces ());
269 ACE_CString::size_type pos = 0;
271 pos = tmp.find (this->host_.in ());
273 TAO_SCIOP_Endpoint *latest = this;
275 CORBA::ULong count = 0;
277 while (pos != ACE_CString::npos)
279 // Do we have a "," or an '\0'?
280 ACE_CString::size_type new_pos = tmp.find (",", pos + 1);
282 // Length of the preferred path
283 ACE_CString::size_type length = 0;
285 if (new_pos == ACE_CString::npos)
286 length = tmp.length () - pos;
287 else
288 length = new_pos - pos;
290 ACE_CString rem_tmp = tmp.substr (pos, length);
292 // Search for the ":"
293 ACE_CString::size_type col_pos = rem_tmp.find (":");
295 if (col_pos == ACE_CString::npos)
297 pos = tmp.find (latest->host_.in (),
298 pos + length);
299 continue;
302 ACE_CString path = rem_tmp.substr (col_pos + 1);
304 latest->preferred_path_.host =
305 CORBA::string_dup (path.c_str ());
307 if (TAO_debug_level > 3)
308 TAOLIB_DEBUG ((LM_DEBUG,
309 "(%P|%t) Adding path [%C] "
310 " as preferred path for [%C]\n",
311 path.c_str (), this->host_.in ()));
313 pos = tmp.find (latest->host_.in (),
314 pos + length);
316 if (pos != ACE_CString::npos)
318 TAO_Endpoint *tmp_ep =
319 latest->duplicate ();
321 latest->next_ = dynamic_cast<TAO_SCIOP_Endpoint *> (tmp_ep);
323 if (latest->next_ == 0) return count;
325 latest = latest->next_;
326 ++count;
330 if (tmp.length () != 0 &&
331 !oc->orb_params ()->enforce_pref_interfaces ())
333 TAO_Endpoint *tmp_ep = latest->duplicate ();
335 latest->next_ =
336 dynamic_cast<TAO_SCIOP_Endpoint *> (tmp_ep);
338 if (latest->next_ == 0) return count;
340 latest->next_->preferred_path_.host = (const char *) 0;
341 ++count;
344 return count;
347 bool
348 TAO_SCIOP_Endpoint::is_preferred_network () const
350 return (this->preferred_path_.host.in () != 0);
353 const char *
354 TAO_SCIOP_Endpoint::preferred_network () const
356 return this->preferred_path_.host.in ();
359 TAO_END_VERSIONED_NAMESPACE_DECL
361 #endif /* TAO_HAS_SCIOP == 1 */