00001
00002
00003 #include "tao/Connection_Handler.h"
00004 #include "tao/ORB_Core.h"
00005 #include "tao/debug.h"
00006 #include "tao/Resume_Handle.h"
00007 #include "tao/Transport.h"
00008 #include "tao/Wait_Strategy.h"
00009
00010 #include "ace/SOCK.h"
00011 #include "ace/Reactor.h"
00012 #include "ace/os_include/sys/os_socket.h"
00013
00014
00015
00016 #if !defined (__ACE_INLINE__)
00017 #include "tao/Connection_Handler.inl"
00018 #endif
00019
00020 ACE_RCSID (tao,
00021 Connection_Handler,
00022 "$Id: Connection_Handler.cpp 80603 2008-02-11 22:14:39Z johnc $")
00023
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025
00026 TAO_Connection_Handler::TAO_Connection_Handler (TAO_ORB_Core *orb_core)
00027 : orb_core_ (orb_core),
00028 transport_ (0),
00029 connection_pending_ (false)
00030 {
00031
00032
00033 this->lock_ =
00034 this->orb_core_->resource_factory ()->create_cached_connection_lock ();
00035
00036
00037
00038 this->state_changed (TAO_LF_Event::LFS_CONNECTION_WAIT,
00039 this->orb_core_->leader_follower ());
00040 }
00041
00042 TAO_Connection_Handler::~TAO_Connection_Handler (void)
00043 {
00044
00045 delete this->lock_;
00046
00047
00048 }
00049
00050 int
00051 TAO_Connection_Handler::shared_open (void)
00052 {
00053
00054
00055
00056
00057
00058 this->cancel_pending_connection();
00059
00060 return 0;
00061 }
00062
00063 int
00064 TAO_Connection_Handler::set_socket_option (ACE_SOCK &sock,
00065 int snd_size,
00066 int rcv_size)
00067 {
00068 #if !defined (ACE_LACKS_SOCKET_BUFSIZ)
00069
00070 if (snd_size != 0
00071 && sock.set_option (SOL_SOCKET,
00072 SO_SNDBUF,
00073 (void *) &snd_size,
00074 sizeof (snd_size)) == -1
00075 && errno != ENOTSUP)
00076 {
00077 return -1;
00078 }
00079
00080 if (rcv_size != 0
00081 && sock.set_option (SOL_SOCKET,
00082 SO_RCVBUF,
00083 (void *) &rcv_size,
00084 sizeof (int)) == -1
00085 && errno != ENOTSUP)
00086 {
00087 return -1;
00088 }
00089 #else
00090 ACE_UNUSED_ARG (snd_size);
00091 ACE_UNUSED_ARG (rcv_size);
00092 #endif
00093
00094
00095
00096
00097 (void) sock.enable (ACE_CLOEXEC);
00098
00099 return 0;
00100 }
00101
00102 int
00103 TAO_Connection_Handler::svc_i (void)
00104 {
00105 int result = 0;
00106
00107 if (TAO_debug_level > 0)
00108 ACE_DEBUG ((LM_DEBUG,
00109 ACE_TEXT ("TAO (%P|%t) - Connection_Handler::svc_i begin\n")));
00110
00111
00112
00113
00114
00115 ACE_Time_Value *max_wait_time = 0;
00116 ACE_Time_Value timeout;
00117 ACE_Time_Value current_timeout;
00118
00119 if (this->orb_core_->thread_per_connection_timeout (timeout))
00120 {
00121 current_timeout = timeout;
00122 max_wait_time = ¤t_timeout;
00123 }
00124
00125 TAO_Resume_Handle rh (this->orb_core_,
00126 ACE_INVALID_HANDLE);
00127
00128
00129
00130
00131
00132
00133 while (!this->orb_core_->has_shutdown ()
00134 && result >= 0)
00135 {
00136
00137 (void) this->transport ()->update_transport ();
00138
00139 result = this->transport ()->handle_input (rh, max_wait_time);
00140
00141 if (result == -1 && errno == ETIME)
00142 {
00143
00144
00145 result = 0;
00146
00147
00148
00149
00150 errno = 0;
00151 }
00152 else if (result == -1)
00153 {
00154
00155 return result;
00156 }
00157
00158 current_timeout = timeout;
00159
00160 if (TAO_debug_level > 0)
00161 ACE_DEBUG ((LM_DEBUG,
00162 "TAO (%P|%t) - Connection_Handler::svc_i - "
00163 "loop <%d>\n", current_timeout.msec ()));
00164 }
00165
00166 if (TAO_debug_level > 0)
00167 ACE_DEBUG ((LM_DEBUG,
00168 "TAO (%P|%t) - Connection_Handler::svc_i end\n"));
00169
00170 return result;
00171 }
00172
00173 void
00174 TAO_Connection_Handler::transport (TAO_Transport* transport)
00175 {
00176 this->transport_ = transport;
00177
00178
00179 this->transport_->event_handler_i ()->reference_counting_policy ().value (
00180 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
00181 );
00182 }
00183
00184 int
00185 TAO_Connection_Handler::handle_output_eh (
00186 ACE_HANDLE, ACE_Event_Handler * eh)
00187 {
00188
00189 (void) this->transport ()->update_transport ();
00190
00191
00192
00193 TAO_Resume_Handle resume_handle (this->orb_core (),
00194 eh->get_handle ());
00195
00196 int return_value = 0;
00197 this->pre_io_hook (return_value);
00198 if (return_value != 0)
00199 {
00200 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00201 return return_value;
00202 }
00203
00204 return_value = this->transport ()->handle_output (0);
00205
00206 this->pos_io_hook (return_value);
00207
00208 if (return_value != 0)
00209 {
00210 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00211 }
00212
00213 return return_value;
00214 }
00215
00216 int
00217 TAO_Connection_Handler::handle_input_eh (
00218 ACE_HANDLE h, ACE_Event_Handler *eh)
00219 {
00220
00221 if (!this->transport ()->wait_strategy ()->can_process_upcalls ())
00222 {
00223 if (TAO_debug_level > 6)
00224 ACE_DEBUG ((LM_DEBUG,
00225 "TAO (%P|%t) - Connection_Handler[%d]::handle_input_eh, "
00226 "not going to handle_input on transport "
00227 "because upcalls temporarily suspended on this thread\n",
00228 this->transport()->id()));
00229 return 0;
00230 }
00231
00232 int const result = this->handle_input_internal (h, eh);
00233
00234 if (result == -1)
00235 {
00236 this->close_connection ();
00237 return 0;
00238 }
00239
00240 return result;
00241 }
00242
00243 int
00244 TAO_Connection_Handler::handle_input_internal (
00245 ACE_HANDLE h, ACE_Event_Handler * eh)
00246 {
00247
00248 (void) this->transport ()->update_transport ();
00249
00250
00251
00252
00253 size_t const t_id =
00254 this->transport ()->id ();
00255
00256 if (TAO_debug_level > 6)
00257 {
00258 ACE_HANDLE handle = eh->get_handle();
00259 ACE_DEBUG ((LM_DEBUG,
00260 "TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
00261 "handle = %d/%d\n",
00262 t_id, handle, h));
00263 }
00264
00265 TAO_Resume_Handle resume_handle (this->orb_core (), eh->get_handle ());
00266
00267 int return_value = 0;
00268
00269 this->pre_io_hook (return_value);
00270 if (return_value != 0)
00271 return return_value;
00272
00273 return_value = this->transport ()->handle_input (resume_handle);
00274
00275 this->pos_io_hook (return_value);
00276
00277
00278
00279 resume_handle.handle_input_return_value_hook(return_value);
00280
00281 if (TAO_debug_level > 6)
00282 {
00283 ACE_HANDLE handle = eh->get_handle ();
00284 ACE_DEBUG ((LM_DEBUG,
00285 "TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
00286 "handle = %d/%d, retval = %d\n",
00287 t_id, handle, h, return_value));
00288 }
00289
00290 if (return_value == -1)
00291 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00292 return return_value;
00293 }
00294
00295 int
00296 TAO_Connection_Handler::close_connection_eh (ACE_Event_Handler *eh)
00297 {
00298
00299 ACE_HANDLE handle = eh->get_handle ();
00300
00301 size_t const id = this->transport ()->id ();
00302 if (TAO_debug_level)
00303 {
00304 ACE_DEBUG ((LM_DEBUG,
00305 "TAO (%P|%t) - Connection_Handler[%d]::"
00306 "close_connection_eh, purging entry from cache\n",
00307 handle));
00308 }
00309
00310 this->transport ()->pre_close ();
00311
00312
00313
00314 if (this->transport ()->wait_strategy ()->is_registered ())
00315 {
00316 ACE_Reactor *eh_reactor = eh->reactor ();
00317
00318 if (this->orb_core_->has_shutdown () == 0)
00319 {
00320
00321
00322 if (eh_reactor == 0)
00323 eh_reactor = this->transport()->orb_core()->reactor ();
00324 }
00325
00326
00327
00328 ACE_ASSERT (eh_reactor != 0);
00329
00330 if (TAO_debug_level)
00331 {
00332 ACE_DEBUG ((LM_DEBUG,
00333 "TAO (%P|%t) - Connection_Handler[%d]::"
00334 "close_connection_eh, removing from the reactor\n",
00335 handle));
00336 }
00337
00338
00339
00340
00341
00342
00343
00344 ACE_HANDLE tmp_handle = handle;
00345 if (this->orb_core_->has_shutdown ())
00346 tmp_handle = (ACE_HANDLE) id;
00347
00348 eh_reactor->remove_handler (tmp_handle,
00349 ACE_Event_Handler::ALL_EVENTS_MASK |
00350 ACE_Event_Handler::DONT_CALL);
00351
00352
00353
00354 if (TAO_debug_level)
00355 {
00356 ACE_DEBUG ((LM_DEBUG,
00357 "TAO (%P|%t) - Connection_Handler[%d]::"
00358 "close_connection_eh, cancel all timers\n",
00359 handle));
00360 }
00361
00362 eh_reactor->cancel_timer (eh);
00363
00364
00365
00366 this->transport ()->wait_strategy ()->is_registered (false);
00367 }
00368
00369
00370
00371
00372
00373
00374
00375 this->transport ()->send_connection_closed_notifications ();
00376 this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
00377 this->orb_core_->leader_follower ());
00378
00379 if (TAO_debug_level)
00380 {
00381 ACE_DEBUG ((LM_DEBUG,
00382 "TAO (%P|%t) - Connection_Handler[%d]::"
00383 "close_connection_eh\n",
00384 id));
00385 }
00386
00387 return 1;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 int
00400 TAO_Connection_Handler::set_dscp_codepoint (CORBA::Boolean)
00401 {
00402 return 0;
00403 }
00404
00405 int
00406 TAO_Connection_Handler::set_dscp_codepoint (CORBA::Long)
00407 {
00408 return 0;
00409 }
00410
00411 int
00412 TAO_Connection_Handler::release_os_resources (void)
00413 {
00414 return 0;
00415 }
00416
00417
00418
00419 void
00420 TAO_Connection_Handler::pre_io_hook (int &)
00421 {
00422 }
00423
00424 void
00425 TAO_Connection_Handler::pos_io_hook (int &)
00426 {
00427 }
00428
00429 int
00430 TAO_Connection_Handler::close_handler (void)
00431 {
00432 this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
00433 this->orb_core_->leader_follower ());
00434 this->transport ()->purge_entry();
00435 this->transport ()->remove_reference ();
00436
00437
00438
00439
00440
00441
00442 return 0;
00443 }
00444
00445
00446
00447 TAO_END_VERSIONED_NAMESPACE_DECL