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 "Connection_Handler.cpp,v 1.69 2006/06/20 05:46:28 jwillemsen Exp")
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 {
00030
00031
00032 this->lock_ =
00033 this->orb_core_->resource_factory ()->create_cached_connection_lock ();
00034
00035
00036
00037 this->state_changed (TAO_LF_Event::LFS_CONNECTION_WAIT,
00038 this->orb_core_->leader_follower ());
00039 }
00040
00041 TAO_Connection_Handler::~TAO_Connection_Handler (void)
00042 {
00043 int const result =
00044 this->release_os_resources ();
00045
00046 if (result == -1 && TAO_debug_level)
00047 {
00048 ACE_ERROR ((LM_ERROR,
00049 "TAO (%P|%t) - Connection_Handler::~Connection_Handler,"
00050 "release_os_resources() failed %m\n"));
00051 }
00052
00053
00054 delete this->lock_;
00055
00056
00057 }
00058
00059
00060 int
00061 TAO_Connection_Handler::set_socket_option (ACE_SOCK &sock,
00062 int snd_size,
00063 int rcv_size)
00064 {
00065 #if !defined (ACE_LACKS_SOCKET_BUFSIZ)
00066
00067 if (snd_size != 0
00068 && sock.set_option (SOL_SOCKET,
00069 SO_SNDBUF,
00070 (void *) &snd_size,
00071 sizeof (snd_size)) == -1
00072 && errno != ENOTSUP)
00073 {
00074 return -1;
00075 }
00076
00077 if (rcv_size != 0
00078 && sock.set_option (SOL_SOCKET,
00079 SO_RCVBUF,
00080 (void *) &rcv_size,
00081 sizeof (int)) == -1
00082 && errno != ENOTSUP)
00083 {
00084 return -1;
00085 }
00086 #else
00087 ACE_UNUSED_ARG (snd_size);
00088 ACE_UNUSED_ARG (rcv_size);
00089 #endif
00090
00091 (void) sock.enable (ACE_CLOEXEC);
00092
00093
00094
00095
00096 return 0;
00097 }
00098
00099 int
00100 TAO_Connection_Handler::svc_i (void)
00101 {
00102 int result = 0;
00103
00104 if (TAO_debug_level > 0)
00105 ACE_DEBUG ((LM_DEBUG,
00106 ACE_TEXT ("TAO (%P|%t) - Connection_Handler::svc_i begin\n")));
00107
00108
00109
00110
00111
00112 ACE_Time_Value *max_wait_time = 0;
00113 ACE_Time_Value timeout;
00114 ACE_Time_Value current_timeout;
00115
00116 if (this->orb_core_->thread_per_connection_timeout (timeout))
00117 {
00118 current_timeout = timeout;
00119 max_wait_time = ¤t_timeout;
00120 }
00121
00122 TAO_Resume_Handle rh (this->orb_core_,
00123 ACE_INVALID_HANDLE);
00124
00125
00126
00127
00128
00129
00130 while (!this->orb_core_->has_shutdown ()
00131 && result >= 0)
00132 {
00133
00134 (void) this->transport ()->update_transport ();
00135
00136 result =
00137 this->transport ()->handle_input (rh,
00138 max_wait_time);
00139
00140 if (result == -1 && errno == ETIME)
00141 {
00142
00143
00144 result = 0;
00145
00146
00147
00148
00149 errno = 0;
00150 }
00151 else if (result == -1)
00152 {
00153
00154 return result;
00155 }
00156
00157 current_timeout = timeout;
00158
00159 if (TAO_debug_level > 0)
00160 ACE_DEBUG ((LM_DEBUG,
00161 "TAO (%P|%t) - Connection_Handler::svc_i - "
00162 "loop <%d>\n", current_timeout.msec ()));
00163 }
00164
00165 if (TAO_debug_level > 0)
00166 ACE_DEBUG ((LM_DEBUG,
00167 "TAO (%P|%t) - Connection_Handler::svc_i end\n"));
00168
00169 return result;
00170 }
00171
00172 void
00173 TAO_Connection_Handler::transport (TAO_Transport* transport)
00174 {
00175 this->transport_ = transport;
00176
00177
00178 this->transport_->event_handler_i ()->reference_counting_policy ().value (
00179 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
00180 );
00181 }
00182
00183 int
00184 TAO_Connection_Handler::handle_output_eh (
00185 ACE_HANDLE, ACE_Event_Handler * eh)
00186 {
00187
00188 (void) this->transport ()->update_transport ();
00189
00190
00191
00192 TAO_Resume_Handle resume_handle (this->orb_core (),
00193 eh->get_handle ());
00194
00195 int return_value = 0;
00196 this->pre_io_hook (return_value);
00197 if (return_value != 0)
00198 {
00199 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00200 return return_value;
00201 }
00202
00203 return_value = this->transport ()->handle_output ();
00204
00205 this->pos_io_hook (return_value);
00206
00207 if (return_value != 0)
00208 {
00209 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00210 }
00211
00212 return return_value;
00213 }
00214
00215 int
00216 TAO_Connection_Handler::handle_input_eh (
00217 ACE_HANDLE h, ACE_Event_Handler *eh)
00218 {
00219
00220 if (!this->transport ()->wait_strategy ()->can_process_upcalls ())
00221 {
00222 if (TAO_debug_level > 6)
00223 ACE_DEBUG ((LM_DEBUG,
00224 "TAO (%P|%t) - Connection_Handler[%d]::handle_input_eh, "
00225 "not going to handle_input on transport "
00226 "because upcalls temporarily suspended on this thread\n",
00227 this->transport()->id()));
00228 return 0;
00229 }
00230
00231 int const result = this->handle_input_internal (h, eh);
00232
00233 if (result == -1)
00234 {
00235 this->close_connection ();
00236 return 0;
00237 }
00238
00239 return result;
00240 }
00241
00242 int
00243 TAO_Connection_Handler::handle_input_internal (
00244 ACE_HANDLE h, ACE_Event_Handler * eh)
00245 {
00246
00247 (void) this->transport ()->update_transport ();
00248
00249
00250
00251
00252 size_t const t_id =
00253 this->transport ()->id ();
00254
00255 if (TAO_debug_level > 6)
00256 {
00257 ACE_HANDLE handle = eh->get_handle();
00258 ACE_DEBUG ((LM_DEBUG,
00259 "TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
00260 "handle = %d/%d\n",
00261 t_id, handle, h));
00262 }
00263
00264 TAO_Resume_Handle resume_handle (this->orb_core (),
00265 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 ()->purge_entry ();
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::release_os_resources (void)
00407 {
00408 return 0;
00409 }
00410
00411
00412
00413 void
00414 TAO_Connection_Handler::pre_io_hook (int &)
00415 {
00416 }
00417
00418 void
00419 TAO_Connection_Handler::pos_io_hook (int &)
00420 {
00421 }
00422
00423 int
00424 TAO_Connection_Handler::close_handler (void)
00425 {
00426 this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
00427 this->orb_core_->leader_follower ());
00428 this->transport ()->remove_reference ();
00429 return 0;
00430 }
00431
00432
00433
00434 TAO_END_VERSIONED_NAMESPACE_DECL