00001 #include "tao/Strategies/UIOP_Acceptor.h"
00002
00003 #if TAO_HAS_UIOP == 1
00004
00005 #include "tao/Strategies/UIOP_Profile.h"
00006 #include "tao/MProfile.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Server_Strategy_Factory.h"
00009 #include "tao/debug.h"
00010 #include "tao/Protocols_Hooks.h"
00011 #include "tao/Codeset_Manager.h"
00012 #include "tao/CDR.h"
00013
00014 #include "ace/OS_NS_stdio.h"
00015 #include "ace/OS_NS_string.h"
00016 #include "ace/OS_NS_unistd.h"
00017
00018 ACE_RCSID (Strategies,
00019 UIOP_Acceptor,
00020 "$Id: UIOP_Acceptor.cpp 78937 2007-07-18 14:37:07Z johnnyw $")
00021
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023
00024 TAO_UIOP_Acceptor::TAO_UIOP_Acceptor (void)
00025 : TAO_Acceptor (TAO_TAG_UIOP_PROFILE),
00026 base_acceptor_ (),
00027 creation_strategy_ (0),
00028 concurrency_strategy_ (0),
00029 accept_strategy_ (0),
00030 version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR),
00031 orb_core_ (0),
00032 unlink_on_close_ (true)
00033 {
00034 }
00035
00036 TAO_UIOP_Acceptor::~TAO_UIOP_Acceptor (void)
00037 {
00038
00039
00040 this->close ();
00041
00042 delete this->creation_strategy_;
00043 delete this->concurrency_strategy_;
00044 delete this->accept_strategy_;
00045 }
00046
00047 int
00048 TAO_UIOP_Acceptor::create_profile (const TAO::ObjectKey &object_key,
00049 TAO_MProfile &mprofile,
00050 CORBA::Short priority)
00051 {
00052
00053
00054 if (priority == TAO_INVALID_PRIORITY)
00055 return this->create_new_profile (object_key,
00056 mprofile,
00057 priority);
00058 else
00059 return this->create_shared_profile (object_key,
00060 mprofile,
00061 priority);
00062
00063 }
00064
00065 int
00066 TAO_UIOP_Acceptor::create_new_profile (const TAO::ObjectKey &object_key,
00067 TAO_MProfile &mprofile,
00068 CORBA::Short priority)
00069 {
00070 ACE_UNIX_Addr addr;
00071
00072 if (this->base_acceptor_.acceptor ().get_local_addr (addr) == -1)
00073 return 0;
00074
00075 int count = mprofile.profile_count ();
00076 if ((mprofile.size () - count) < 1
00077 && mprofile.grow (count + 1) == -1)
00078 return -1;
00079
00080 TAO_UIOP_Profile *pfile = 0;
00081 ACE_NEW_RETURN (pfile,
00082 TAO_UIOP_Profile (addr,
00083 object_key,
00084 this->version_,
00085 this->orb_core_),
00086 -1);
00087 pfile->endpoint ()->priority (priority);
00088
00089 if (mprofile.give_profile (pfile) == -1)
00090 {
00091 pfile->_decr_refcnt ();
00092 pfile = 0;
00093 return -1;
00094 }
00095
00096
00097
00098
00099
00100 if (this->orb_core_->orb_params ()->std_profile_components () == 0
00101 || (this->version_.major == 1 && this->version_.minor == 0))
00102 return 0;
00103
00104 pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00105 TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
00106 if (csm)
00107 csm->set_codeset(pfile->tagged_components());
00108 return 0;
00109 }
00110
00111 int
00112 TAO_UIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
00113 TAO_MProfile &mprofile,
00114 CORBA::Short priority)
00115 {
00116 TAO_Profile *pfile = 0;
00117 TAO_UIOP_Profile *uiop_profile = 0;
00118
00119
00120 for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
00121 {
00122 pfile = mprofile.get_profile (i);
00123 if (pfile->tag () == TAO_TAG_UIOP_PROFILE)
00124 {
00125 uiop_profile = dynamic_cast<TAO_UIOP_Profile *> (pfile);
00126 break;
00127 }
00128 }
00129
00130 if (uiop_profile == 0)
00131 {
00132
00133
00134 return create_new_profile (object_key,
00135 mprofile,
00136 priority);
00137 }
00138 else
00139 {
00140
00141 ACE_UNIX_Addr addr;
00142
00143 if (this->base_acceptor_.acceptor ().get_local_addr (addr) == -1)
00144 return 0;
00145
00146 TAO_UIOP_Endpoint *endpoint = 0;
00147 ACE_NEW_RETURN (endpoint,
00148 TAO_UIOP_Endpoint (addr),
00149 -1);
00150 endpoint->priority (priority);
00151 uiop_profile->add_endpoint (endpoint);
00152
00153 return 0;
00154 }
00155 }
00156
00157 int
00158 TAO_UIOP_Acceptor::is_collocated (const TAO_Endpoint *endpoint)
00159 {
00160 const TAO_UIOP_Endpoint *endp =
00161 dynamic_cast<const TAO_UIOP_Endpoint *> (endpoint);
00162
00163
00164 if (endp == 0)
00165 return 0;
00166
00167
00168 ACE_UNIX_Addr address;
00169 if (this->base_acceptor_.acceptor ().get_local_addr (address) == -1)
00170 return 0;
00171
00172 return endp->object_addr () == address;
00173 }
00174
00175 int
00176 TAO_UIOP_Acceptor::close (void)
00177 {
00178 if (this->unlink_on_close_)
00179 {
00180 ACE_UNIX_Addr addr;
00181
00182 if (this->base_acceptor_.acceptor ().get_local_addr (addr) == 0)
00183 (void) ACE_OS::unlink (addr.get_path_name ());
00184
00185 this->unlink_on_close_ = false;
00186 }
00187
00188 return this->base_acceptor_.close ();
00189 }
00190
00191 int
00192 TAO_UIOP_Acceptor::open (TAO_ORB_Core *orb_core,
00193 ACE_Reactor *reactor,
00194 int major,
00195 int minor,
00196 const char *address,
00197 const char *options)
00198 {
00199 this->orb_core_ = orb_core;
00200
00201 if (address == 0)
00202 return -1;
00203
00204 if (major >= 0 && minor >= 0)
00205 this->version_.set_version (static_cast<CORBA::Octet> (major),
00206 static_cast<CORBA::Octet> (minor));
00207
00208 if (this->parse_options (options) == -1)
00209 return -1;
00210 else
00211 return this->open_i (address,
00212 reactor);
00213 }
00214
00215 int
00216 TAO_UIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
00217 ACE_Reactor *reactor,
00218 int major,
00219 int minor,
00220 const char *options)
00221 {
00222 this->orb_core_ = orb_core;
00223
00224 if (major >= 0 && minor >= 0)
00225 this->version_.set_version (static_cast<CORBA::Octet> (major),
00226 static_cast<CORBA::Octet> (minor));
00227
00228
00229 if (this->parse_options (options) == -1)
00230 return -1;
00231
00232 ACE_Auto_String_Free tempname (ACE_OS::tempnam (0, "TAO"));
00233
00234 if (tempname.get () == 0)
00235 return -1;
00236
00237 return this->open_i (tempname.get (),
00238 reactor);
00239 }
00240
00241 int
00242 TAO_UIOP_Acceptor::open_i (const char *rendezvous,
00243 ACE_Reactor *reactor)
00244 {
00245 ACE_NEW_RETURN (this->creation_strategy_,
00246 TAO_UIOP_CREATION_STRATEGY (this->orb_core_),
00247 -1);
00248
00249 ACE_NEW_RETURN (this->concurrency_strategy_,
00250 TAO_UIOP_CONCURRENCY_STRATEGY (this->orb_core_),
00251 -1);
00252
00253 ACE_NEW_RETURN (this->accept_strategy_,
00254 TAO_UIOP_ACCEPT_STRATEGY (this->orb_core_),
00255 -1);
00256
00257 ACE_UNIX_Addr addr;
00258
00259 this->rendezvous_point (addr, rendezvous);
00260
00261 if (this->base_acceptor_.open (addr,
00262 reactor,
00263 this->creation_strategy_,
00264 this->accept_strategy_,
00265 this->concurrency_strategy_) == -1)
00266 {
00267
00268
00269 if (errno == EADDRINUSE)
00270 this->unlink_on_close_ = false;
00271
00272 return -1;
00273 }
00274
00275 (void) this->base_acceptor_.acceptor().enable (ACE_CLOEXEC);
00276
00277
00278
00279
00280
00281
00282
00283 if (TAO_debug_level > 5)
00284 ACE_DEBUG ((LM_DEBUG,
00285 "\nTAO (%P|%t) UIOP_Acceptor::open_i - "
00286 "listening on: <%s>\n",
00287 addr.get_path_name ()));
00288 return 0;
00289 }
00290
00291 void
00292 TAO_UIOP_Acceptor::rendezvous_point (ACE_UNIX_Addr &addr,
00293 const char *rendezvous)
00294 {
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 addr.set (rendezvous);
00319
00320 const size_t length = ACE_OS::strlen (addr.get_path_name ());
00321
00322
00323
00324
00325 if (length < ACE_OS::strlen (rendezvous))
00326 ACE_DEBUG ((LM_WARNING,
00327 "TAO (%P|%t) UIOP rendezvous point was truncated to <%s>\n"
00328 "since it was longer than %d characters long.\n",
00329 addr.get_path_name (),
00330 length));
00331 }
00332
00333 CORBA::ULong
00334 TAO_UIOP_Acceptor::endpoint_count (void)
00335 {
00336 return 1;
00337 }
00338
00339 int
00340 TAO_UIOP_Acceptor::object_key (IOP::TaggedProfile &profile,
00341 TAO::ObjectKey &object_key)
00342 {
00343
00344 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00345 TAO_InputCDR cdr (profile.profile_data.mb ());
00346 #else
00347 TAO_InputCDR cdr (reinterpret_cast<char*> (profile.profile_data.get_buffer ()),
00348 profile.profile_data.length ());
00349 #endif
00350
00351 CORBA::Octet major, minor;
00352
00353
00354
00355 if (!(cdr.read_octet (major) && cdr.read_octet (minor)))
00356 {
00357 if (TAO_debug_level > 0)
00358 {
00359 ACE_DEBUG ((LM_DEBUG,
00360 ACE_TEXT ("TAO (%P|%t) IIOP_Profile::decode - v%d.%d\n"),
00361 major,
00362 minor));
00363 }
00364
00365 return -1;
00366 }
00367
00368 char * rendezvous = 0;
00369
00370
00371 if (cdr.read_string (rendezvous) == 0)
00372 {
00373 ACE_ERROR ((LM_ERROR, "error decoding UIOP rendezvous_point"));
00374
00375 return -1;
00376 }
00377
00378
00379 delete [] rendezvous;
00380
00381
00382 if ((cdr >> object_key) == 0)
00383 return -1;
00384
00385 return 1;
00386 }
00387
00388 int
00389 TAO_UIOP_Acceptor::parse_options (const char *str)
00390 {
00391 if (str == 0)
00392 return 0;
00393
00394
00395
00396
00397
00398 ACE_CString options (str);
00399
00400 const size_t len = options.length ();
00401
00402 static const char option_delimiter = '&';
00403
00404
00405
00406 CORBA::ULong option_count = 1;
00407
00408
00409
00410
00411 for (size_t i = 0; i < len; ++i)
00412 if (options[i] == option_delimiter)
00413 ++option_count;
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 ACE_CString::size_type begin = 0;
00424 ACE_CString::size_type end = 0;
00425
00426 for (CORBA::ULong j = 0; j < option_count; ++j)
00427 {
00428 if (j < option_count - 1)
00429 end = options.find (option_delimiter, begin);
00430 else
00431 end = len;
00432
00433 if (end == begin)
00434 ACE_ERROR_RETURN ((LM_ERROR,
00435 "TAO (%P|%t) Zero length UIOP option.\n"),
00436 -1);
00437 else if (end != ACE_CString::npos)
00438 {
00439 ACE_CString opt =
00440 options.substring (begin, end - begin);
00441
00442 ACE_CString::size_type const slot = opt.find ("=");
00443
00444 if (slot == len - 1
00445 || slot == ACE_CString::npos)
00446 ACE_ERROR_RETURN ((LM_ERROR,
00447 "TAO (%P|%t) UIOP option <%s> is "
00448 "missing a value.\n",
00449 opt.c_str ()),
00450 -1);
00451
00452 const ACE_CString name (opt.substring (0, slot));
00453 ACE_CString value = opt.substring (slot + 1);
00454
00455 begin = end + 1;
00456
00457 if (name.length () == 0)
00458 ACE_ERROR_RETURN ((LM_ERROR,
00459 "TAO (%P|%t) Zero length UIOP "
00460 "option name.\n"),
00461 -1);
00462
00463 if (name == "priority")
00464 {
00465 ACE_ERROR_RETURN ((LM_ERROR,
00466 ACE_TEXT ("TAO (%P|%t) Invalid UIOP endpoint format: ")
00467 ACE_TEXT ("endpoint priorities no longer supported. \n")),
00468 -1);
00469 }
00470 else
00471 ACE_ERROR_RETURN ((LM_ERROR,
00472 "TAO (%P|%t) Invalid UIOP option: <%s>\n",
00473 name.c_str ()),
00474 -1);
00475 }
00476 else
00477 break;
00478 }
00479 return 0;
00480 }
00481
00482 TAO_END_VERSIONED_NAMESPACE_DECL
00483
00484 #endif