diff options
author | Johnny Willemsen <jwillemsen@remedy.nl> | 2004-08-09 11:53:16 +0000 |
---|---|---|
committer | Johnny Willemsen <jwillemsen@remedy.nl> | 2004-08-09 11:53:16 +0000 |
commit | 5eab0611201c153800002942b0bd5d06743085a5 (patch) | |
tree | 9db9c40b62eb2bf93e31f5fbf3a479f450148a10 /TAO | |
parent | 659b1d7d4d4d401cff367f8d6e53f07eaf75057a (diff) | |
download | ATCD-5eab0611201c153800002942b0bd5d06743085a5.tar.gz |
ChangeLogTag: Mon Aug 9 11:51:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl>
Diffstat (limited to 'TAO')
38 files changed, 1644 insertions, 521 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index d29e166e7f5..c1cab5d9115 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,684 @@ +Mon Aug 9 11:51:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + Integration of the fixes for bug 1476. In short, when making oneway + calls with sync_none policy applied, the ORB shouldn't block, this was + working for all calls, except for the first call, the connection + establishment blocked and violated the meaning of sync_none. All changes + below are there to also don't block on the first call, but just queue + the messages until the transport is connection. Thanks to Bala for + helping with this. + + Fri Aug 6 15:27:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector: + * tao/SCIOP_Connection: + * tao/UIOP_Connector: + * orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp: + * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp: + As last step in the make_connection register the transport with the + reactor when the transport is connected. When it is not connected it + will or happen in the Transport_Connector when there the connection + is established or in the Transport::post_open when the transport is + connected and we have outgoing data. + + Fri Aug 6 15:11:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp (make_connection): + * tao/Transport_Connector.cpp (connect): + Corrected method name in debug statement + + Fri Aug 6 14:58:18 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/IIOP_Connector.cpp: + * tao/Transport_Connector.cpp: + + Test for is_connected () before registration. + + Fri Aug 6 14:11:10 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/IIOP_Connection_Handler.cpp: + + Cosmetic fix. + + * tao/IIOP_Connector.cpp: + + Register handler after the caching the transport. + + * tao/Transport.cpp: + + Register handler if there is a non-empty queue. then call + schedule_wakeup (). Added locks to prevents races. + + Removed locks from format_queue_message (), since I think its + not necessary. + + * tao/Transport.inl: + + Added a lock to is_connected (). This introduces a lock on the + critical path. We need to think about this later. + + * tao/Transport_Connector.cpp: + + Added code to register the handler with the reactor. + + Fri Aug 6 13:52:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connection_Handler.cpp: + Removed duplicate include + + * ace/Thread_Per_Connection_Handler.cpp: + Corrected classname in debug statement + + Thu Aug 5 08:09:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Invocation_Adapter.{h,cpp}: + Renamed set_sync_policy to set_response_flags, we are setting + the response flags using sync_policy for oneways. Also, when + having a twoway set the correct response_flags, this was done + later in the twoday invocation, but the response_flags are + SYNC_NONE by default, resulting that all twoways used a non + blocking connect. By setting the response_flags earlier, the + blocked member of the profile transport resolver is set + to the correct value + + * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp: + Corrected some errors + + * tao/Transport.cpp: + When we are not connected, also purge us from the connection + cache. When we are connected, the connection closure will do this + but not when we are not connected. Use in recache_transport() the + this->purge_entry() call to reduce code duplication + + * tao/IIOP_Connector: + * tao/SCIOP_Connection: + * tao/UIOP_Connector: + * orbsvcs/orbsvcs/SSLIOP_Connector.cpp: + * orbsvcs/orbsvcs/IIOP_SSL_Connector.cpp: + When the connect() calls return -1, only when errno == EWOULDBLOCK + we wait for completion, for other errno's we have to set + transport to zero, because the transport is not usable in that + case and we just don't have a connection then. + + Wed Aug 4 09:44:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * orbsvs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp: + * orbsvs/orbsvcs/SSLIOP/SSLIOP_Connector.{h,cpp}: + * orbsvs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp: + Updated for changes. These files wheren't added to my original + branch and they where recently changed by Ossame, so make a new + branch bug1476 on the head, so that I can merge all changes in one + action to the main + + Wed Aug 4 09:31:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp: + Fixed typo in debug line + + * tao/IIOP_Connector.h: + Added virtual to cancel_svc_handler() to show that this is a virtual + method. + + * tao/Strategies/DIOP_Connection_Handler.cpp: + * tao/Strategies/SCIOP_Connection_Handler.cpp: + * tao/Strategies/SHMIOP_Connection_Handler.cpp: + * tao/Strategies/UIOP_Connection_Handler.cpp: + * tao/Strategies/DIOP_Connector.{h,cpp}: + * tao/Strategies/SCIOP_Connector.{h,cpp}: + * tao/Strategies/SHMIOP_Connector.{h,cpp}: + * tao/Strategies/UIOP_Connector.{h,cpp}: + Updated these protocols with all changes we did in the base classes + + Tue Aug 3 11:56:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + An overview of the changes in the pluggable transport interface + which has to be done in all pluggable transports: + * Connection_Handler::open(), instead of setting just the id of the + transport, call transport::post_open() with the id, this will set + the id, mark the transport as connected, register the transport with + the reactor and in case there is data in the outgoing queue it + will also schedule the transport for output. + * Connection_Handler::close(), check the implementation of this + method, it should in most cases sufficient to just call + this->close_handler(). + * Connector::make_connection(), check using the profile transport + resolver whether to make a blocked connect or non blocked. A non + blocked is done when making oneways with sync_none policy applied. + In case the connect returns -1 and errno == EWOULDBLOCK use the + base method wait_for_connection_completion to wait for the + connection to be established. Don't register here anymore the + transport with the reactor, this is already done in your derived + Connection_Handler::open() by calling the post_open() + * Connector::cancel_svc_handler, a new method that must be + implemented by each pluggable protocol to cancel the connection + handler from the connector. + + Tue Aug 3 09:45:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Remove_Invocation.cpp: + Removed debug comment + + Tue Aug 3 09:21:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.{h,cpp}: + * tao/IIOP_Connector.cpp: + Changed signature of wait_for_connection_completion, pass transport + as *&, so that is can be set to 0 when not usable and return a bool + whether succeeded or not. + + Tue Aug 3 08:25:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.h: + Corrected link to pluggable protocols documentation + + Mon Aug 2 18:20:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.cpp: + Added wait_for_connection_completion() which now contains the code + from connect that handles the waiting until the connection is + completed. The only thing is the result value, maybe add a bool as + return value and pass Transport by *&, what about that? + + * tao/IIOP_Connector.cpp: + Use the new Transport_Connector::wait_for_connection_completion + instead of doing everything here again + + Mon Aug 2 13:52:27 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/Transport_Connector.cpp (connect): + + Left some comments for Johnny. + + Mon Aug 2 09:45:36 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.h: + Added a todo that event_handler_i has to be renamed to event_handler + + * tao/Transport.cpp (send_message_shared_i): + Use ACE_ERROR for a fatal message instead of a debug + + Mon Aug 2 09:16:36 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.cpp (connect): + Refactored this method so that checking for errors is easier, seems + to me that part of this method can be factored out again and can + then also be called from IIOP_Connector::make_connection(). Added + some remarks for Bala, in case we do a wait of zero on a non + blocking connection, how to handle any return value? + + Mon Aug 2 07:54:36 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,cpp}: + Changed the result value type of post_open from int to bool. In case + registration succeeds and we have data in our outgoing queue, + schedule ourselves for output. + + * tao/IIOP_Connection_Handler.cpp: + Check the result value of post_open. In case this fails, we return + -1, the setting of the state to success, is now moved after the + post_open. + + * tao/IIOP_Connector.cpp: + Added a comment for Bala. Only call check_connection_closure when + wait return -1. + + * tao/Transport_Connector.{h,cpp}: + Only when wait fails call check_connection_closure. Removed the + result argument from this method, the caller should only call this + when wait returns -1, clarified the return value meaning. Removed + the printing of errno when connection establishment fails, shouldn't + we do the same in TAO_IIOP_Connector::make_connection()? + + Not all comments of Bala below are handled yet, handling + of connection failures must still be improved. + + Mon Aug 2 03:40:36 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/Transport_Connector.cpp: + + Fixed a logic error and added a few comments for Johnny. + + * tao/IIOP_Connection_Handler.cpp: + * tao/IIOP_Connector.cpp: + * tao/Transport.cpp: + * tao/Transport_Connector.h: + + More comments for Johnny. + + Fri Jul 30 10:25:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.cpp: + * tao/Transport_Connector.cpp: + * tao/IIOP_Connector.cpp: + Added some comments, removed commented out code + + * tao/IIOP_Connection_Handler.cpp: + Removed not needed include which I added during my changes but is + now not needed anymore + + * tao/Invocation_Endpoint_Selectors.cpp: + Removed comments and changed the logic of selecting an endpoint, if + one isn't usable not break but try the next. + + Thu Jul 29 13:35:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.cpp: + Removed not needed include + + Thu Jul 29 13:35:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,cpp}: + Renamed set_connected to post_open, we do much more then just + setting a property. When the transport is connected we register + ourselves with the reactor. In case of failure we close the + connection. The thing to check is whether it is safe to assume that + we are also in the transport cache + + * tao/Transport_Connector.{h,cpp}: + Removed register_transport() because the transport register itselves + now. Also removed the calls to register_transport, we don't have to + register the transport as connector anymore, the transport does + that. + + * tao/IIOP_Connector.cpp (make_connection): + Removed the registration of the transport with the reactor, see + above. Use a ACE_Event_Handler_var to make sure that we always do + a remove reference on the connection handler. + + * tao/IIOP_Connection_Handler.cpp (open): + Call transport::post_open instead of set_connected + + Thu Jul 29 10:00:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.cpp (set_connected): + Commented out schedule_output, this doesn't work, have to think + about something else + + * tao/Transport_Connector.cpp (connect): + When we get a connected transport out of the transport cache it can + happen that another thread drove the reactor and set the transport + to connected, but then it is not registered with the reactor, so add + a check here that when we get a connected transport and it is not + registered it yet, register it. + + In case we get a setup where the connection_handler::open() could + safely register it, we could remove the checks above. + + Thu Jul 29 08:44:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.cpp (connect): + Added more error handling to handle situations where connections + can't be established + + Wed Jul 28 15:24:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.{h,cpp} + Added pure virtual cancel_svc_handler() method which must be + implemented by derived connectors to cancel the passed svc_handler + with their base connector, the cancel on the base_connector must + have derived connection handler, so we just can't do it in the base. + Another option would be to make Transport_Connector a template which + gets the connection handler type as template argument. + Added also check_connection_closure, which is now generic and can + also be used from the connect() call. + + * tao/IIOP_Connector.{h,cpp}: + Implemented the cancel_svc_handler() and removed the + check_connection_closure() because it is now in the base. + + Tue Jul 27 18:12:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Connection_Handler.{h,cpp}: + Added virtual close_handler() method, this will be called the the + Transport_Connector and derived classes if they want to close the + connection_handler, the default implementation changes the LF state + to closed and removes a reference from the transport + + * tao/IIOP_Connection_Handler.cpp (close): + Instead of modifing the LF state and removing a reference from the + transport, just call this->close_handler(), this calls the + Connection_Handler::close_handler(). + + With this we can close handlers in a generic way from the + Transport_Connectors. + + When we would move a template class between + the ACE_Svc_Handler template and the derived connection handlers, + this extra template could implement the close method in a generic + way, this would reduce the footprint a little. + + * tao/IIO_Connector.cpp: + Moved docu to the correct place + + Tue Jul 27 17:26:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connection_Handler.cpp: + Instead of modifying the transport in several steps, just call + set_connected which will do all work. + + * tao/Transport.{h,cpp,inl}: + Removed the is_connected accessor, made a set_connected, which will + set the id, set the connected_ bool and will schedule an output + when the queue is not empty + + Tue Jul 27 12:28:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,cpp}: + * tao/Synch_Invocation.cpp: + Renamed queue_message to format_queue_message + + Tue Jul 27 12:22:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,cpp}: + Added out_stream() which returns the out_stream from the + messaging_object, this way the invocation classes don't need to use + messaging_object anymore, just get the stream from the transport + + * tao/Synch_Invocation.cpp: + * tao/Messaging/Asynch_Invocation.cpp: + * tao/LocateRequest_Invocation.cpp: + Instead of getting the out_stream from the messaging_object which is + retrieved from the transport, get it from the transport. This way we + don't have to include tao/Pluggable_Messaging.h + + Tue Jul 27 08:37:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.{h,cpp}: + Factered out the registration of the transport into + register_transport() + + Tue Jul 27 07:31:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Sync_Invocation.cpp: + * tao/Transport.{h,cpp}: + Changed queue_message so that transport does the formatting + + Tue Jul 27 02:47:18 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/Synch_Invocation.cpp: + + Left some comments for Johnny. + + Mon Jul 26 13:48:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Synch_Invocation.cpp (remote_oneway): + When queueing the message, stream it first else we just queue no + message contents. The only question is how to handle the failure + of the streaming + + Mon Jul 26 13:09:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,cpp}: + Moved cleaning up the queue out of destruction and + send_connection_closed_notifications_i annd into the new method + cleanup_queue_i which is called from these places + + * tao/IIOP_Connection_Handler.cpp: + Marked the transport as connected after we changed the state to + success + + * tao/IIOP_Connector.cpp: + We have to handle the timeout of wait, made an implementation, but + with a remark to Bala to check this, not sure if this is the correct + way todo. + + Mon Jul 26 11:38:41 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/Transport.cpp (TAO_Transport): + + Left a comment for Johnny. + + Mon Jul 26 11:04:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Invocation_Adapter.cpp: + Check for blocked or not blocked connection was wrong + + * tao/Transport_Connector.cpp: + Corrected debug statement + + Mon Jul 26 09:24:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.cpp: + In case we destruct a not connected transport it can happen that + we have queued messages, zap these then from memory, we just can't + deliver them. + + Sat Jul 24 18:08:13 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/Connect_Strategy.h: + + Added a new wait () method which takes in a transport. + + * tao/Blocked_Connect_Strategy.cpp: + * tao/Blocked_Connect_Strategy.h: + + Provided a default implementation for the new wait () method. + + * tao/LF_Connect_Strategy.cpp: + * tao/LF_Connect_Strategy.h: + * tao/Reactive_Connect_Strategy.cpp: + * tao/Reactive_Connect_Strategy.h: + + Provided an implementation of the new wait () method. + + * tao/Invocation_Adapter.h: + + Changed the setup_operation_details_i () to set_syncscope_policy + () since that is what it does. + + * tao/Invocation_Adapter.cpp: + + Changed the operation name in the implementation of the above + method. Did a bunch of cosmetic changes to keep the line lengths + smaller. + + * tao/Profile_Transport_Resolver.h: + * tao/Profile_Transport_Resolver.inl: + + Changed the name of the connected () method as blocked + (). Improved const correctness so that the blocked_ data member + is const. + + * tao/Invocation_Endpoint_Selectors.cpp: + + Use TAO::ProfileTransportResolver::blocked () instead of + TAO::ProfileTransportResolver::connected (). + + * tao/Transport_Connector.cpp: + * tao/IIOP_Connector.cpp: + + Made a bunch of changes to improve readability of the code. Left + a couple of questions for Johnny. There are a few more things + that need to be addressed here. + + Fri Jul 22 09:54:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp (make_connection): + Call the check_connection_closure only when we want to have a + connected transport, for the non-blocking case we have to do + something else because the return value of -1 doesn't mean there + always the we have a problem just establishing this connection. + + * tao/IIOP_Connector.{h,cpp} (check_connection_closure): + Changed method signature to have a return value + + Fri Jul 22 09:20:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.cpp (connect): + When getting a transport out of the cache, print out whether it is + connected or not + + Thu Jul 21 15:03:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp (make_connection): + Use timeout to change the sync_options, this way we don't change + the bitmask + + Thu Jul 21 14:34:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/ORB_Core.h: + Removed the transport_cache accessor method, it was just declared + and not implemented, the ORB_Core know nothing about this + + Thu Jul 21 13:35:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.cpp: + In case we have a not connected transport we should look if we need + to deliver a connected transport or not and behave accordingly to it + + Wed Jul 20 15:25:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/TAO_Server_Request.cpp: + Updated all ACE_DEBUG and ACE_ERROR macros so that the formatting of + messages is the same as in the rest of TAO. This makes reading the + logfiles much easier. + + Wed Jul 20 14:42:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp (make_connection): + Removed commented out code and only check for registration errors + when we are calling the register_handler(). + + Wed Jul 20 11:12:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.cpp: + Changed some remarks, some are not valid, some need some more + clarification + + * tao/IIOP_Connector.{h,cpp}: + Moved the handling of connection closure to a new separate method + check_connection_closure(). This contains code original in + make_connection(). This code is dependent on the type of tranport + used, so it can't move into the base class. + + Thu Jul 8 14:50:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connection_Handler.cpp (open): + Set the transport to connected here. We should refactor the last + lines of this method, these lines are copied in each different type + of connection_handler. + + * tao/IIOP_Connector.cpp: + Removed not needed code, just us is_connected() on the transport. + Made a remark with the registration of the wait_strategy, do we need + to do this here? + + * tao/Transport_Connector.cpp: + Use the transport->is_connected() instead of the wait of the result. + + Thanks to Bala for getting me on the right track. + + Thu Jul 8 13:18:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp: + * tao/Transport_Connector.cpp: + Some changes to handle the wait, but things are still not correct + + * tao/Transport.cpp: + Initialize is_connected+ to false + + Thu Jul 8 11:58:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp: + Added some test code for how the handle the wait result value + + * tao/Transport_Connector.cpp: + Added more logic what to do when a not connected transport is + retrieved + + Mon Jul 5 12:37:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,cpp}: + Removed commented out method in the header file and give purge_entry + a return value, so that we can check for failure. + + Mon Jul 5 12:02:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/IIOP_Connector.cpp: + * tao/Transport_Connector.cpp: + * tao/Profile_Transport_Resolver.cpp: + Added some documentation and added some question to some code parts + to be sure that we check this + + Fri Jul 2 11:32:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Invocation_Adapter.{h,cpp}: + Added setup_operation_details_i() which will setup the operation + details and determine whether we want to block until a connection + is ready or not, this removes duplicated code and we ony determine + the settings once in the invocation path. + + Thu Jul 1 12:52:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport_Connector.{h,cpp}: + Removed the block argument from the make_connection and connect + method again, if we should get a connected transport or not can be + retrieved from the ProfileTransportResolver + + * tao/Transport_Connector.cpp: + In case we get a transport from the cache that is not connected, + call wait with zero time. We have to add more functionality here + to handle the closing of that transport, and check the + implementation what we do when we can't register the wait strategy + with the reactor + + * tao/IIOP_Connector.{h,cpp}: + Added better handling of blocking or non-blocking connects. + + Thu Jul 1 10:02:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,inl}: + Added connection_handler accessor function and made + connetion_handler_i protected again + + * tao/Transport_Connector.cpp: + Use Transport::connection_handler instead of the _i version. + + Wed Jun 30 14:26:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Profile_Transport_Resolver.{h,cpp,i}: + Instead of passed with each operation whether the connect should + block or not, we now pass a boolean with the constructor if this + tranport must deliver a connected transport or whether it is also + allowed to deliver a not connected transport. Added an accessor for + this member. + + * tao/Invocation_Adapter.cpp: + * tao/Invocation_Endpoint_Selectors.{h,cpp}: + * tao/LocateRequest_Invocation_Adapter.cpp: + Instead of passing the block boolean with each operation, pass it + with the constructor or the Profile_Transport_Resolver. + + Wed Jun 30 10:19:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Synch_Invocation (remote_oneway): + At the top of the method we check for sync with server or sync with + target. In case of this we do a twoway. I don't see any reason why + lower in the method we check another time for sync with server, so + removed that check. Changed the calling of + Synch_Twoway_Invocation::remote_twoway(), so that we check for + exceptions in case of emulated exception macros. Add transport local + variable, so that we don't need to get it several times in one + method call. + + * tao/Transport.cpp (send_message_shared_i): + Removed queueing, it should be here, added some comments that the + code checking for twoways or replies should go out of here. This + class also got the new methods queue_message and queue_message_i + when it was created as branch. + + Tue Jun 20 10:10:10 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> + + * tao/Transport.{h,cpp}: + Added queue_message and queue_message_i to be able to queue a + message from the outside, use this method also internally. + Added connected_ member and accessors to indicate whether this + transport is connected or not + + * tao/LocateRequest_Invocation_Adapter.cpp: + We use the Profile_Transport_Resolver here, assume that we always + need to get a connected transport + Mon Aug 9 09:29:12 UTC 2004 Johnny Willemsen <jwillemsen@remedy.nl> * tao/Buffer_Allocator_T.h: diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp index a13d41276d7..b2c65d931e1 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.cpp @@ -10,6 +10,7 @@ #include "tao/Thread_Lane_Resources.h" #include "tao/Connect_Strategy.h" #include "tao/Wait_Strategy.h" +#include "tao/Profile_Transport_Resolver.h" #include "ace/Strategies_T.h" @@ -125,7 +126,7 @@ TAO::IIOP_SSL_Connector::set_validate_endpoint (TAO_Endpoint *endpoint) if (TAO_debug_level > 0) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) IIOP connection failed.\n") + ACE_TEXT ("TAO (%P|%t) IIOP_SSL connection failed.\n") ACE_TEXT ("TAO (%P|%t) This is most likely ") ACE_TEXT ("due to a hostname lookup ") ACE_TEXT ("failure.\n"))); @@ -139,7 +140,7 @@ TAO::IIOP_SSL_Connector::set_validate_endpoint (TAO_Endpoint *endpoint) TAO_Transport * TAO::IIOP_SSL_Connector::make_connection ( - TAO::Profile_Transport_Resolver *, + TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface &desc, ACE_Time_Value *max_wait_time) { @@ -163,6 +164,16 @@ TAO::IIOP_SSL_Connector::make_connection ( this->active_connect_strategy_->synch_options (max_wait_time, synch_options); + // If we don't need to block for a transport just set the timeout to + // be zero. + ACE_Time_Value tmp_zero (ACE_Time_Value::zero); + if (!r->blocked ()) + { + synch_options.timeout (ACE_Time_Value::zero); + max_wait_time = &tmp_zero; + } + + IIOP_SSL_Connection_Handler *svc_handler = 0; // Connect. @@ -189,97 +200,45 @@ TAO::IIOP_SSL_Connector::make_connection ( // another thread pick up the completion and potentially deletes the // handler before we get a chance to increment the reference count. - // No immediate result. Wait for completion. - if (result == -1 && errno == EWOULDBLOCK) - { - if (TAO_debug_level) - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_SSL_Connector::make_connection(), " - "going to wait for connection completion on local" - "handle [%d]\n", - svc_handler->get_handle ())); - - // Wait for connection completion. No need to specify timeout - // to wait() since the correct timeout was passed to the - // Connector. The Connector will close the handler in the case - // of timeouts, so the event will complete (either success or - // failure) within timeout. - result = - this->active_connect_strategy_->wait (svc_handler, - 0); - - if (TAO_debug_level > 2) - { - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_SSL_Connector::make_connection(), " - "wait done for handle[%d], result = %d\n", - svc_handler->get_handle (), result)); - } - - // There are three possibilities when wait() returns: (a) - // connection succeeded; (b) connection failed; (c) wait() - // failed because of some other error. It is easy to deal with - // (a) and (b). (c) is tricky since the connection is still - // pending and may get completed by some other thread. The - // following code deals with (c). + // Make sure that we always do a remove_reference + ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler); - // Check if the handler has been closed. - int closed = - svc_handler->is_closed (); + TAO_Transport *transport = + svc_handler->transport (); - // In case of failures and close() has not be called. - if (result == -1 && - !closed) + if (result == -1) + { + // No immediate result, wait for completion + if (errno == EWOULDBLOCK) { - // First, cancel from connector. - this->base_connector_.cancel (svc_handler); - - // Double check to make sure the handler has not been closed - // yet. This double check is required to ensure that the - // connection handler was not closed yet by some other - // thread since it was still registered with the connector. - // Once connector.cancel() has been processed, we are - // assured that the connector will no longer open/close this - // handler. - closed = - svc_handler->is_closed (); - - // If closed, there is nothing to do here. If not closed, - // it was either opened or is still pending. - if (!closed) + // Try to wait until connection completion. Incase we block, then we + // get a connected transport or not. In case of non block we get + // a connected or not connected transport + if (!this->wait_for_connection_completion (r, + transport, + max_wait_time)) { - // Check if the handler has been opened. - int open = - svc_handler->is_open (); - - // Some other thread was able to open the handler even - // though wait failed for this thread. - if (open) - // Overwrite <result>. - result = 0; - else - { - // Assert that it is still connecting. - ACE_ASSERT (svc_handler->is_connecting ()); - - // Force close the handler now. - svc_handler->close (); - } + if (TAO_debug_level > 2) + ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - IIOP_SSL_Connector::" + "make_connection, " + "wait for completion failed\n")); } } + else + { + // Transport is not usable + transport = 0; + } } - // Irrespective of success or failure, remove the extra #REFCOUNT#. - svc_handler->remove_reference (); - - // In case of errors. - if (result == -1) + // In case of errors transport is zero + if (transport == 0) { // Give users a clue to the problem. if (TAO_debug_level) { ACE_DEBUG ((LM_ERROR, - "TAO (%P|%t) - IIOP_Connector::make_connection, " + "TAO (%P|%t) - IIOP_SSL_Connector::make_connection, " "connection to <%s:%d> failed (%p)\n", iiop_endpoint->host (), iiop_endpoint->port (), "errno")); @@ -292,14 +251,11 @@ TAO::IIOP_SSL_Connector::make_connection ( // #REFCOUNT# is one. if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_Connector::make_connection, " + "TAO (%P|%t) - IIOP_SSL_Connector::make_connection, " "new connection to <%s:%d> on Transport[%d]\n", iiop_endpoint->host (), iiop_endpoint->port (), svc_handler->peer ().get_handle ())); - TAO_Transport *transport = - svc_handler->transport (); - // Add the handler to Cache int retval = this->orb_core ()->lane_resources ().transport_cache ().cache_transport ( @@ -315,36 +271,54 @@ TAO::IIOP_SSL_Connector::make_connection ( if (TAO_debug_level > 0) { ACE_ERROR ((LM_ERROR, - "TAO (%P|%t) - IIOP_Connector::make_connection, " + "TAO (%P|%t) - IIOP_SSL_Connector::make_connection, " "could not add the new connection to cache\n")); } return 0; } - // If the wait strategy wants us to be registered with the reactor - // then we do so. If registeration is required and it succeeds, - // #REFCOUNT# becomes two. - retval = transport->wait_strategy ()->register_handler (); - - // Registration failures. - if (retval != 0) + if (transport->is_connected () && + transport->wait_strategy ()->register_handler () != 0) { - // Purge from the connection cache. - transport->purge_entry (); + // Registration failures. + + // Purge from the connection cache, if we are not in the cache, this + // just does nothing. + (void) transport->purge_entry (); // Close the handler. - svc_handler->close (); + (void) transport->close_connection (); if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - "TAO (%P|%t) - IIOP_Connector::make_connection, " - "could not register the new connection in the reactor\n")); - } + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - IIOP_SSL_Connector [%d]::make_connection, " + "could not register the transport " + "in the reactor.\n", + transport->id ())); return 0; } return transport; } + +int +TAO::IIOP_SSL_Connector::cancel_svc_handler ( + TAO_Connection_Handler * svc_handler) +{ + IIOP_SSL_Connection_Handler* handler= + dynamic_cast<IIOP_SSL_Connection_Handler*>(svc_handler); + + if (handler) + { + // Cancel from the connector + this->base_connector_.cancel (handler); + + return 0; + } + else + { + return -1; + } +} diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.h b/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.h index 24f4481fc61..ab1b6449ec6 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.h +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/IIOP_SSL_Connector.h @@ -81,6 +81,8 @@ namespace TAO TAO_Transport *make_connection (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface &desc, ACE_Time_Value *timeout = 0); + + virtual int cancel_svc_handler (TAO_Connection_Handler * svc_handler); //@} private: diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp index 6660602351c..1d11ea6eb0d 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connection_Handler.cpp @@ -164,10 +164,11 @@ TAO::SSLIOP::Connection_Handler::open (void *) this->peer ().get_handle ())); } - // Set the id in the transport now that we're active. + // Set that the transport is now connected, if fails we return -1 // Use C-style cast b/c otherwise we get warnings on lots of - // compilers. - this->transport ()->id ((size_t) this->get_handle ()); + // compilers + if (!this->transport ()->post_open ((size_t) this->get_handle ())) + return -1; // @@ Not needed this->state_changed (TAO_LF_Event::LFS_SUCCESS); @@ -238,9 +239,7 @@ TAO::SSLIOP::Connection_Handler::handle_close (ACE_HANDLE, int TAO::SSLIOP::Connection_Handler::close (u_long) { - this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); - this->transport ()->remove_reference (); - return 0; + return this->close_handler (); } int diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp index cc2f125e75a..f38b37ef4bc 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp @@ -126,7 +126,7 @@ TAO::SSLIOP::Connector::connect (TAO::Profile_Transport_Resolver *resolver, { if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) Connector::connect - ") + ACE_TEXT ("TAO (%P|%t) - Connector::connect, ") ACE_TEXT ("looking for SSLIOP connection.\n"))); TAO_Endpoint *endpoint = desc->endpoint (); @@ -411,15 +411,29 @@ TAO::SSLIOP::Connector::ssliop_connect ( { if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) SSLIOP_Connector::connect ") + ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, ") ACE_TEXT ("got existing transport[%d]\n"), transport->id ())); + + // When the transport is not connected wait for completion + if (!transport->is_connected()) + { + if (!this->wait_for_connection_completion (resolver, + transport, + max_wait_time)) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect,") + ACE_TEXT ("wait for completion failed\n"))); + + } + } } else { if (TAO_debug_level > 4) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) SSLIOP_Connector::connect ") + ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, ") ACE_TEXT ("making a new connection \n"))); // Purge connections (if necessary) @@ -447,7 +461,7 @@ TAO::SSLIOP::Connector::ssliop_connect ( { if (TAO_debug_level > 0) ACE_DEBUG ((LM_ERROR, - ACE_TEXT ("(%P|%t) Unable to create SSLIOP ") + ACE_TEXT ("TAO (%P|%t) Unable to create SSLIOP ") ACE_TEXT ("service handler.\n"))); return 0; @@ -515,6 +529,15 @@ TAO::SSLIOP::Connector::ssliop_connect ( this->active_connect_strategy_->synch_options (max_wait_time, synch_options); + // If we don't need to block for a transport just set the timeout to + // be zero. + ACE_Time_Value tmp_zero (ACE_Time_Value::zero); + if (!resolver->blocked ()) + { + synch_options.timeout (ACE_Time_Value::zero); + max_wait_time = &tmp_zero; + } + // We obtain the transport in the <svc_handler> variable. As we // know now that the connection is not available in Cache we can // make a new connection @@ -530,91 +553,39 @@ TAO::SSLIOP::Connector::ssliop_connect ( // the #REFCOUNT# on the handler is one since close() gets // called on the handler. - // No immediate result. Wait for completion. - if (result == -1 && errno == EWOULDBLOCK) - { - if (TAO_debug_level > 2) - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - SSLIOP_Connector::ssliop_connect(), " - "going to wait for connection completion on local" - "handle [%d]\n", - svc_handler->get_handle ())); - - // Wait for connection completion. No need to specify timeout - // to wait() since the correct timeout was passed to the - // Connector. The Connector will close the handler in the case - // of timeouts, so the event will complete (either success or - // failure) within timeout. - result = - this->active_connect_strategy_->wait (svc_handler, - 0); - - if (TAO_debug_level > 2) - { - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_Connector::make_connection" - "wait done for handle[%d], result = %d\n", - svc_handler->get_handle (), result)); - } - - // There are three possibilities when wait() returns: (a) - // connection succeeded; (b) connection failed; (c) wait() - // failed because of some other error. It is easy to deal with - // (a) and (b). (c) is tricky since the connection is still - // pending and may get completed by some other thread. The - // following code deals with (c). + // Make sure that we always do a remove_reference + ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler); - // Check if the handler has been closed. - int closed = - svc_handler->is_closed (); + transport = + svc_handler->transport (); - // In case of failures and close() has not be called. - if (result == -1 && - !closed) + if (result == -1) + { + // No immediate result, wait for completion + if (errno == EWOULDBLOCK) { - // First, cancel from connector. - this->base_connector_.cancel (svc_handler); - - // Double check to make sure the handler has not been closed - // yet. This double check is required to ensure that the - // connection handler was not closed yet by some other - // thread since it was still registered with the connector. - // Once connector.cancel() has been processed, we are - // assured that the connector will no longer open/close this - // handler. - closed = - svc_handler->is_closed (); - - // If closed, there is nothing to do here. If not closed, - // it was either opened or is still pending. - if (!closed) + // Try to wait until connection completion. Incase we block, then we + // get a connected transport or not. In case of non block we get + // a connected or not connected transport + if (!this->wait_for_connection_completion (resolver, + transport, + max_wait_time)) { - // Check if the handler has been opened. - int open = - svc_handler->is_open (); - - // Some other thread was able to open the handler even - // though wait failed for this thread. - if (open) - // Overwrite <result>. - result = 0; - else - { - // Assert that it is still connecting. - ACE_ASSERT (svc_handler->is_connecting ()); - - // Force close the handler now. - svc_handler->close (); - } + if (TAO_debug_level > 2) + ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - SSLIOP_Connector::" + "ssliop_connect, " + "wait for completion failed\n")); } } + else + { + // Transport is not usable + transport = 0; + } } - // Irrespective of success or failure, remove the extra #REFCOUNT#. - svc_handler->remove_reference (); - - // In case of errors. - if (result == -1) + // In case of errors transport is zero + if (transport == 0) { // Give users a clue to the problem. if (TAO_debug_level) @@ -623,7 +594,7 @@ TAO::SSLIOP::Connector::ssliop_connect ( ssl_endpoint->addr_to_string (buffer, sizeof (buffer) - 1); ACE_DEBUG ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) %N:%l, SSL connection to ") + ACE_TEXT ("TAO (%P|%t) - SSL connection to ") ACE_TEXT ("<%s:%d> failed (%p)\n"), buffer, remote_address.get_port_number (), @@ -637,14 +608,11 @@ TAO::SSLIOP::Connector::ssliop_connect ( // #REFCOUNT# is one. if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - SSLIOP_Connector::ssliop_connect(): " + "TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, " "new SSL connection to port %d on transport[%d]\n", remote_address.get_port_number (), svc_handler->peer ().get_handle ())); - transport = - svc_handler->transport (); - ssl_endpoint->qop (qop); ssl_endpoint->trust (trust); ssl_endpoint->credentials (credentials.in ()); @@ -664,34 +632,31 @@ TAO::SSLIOP::Connector::ssliop_connect ( if (TAO_debug_level > 0) { ACE_ERROR ((LM_ERROR, - "TAO (%P|%t) - IIOP_Connector::make_connection, " + "TAO (%P|%t) - SLIIOP_Connector::ssliop_connect, " "could not add the new connection to cache\n")); } return 0; } - // If the wait strategy wants us to be registered with the reactor - // then we do so. If registeration is required and it succeeds, - // #REFCOUNT# becomes two. - retval = transport->wait_strategy ()->register_handler (); - - // Registration failures. - if (retval != 0) + if (transport->is_connected () && + transport->wait_strategy ()->register_handler () != 0) { - // Purge from the connection cache. - transport->purge_entry (); + // Registration failures. + + // Purge from the connection cache, if we are not in the cache, this + // just does nothing. + (void) transport->purge_entry (); // Close the handler. - svc_handler->close (); + (void) transport->close_connection (); if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - "TAO (%P|%t) - IIOP_Connector::make_connection, " - "could not register the new connection in the " - "reactor\n")); - } + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - SSLIOP_Connector [%d]::ssliop_connect, " + "could not register the transport " + "in the reactor.\n", + transport->id ())); return 0; } @@ -771,3 +736,23 @@ TAO::SSLIOP::Connector::retrieve_credentials (TAO_Stub *stub, return ssliop_credentials._retn (); } + +int +TAO::SSLIOP::Connector::cancel_svc_handler ( + TAO_Connection_Handler * svc_handler) +{ + TAO::SSLIOP::Connection_Handler* handler= + dynamic_cast<TAO::SSLIOP::Connection_Handler*>(svc_handler); + + if (handler) + { + // Cancel from the connector + this->base_connector_.cancel (handler); + + return 0; + } + else + { + return -1; + } +} diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.h b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.h index 85e4362153c..9a3a5ddb1a2 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.h +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.h @@ -81,6 +81,9 @@ namespace TAO */ virtual TAO_Profile * make_profile (ACE_ENV_SINGLE_ARG_DECL); + /// Cancel the passed cvs handler from the connector + virtual int cancel_svc_handler (TAO_Connection_Handler * svc_handler); + /// IIOP-specific connection establishment. /** * @note The IIOP endpoint is extracted from the SSLIOP endpoint. diff --git a/TAO/tao/Blocked_Connect_Strategy.cpp b/TAO/tao/Blocked_Connect_Strategy.cpp index 445daf1d21d..a7d50c3d307 100644 --- a/TAO/tao/Blocked_Connect_Strategy.cpp +++ b/TAO/tao/Blocked_Connect_Strategy.cpp @@ -45,3 +45,11 @@ TAO_Blocked_Connect_Strategy::wait (TAO_Connection_Handler *, // We cannot wait for connection completion return -1; } + +int +TAO_Blocked_Connect_Strategy::wait (TAO_Transport *, + ACE_Time_Value *) +{ + // We cannot wait for connection completion + return -1; +} diff --git a/TAO/tao/Blocked_Connect_Strategy.h b/TAO/tao/Blocked_Connect_Strategy.h index 4e04945b255..87016f0470f 100644 --- a/TAO/tao/Blocked_Connect_Strategy.h +++ b/TAO/tao/Blocked_Connect_Strategy.h @@ -45,8 +45,10 @@ public: ACE_Synch_Options &opt); virtual int wait (TAO_Connection_Handler *ch, - ACE_Time_Value *val); + ACE_Time_Value *val); + virtual int wait (TAO_Transport *t, + ACE_Time_Value *val); }; diff --git a/TAO/tao/Connect_Strategy.h b/TAO/tao/Connect_Strategy.h index 61b400e4510..488fe149d93 100644 --- a/TAO/tao/Connect_Strategy.h +++ b/TAO/tao/Connect_Strategy.h @@ -24,6 +24,7 @@ class TAO_ORB_Core; class TAO_Connector; class TAO_Connection_Handler; +class TAO_Transport; class ACE_Synch_Options; class ACE_Time_Value; @@ -65,6 +66,9 @@ public: * connection handler is set appropriately. */ virtual int wait (TAO_Connection_Handler *ch, + ACE_Time_Value *val) = 0; + + virtual int wait (TAO_Transport *t, ACE_Time_Value *val) = 0; protected: diff --git a/TAO/tao/Connection_Handler.cpp b/TAO/tao/Connection_Handler.cpp index 9ae1a7c2583..601d11ac066 100644 --- a/TAO/tao/Connection_Handler.cpp +++ b/TAO/tao/Connection_Handler.cpp @@ -265,7 +265,7 @@ TAO_Connection_Handler::close_connection_eh (ACE_Event_Handler *eh) { ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Connection_Handler[%d]::" - "close_connection, purging entry from cache\n", + "close_connection_eh, purging entry from cache\n", handle)); } @@ -311,7 +311,7 @@ TAO_Connection_Handler::close_connection_eh (ACE_Event_Handler *eh) { ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Connection_Handler[%d]::" - "close_connection, removing from the reactor\n", + "close_connection_eh, removing from the reactor\n", handle)); } @@ -325,7 +325,7 @@ TAO_Connection_Handler::close_connection_eh (ACE_Event_Handler *eh) { ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Connection_Handler[%d]::" - "close_connection, cancel all timers\n", + "close_connection_eh, cancel all timers\n", handle)); } @@ -349,7 +349,7 @@ TAO_Connection_Handler::close_connection_eh (ACE_Event_Handler *eh) { ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Connection_Handler[%d]::" - "close_connection\n", + "close_connection_eh\n", id)); } @@ -371,3 +371,11 @@ void TAO_Connection_Handler::pos_io_hook (int & ) { } + +int +TAO_Connection_Handler::close_handler (void) +{ + this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); + this->transport ()->remove_reference (); + return 0; +} diff --git a/TAO/tao/Connection_Handler.h b/TAO/tao/Connection_Handler.h index e3b348a3b2c..594eabe7831 100644 --- a/TAO/tao/Connection_Handler.h +++ b/TAO/tao/Connection_Handler.h @@ -93,6 +93,10 @@ public: */ virtual int open_handler (void *) = 0; + /// A close() hook, called by the Transport Connector when they want to close + /// this handler + virtual int close_handler (void); + protected: /// Return our TAO_ORB_Core pointer diff --git a/TAO/tao/IIOP_Connection_Handler.cpp b/TAO/tao/IIOP_Connection_Handler.cpp index cd8aa272822..2db80b17e0f 100644 --- a/TAO/tao/IIOP_Connection_Handler.cpp +++ b/TAO/tao/IIOP_Connection_Handler.cpp @@ -15,7 +15,6 @@ #include "ace/os_include/netinet/os_tcp.h" #include "ace/os_include/os_netdb.h" -#include "ace/os_include/netinet/os_tcp.h" ACE_RCSID (tao, IIOP_Connection_Handler, @@ -141,9 +140,11 @@ TAO_IIOP_Connection_Handler::open (void*) client, this->peer ().get_handle ())); } - // Set the id in the transport now that we're active. - // Use C-style cast b/c otherwise we get warnings on lots of compilers - this->transport ()->id ((size_t) this->get_handle ()); + // Set that the transport is now connected, if fails we return -1 + // Use C-style cast b/c otherwise we get warnings on lots of + // compilers + if (!this->transport ()->post_open ((size_t) this->get_handle ())) + return -1; this->state_changed (TAO_LF_Event::LFS_SUCCESS); @@ -213,9 +214,7 @@ TAO_IIOP_Connection_Handler::handle_close (ACE_HANDLE, int TAO_IIOP_Connection_Handler::close (u_long) { - this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); - this->transport ()->remove_reference (); - return 0; + return this->close_handler (); } int @@ -284,7 +283,9 @@ TAO_IIOP_Connection_Handler::process_listen_point_list ( // The property for this handler has changed. Recache the // handler with this property - int retval = this->transport ()->recache_transport (&prop); + int retval = + this->transport ()->recache_transport (&prop); + if (retval == -1) return retval; diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp index 618ff481ad7..e12e125fcb1 100644 --- a/TAO/tao/IIOP_Connector.cpp +++ b/TAO/tao/IIOP_Connector.cpp @@ -6,6 +6,7 @@ #include "Protocols_Hooks.h" #include "Connect_Strategy.h" #include "Thread_Lane_Resources.h" +#include "Profile_Transport_Resolver.h" #include "Transport.h" #include "Wait_Strategy.h" #include "ace/OS_NS_strings.h" @@ -54,7 +55,7 @@ int TAO_IIOP_Connector::open (TAO_ORB_Core *orb_core) { // @@todo: The functionality of the following two statements could - // be done in the constructor, but that involves changing the + // be done in the constructor, but that involves changing the // interface of the pluggable transport factory. // Set the ORB Core @@ -132,32 +133,42 @@ TAO_IIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint) } TAO_Transport * -TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, +TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface &desc, - ACE_Time_Value *max_wait_time) + ACE_Time_Value *timeout) { - TAO_IIOP_Endpoint *iiop_endpoint = this->remote_endpoint (desc.endpoint ()); + TAO_IIOP_Endpoint *iiop_endpoint = + this->remote_endpoint (desc.endpoint ()); if (iiop_endpoint == 0) return 0; - const ACE_INET_Addr &remote_address = iiop_endpoint->object_addr (); + const ACE_INET_Addr &remote_address = + iiop_endpoint->object_addr (); if (TAO_debug_level > 2) - { - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_Connector::make_connection, " - "to <%s:%d>\n", - ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host()), - iiop_endpoint->port())); - } + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - IIOP_Connector::make_connection, " + "to <%s:%d> which should %s\n", + ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host()), + iiop_endpoint->port(), + r->blocked () ? ACE_TEXT("block") : ACE_TEXT("nonblock"))); // Get the right synch options ACE_Synch_Options synch_options; - this->active_connect_strategy_->synch_options (max_wait_time, + this->active_connect_strategy_->synch_options (timeout, synch_options); + // If we don't need to block for a transport just set the timeout to + // be zero. + ACE_Time_Value tmp_zero (ACE_Time_Value::zero); + if (!r->blocked ()) + { + synch_options.timeout (ACE_Time_Value::zero); + timeout = &tmp_zero; + } + TAO_IIOP_Connection_Handler *svc_handler = 0; // Connect. @@ -167,13 +178,14 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, synch_options); // The connect() method creates the service handler and bumps the - // #REFCOUNT# up one extra. There are three possibilities from + // #REFCOUNT# up one extra. There are four possibilities from // calling connect(): (a) connection succeeds immediately - in this // case, the #REFCOUNT# on the handler is two; (b) connection // completion is pending - in this case, the #REFCOUNT# on the // handler is also two; (c) connection fails immediately - in this // case, the #REFCOUNT# on the handler is one since close() gets - // called on the handler. + // called on the handler; (d) the connect immediately returns when we + // have specified that it shouldn't block. // // The extra reference count in // TAO_Connect_Creation_Strategy::make_svc_handler() is needed in @@ -184,118 +196,67 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, // another thread pick up the completion and potentially deletes the // handler before we get a chance to increment the reference count. - // No immediate result. Wait for completion. - if (result == -1 && errno == EWOULDBLOCK) - { - if (TAO_debug_level > 2) - { - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_Connector::make_connection, " - "going to wait for connection completion on local" - "handle [%d]\n", - svc_handler->get_handle ())); - } + // Make sure that we always do a remove_reference + ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler); - // Wait for connection completion. - result = - this->active_connect_strategy_->wait (svc_handler, - max_wait_time); + TAO_Transport *transport = + svc_handler->transport (); - if (TAO_debug_level > 2) - { - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_Connector::make_connection" - "wait done for handle[%d], result = %d\n", - svc_handler->get_handle (), result)); - } - - // There are three possibilities when wait() returns: (a) - // connection succeeded; (b) connection failed; (c) wait() - // failed because of some other error. It is easy to deal with - // (a) and (b). (c) is tricky since the connection is still - // pending and may get completed by some other thread. The - // following code deals with (c). - - // Check if the handler has been closed. - int closed = - svc_handler->is_closed (); - - // In case of failures and close() has not be called. - if (result == -1 && !closed) + if (result == -1) + { + // No immediate result, wait for completion + if (errno == EWOULDBLOCK) { - // First, cancel from connector. - this->base_connector_.cancel (svc_handler); - - // Double check to make sure the handler has not been closed - // yet. This double check is required to ensure that the - // connection handler was not closed yet by some other - // thread since it was still registered with the connector. - // Once connector.cancel() has been processed, we are - // assured that the connector will no longer open/close this - // handler. - closed = svc_handler->is_closed (); - - // If closed, there is nothing to do here. If not closed, - // it was either opened or is still pending. - if (!closed) + // Try to wait until connection completion. Incase we block, then we + // get a connected transport or not. In case of non block we get + // a connected or not connected transport + if (!this->wait_for_connection_completion (r, + transport, + timeout)) { - // Check if the handler has been opened. - const int open = svc_handler->is_open (); - - // Some other thread was able to open the handler even - // though wait failed for this thread. - if (open) - // Overwrite <result>. - result = 0; - else - { - // Assert that it is still connecting. - ACE_ASSERT (svc_handler->is_connecting ()); - - // Force close the handler now. - svc_handler->close (); - } + if (TAO_debug_level > 2) + ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - IIOP_Connector::" + "make_connection, " + "wait for completion failed\n")); } } + else + { + // Transport is not usable + transport = 0; + } } - // Irrespective of success or failure, remove the extra #REFCOUNT#. - svc_handler->remove_reference (); - - // In case of errors. - if (result == -1) + // In case of errors transport is zero + if (transport == 0) { // Give users a clue to the problem. - if (TAO_debug_level) - { + if (TAO_debug_level > 3) ACE_DEBUG ((LM_ERROR, "TAO (%P|%t) - IIOP_Connector::make_connection, " "connection to <%s:%d> failed (%p)\n", - ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host ()), iiop_endpoint->port (), + iiop_endpoint->host (), iiop_endpoint->port (), ACE_TEXT("errno"))); - } return 0; } - // At this point, the connection has be successfully connected. - // #REFCOUNT# is one. + // At this point, the connection has be successfully created + // connected or not connected, but we have a connection. if (TAO_debug_level > 2) - { - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - IIOP_Connector::make_connection, " - "new connection to <%s:%d> on Transport[%d]\n", - ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host ()), - iiop_endpoint->port (), - svc_handler->peer ().get_handle ())); - } - - TAO_Transport *transport = svc_handler->transport (); + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - IIOP_Connector::make_connection, " + "new %s connection to <%s:%d> on Transport[%d]\n", + transport->is_connected() ? "connected" : "not connected", + iiop_endpoint->host (), + iiop_endpoint->port (), + svc_handler->peer ().get_handle ())); // Add the handler to Cache int retval = - this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc, - transport); + this->orb_core ()->lane_resources ().transport_cache ().cache_transport ( + &desc, + transport); // Failure in adding to cache. if (retval != 0) @@ -313,26 +274,24 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, return 0; } - // If the wait strategy wants us to be registered with the reactor - // then we do so. If registeration is required and it succeeds, - // #REFCOUNT# becomes two. - retval = transport->wait_strategy ()->register_handler (); - - // Registration failures. - if (retval != 0) + if (transport->is_connected () && + transport->wait_strategy ()->register_handler () != 0) { - // Purge from the connection cache. - transport->purge_entry (); + // Registration failures. + + // Purge from the connection cache, if we are not in the cache, this + // just does nothing. + (void) transport->purge_entry (); // Close the handler. - svc_handler->close (); + (void) transport->close_connection (); if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - "TAO (%P|%t) - IIOP_Connector::make_connection, " - "could not register the new connection in the reactor\n")); - } + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - IIOP_Connector [%d]::make_connection, " + "could not register the transport " + "in the reactor.\n", + transport->id ())); return 0; } @@ -343,7 +302,7 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, TAO_Profile * TAO_IIOP_Connector::create_profile (TAO_InputCDR& cdr) { - TAO_Profile *pfile; + TAO_Profile *pfile = 0; ACE_NEW_RETURN (pfile, TAO_IIOP_Profile (this->orb_core ()), 0); @@ -435,7 +394,8 @@ TAO_IIOP_Connector::init_tcp_properties (void) int no_delay = this->orb_core ()->orb_params ()->nodelay (); int enable_network_priority = 0; - TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks (ACE_ENV_SINGLE_ARG_PARAMETER); + TAO_Protocols_Hooks *tph = + this->orb_core ()->get_protocols_hooks (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (-1); if (tph != 0) @@ -482,3 +442,23 @@ TAO_IIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint) return iiop_endpoint; } + +int +TAO_IIOP_Connector::cancel_svc_handler ( + TAO_Connection_Handler * svc_handler) +{ + TAO_IIOP_Connection_Handler* handler= + dynamic_cast<TAO_IIOP_Connection_Handler*>(svc_handler); + + if (handler) + { + // Cancel from the connector + this->base_connector_.cancel (handler); + + return 0; + } + else + { + return -1; + } +} diff --git a/TAO/tao/IIOP_Connector.h b/TAO/tao/IIOP_Connector.h index d8dac4ba098..8b2bcefb164 100644 --- a/TAO/tao/IIOP_Connector.h +++ b/TAO/tao/IIOP_Connector.h @@ -99,6 +99,9 @@ protected: /// initialize <tcp_properties_>. int init_tcp_properties (void); + /// Cancel the passed cvs handler from the connector + virtual int cancel_svc_handler (TAO_Connection_Handler * svc_handler); + protected: /// TCP configuration properties to be used for all diff --git a/TAO/tao/Invocation_Adapter.cpp b/TAO/tao/Invocation_Adapter.cpp index 173782f5ee5..6331f852eca 100644 --- a/TAO/tao/Invocation_Adapter.cpp +++ b/TAO/tao/Invocation_Adapter.cpp @@ -1,4 +1,5 @@ //$Id$ + #include "Invocation_Adapter.h" #include "Profile_Transport_Resolver.h" #include "operation_details.h" @@ -20,7 +21,6 @@ ACE_RCSID (tao, Invocation_Adapter, "$Id$") - namespace TAO { void @@ -163,9 +163,10 @@ namespace TAO details, this->type_ == TAO_TWOWAY_INVOCATION); - status = coll_inv.invoke (this->cpb_, - strat - ACE_ENV_ARG_PARAMETER); + status = + coll_inv.invoke (this->cpb_, + strat + ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); if (status == TAO_INVOKE_RESTART && @@ -183,6 +184,41 @@ namespace TAO return status; } + void + Invocation_Adapter::set_response_flags ( + TAO_Stub *stub, + TAO_Operation_Details &details) + { + switch (this->type_) + { + case TAO_ONEWAY_INVOCATION: + { + // Grab the syncscope policy from the ORB. + Messaging::SyncScope sync_scope; + + bool has_synchronization = false; + + stub->orb_core ()->call_sync_scope_hook (stub, + has_synchronization, + sync_scope); + if (has_synchronization) + details.response_flags (CORBA::Octet (sync_scope)); + else + details.response_flags ( + CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)); + break; + } + case TAO_TWOWAY_INVOCATION: + { + // @@note: Need to change this to something better. Too many + // hash defines meaning the same things. + details.response_flags (TAO_TWOWAY_RESPONSE_FLAG); + break; + } + } + + return; + } Invocation_Status Invocation_Adapter::invoke_remote_i (TAO_Stub *stub, @@ -199,10 +235,15 @@ namespace TAO if (is_timeout) max_wait_time = &tmp_wait_time; + (void) this->set_response_flags (stub, + details); + // Create the resolver which will pick (or create) for us a // transport and a profile from the effective_target. - Profile_Transport_Resolver resolver (effective_target.in (), - stub); + Profile_Transport_Resolver resolver ( + effective_target.in (), + stub, + (details.response_flags () != Messaging::SYNC_NONE)); resolver.resolve (max_wait_time ACE_ENV_ARG_PARAMETER); @@ -223,9 +264,6 @@ namespace TAO } else if (this->type_ == TAO_TWOWAY_INVOCATION) { - // @@ NOTE:Need to change this to something better. Too many - // hash defines meaning the same thing.. - details.response_flags (TAO_TWOWAY_RESPONSE_FLAG); return this->invoke_twoway (details, effective_target, resolver, @@ -237,7 +275,7 @@ namespace TAO } Invocation_Status - Invocation_Adapter::invoke_twoway (TAO_Operation_Details &op, + Invocation_Adapter::invoke_twoway (TAO_Operation_Details &details, CORBA::Object_var &effective_target, Profile_Transport_Resolver &r, ACE_Time_Value *&max_wait_time @@ -257,7 +295,7 @@ namespace TAO TAO::Synch_Twoway_Invocation synch (this->target_, r, - op); + details); Invocation_Status status = synch.remote_twoway (max_wait_time @@ -267,7 +305,8 @@ namespace TAO if (status == TAO_INVOKE_RESTART && synch.is_forwarded ()) { - effective_target = synch.steal_forwarded_reference (); + effective_target = + synch.steal_forwarded_reference (); this->object_forwarded (effective_target, r.stub () @@ -279,28 +318,15 @@ namespace TAO } Invocation_Status - Invocation_Adapter::invoke_oneway (TAO_Operation_Details &op, + Invocation_Adapter::invoke_oneway (TAO_Operation_Details &details, CORBA::Object_var &effective_target, Profile_Transport_Resolver &r, ACE_Time_Value *&max_wait_time ACE_ENV_ARG_DECL) { - // Grab the syncscope policy from the ORB. - bool has_synchronization = false; - Messaging::SyncScope sync_scope; - - r.stub ()->orb_core ()->call_sync_scope_hook (r.stub (), - has_synchronization, - sync_scope); - - if (has_synchronization) - op.response_flags (CORBA::Octet (sync_scope)); - else - op.response_flags (CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)); - TAO::Synch_Oneway_Invocation synch (this->target_, r, - op); + details); Invocation_Status s = synch.remote_oneway (max_wait_time @@ -310,7 +336,8 @@ namespace TAO if (s == TAO_INVOKE_RESTART && synch.is_forwarded ()) { - effective_target = synch.steal_forwarded_reference (); + effective_target = + synch.steal_forwarded_reference (); this->object_forwarded (effective_target, r.stub () diff --git a/TAO/tao/Invocation_Adapter.h b/TAO/tao/Invocation_Adapter.h index c134d991b5d..23e75c89b8a 100644 --- a/TAO/tao/Invocation_Adapter.h +++ b/TAO/tao/Invocation_Adapter.h @@ -201,7 +201,7 @@ namespace TAO * is forwarded to a new location. */ virtual Invocation_Status invoke_twoway ( - TAO_Operation_Details &op, + TAO_Operation_Details &details, CORBA::Object_var &effective_target, Profile_Transport_Resolver &r, ACE_Time_Value *&max_wait_time @@ -215,7 +215,7 @@ namespace TAO * is forwarded to a new location to take appropriate action. */ virtual Invocation_Status invoke_oneway ( - TAO_Operation_Details &op, + TAO_Operation_Details &details, CORBA::Object_var &effective_target, Profile_Transport_Resolver &r, ACE_Time_Value *&max_wait_time @@ -235,6 +235,11 @@ namespace TAO void object_forwarded (CORBA::Object_var &effective_target, TAO_Stub *stub ACE_ENV_ARG_DECL); + + /// Helper method to set the response flags within @a details + void set_response_flags (TAO_Stub *stub, + TAO_Operation_Details &details); + protected: /// The target object on which this invocation is carried out. diff --git a/TAO/tao/Invocation_Endpoint_Selectors.cpp b/TAO/tao/Invocation_Endpoint_Selectors.cpp index 14ce667c411..6324aea5378 100644 --- a/TAO/tao/Invocation_Endpoint_Selectors.cpp +++ b/TAO/tao/Invocation_Endpoint_Selectors.cpp @@ -43,28 +43,34 @@ TAO_Default_Endpoint_Selector::select_endpoint ( { r->profile (r->stub ()->profile_in_use ()); - const size_t endpoint_count = - r->profile ()->endpoint_count (); - - TAO_Endpoint *ep = - r->profile ()->endpoint (); - - for (size_t i = 0; i < endpoint_count; ++i) + // Check whether we need to have do a blocked wait or we have a non + // blocked wait and we support that, if this is not the case we + // can't use this profile and try the next + if (r->blocked () || + (!r->blocked () && r->profile ()->supports_non_blocking_oneways ())) { - TAO_Base_Transport_Property desc (ep); + const size_t endpoint_count = + r->profile ()->endpoint_count (); + + TAO_Endpoint *ep = + r->profile ()->endpoint (); - bool retval = - r->try_connect (&desc, - max_wait_time - ACE_ENV_ARG_PARAMETER); - ACE_CHECK; + for (size_t i = 0; i < endpoint_count; ++i) + { + TAO_Base_Transport_Property desc (ep); + bool retval = + r->try_connect (&desc, + max_wait_time + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; - // Check if the connect has completed. - if (retval) - return; + // Check if the connect has completed. + if (retval) + return; - // Go to the next endpoint in this profile. - ep = ep->next (); + // Go to the next endpoint in this profile. + ep = ep->next (); + } } } while (r->stub ()->next_profile_retry () != 0); diff --git a/TAO/tao/LF_Connect_Strategy.cpp b/TAO/tao/LF_Connect_Strategy.cpp index d1aa0d78b8c..3acdc624452 100644 --- a/TAO/tao/LF_Connect_Strategy.cpp +++ b/TAO/tao/LF_Connect_Strategy.cpp @@ -2,7 +2,7 @@ #include "Connection_Handler.h" #include "LF_Follower.h" #include "Leader_Follower.h" - +#include "Transport.h" #include "ace/Synch_Options.h" ACE_RCSID(tao, @@ -40,19 +40,24 @@ int TAO_LF_Connect_Strategy::wait (TAO_Connection_Handler *ch, ACE_Time_Value *max_wait_time) { - ACE_ASSERT(ch != 0); + ACE_ASSERT (ch != 0); - // @@todo We need to use a auto_ptr<>-like object here! - // TAO_Transport * transport = ch->get_transport_locked(); - TAO_Transport *transport = ch->transport (); + return this->wait (ch->transport (), + max_wait_time); +} +int +TAO_LF_Connect_Strategy::wait (TAO_Transport *transport, + ACE_Time_Value *max_wait_time) +{ // Basically the connection was EINPROGRESS, but before we could // wait for it some other thread detected a failure and cleaned up // the connection handler. - if(transport == 0) - { - return -1; - } + if (transport == 0) + return -1; + + TAO_Connection_Handler *ch = + transport->connection_handler (); TAO_Leader_Follower &leader_follower = this->orb_core_->leader_follower (); diff --git a/TAO/tao/LF_Connect_Strategy.h b/TAO/tao/LF_Connect_Strategy.h index f2e02fc5f8b..5ca99679939 100644 --- a/TAO/tao/LF_Connect_Strategy.h +++ b/TAO/tao/LF_Connect_Strategy.h @@ -51,6 +51,10 @@ public: virtual int wait (TAO_Connection_Handler *ch, ACE_Time_Value *val); + virtual int wait (TAO_Transport *ch, + ACE_Time_Value *val); + + }; #include /**/ "ace/post.h" diff --git a/TAO/tao/LocateRequest_Invocation.cpp b/TAO/tao/LocateRequest_Invocation.cpp index 58e27158601..45e7c44dae7 100644 --- a/TAO/tao/LocateRequest_Invocation.cpp +++ b/TAO/tao/LocateRequest_Invocation.cpp @@ -3,7 +3,6 @@ #include "operation_details.h" #include "Stub.h" #include "Bind_Dispatcher_Guard.h" -#include "Pluggable_Messaging.h" #include "Transport.h" #include "Synch_Reply_Dispatcher.h" #include "GIOP_Utils.h" @@ -62,7 +61,7 @@ namespace TAO this->resolver_.transport (); TAO_OutputCDR &cdr = - transport->messaging_object ()->out_stream (); + transport->out_stream (); int retval = transport->generate_locate_request (tspec, diff --git a/TAO/tao/LocateRequest_Invocation.h b/TAO/tao/LocateRequest_Invocation.h index 8585342818a..9006ada4f05 100644 --- a/TAO/tao/LocateRequest_Invocation.h +++ b/TAO/tao/LocateRequest_Invocation.h @@ -37,7 +37,7 @@ namespace TAO /** * @class LocateRequest_Invocation * - * @brief Object created bu TAO::LocateRequest_Invocation_Adapter to + * @brief Object created by TAO::LocateRequest_Invocation_Adapter to * create and send LocateRequest invocation. * */ @@ -46,7 +46,7 @@ namespace TAO { public: /** - * @param target The target on which this invocation was + * @param otarget The target on which this invocation was * started. * * @param resolver Container of the profile and transport on diff --git a/TAO/tao/LocateRequest_Invocation_Adapter.cpp b/TAO/tao/LocateRequest_Invocation_Adapter.cpp index 20dd2f48720..0e60340a1e7 100644 --- a/TAO/tao/LocateRequest_Invocation_Adapter.cpp +++ b/TAO/tao/LocateRequest_Invocation_Adapter.cpp @@ -49,7 +49,8 @@ namespace TAO s == TAO_INVOKE_RESTART) { Profile_Transport_Resolver resolver (effective_target, - stub); + stub, + true); ACE_TRY { diff --git a/TAO/tao/ORB_Core.h b/TAO/tao/ORB_Core.h index a9836d08857..82c7df7975d 100644 --- a/TAO/tao/ORB_Core.h +++ b/TAO/tao/ORB_Core.h @@ -55,7 +55,6 @@ class TAO_Connector_Registry; class TAO_Resource_Factory; class TAO_Client_Strategy_Factory; class TAO_Server_Strategy_Factory; -class TAO_Transport_Cache_Manager; class TAO_TSS_Resources; class TAO_Leader_Follower; @@ -939,9 +938,6 @@ public: /// Return the valuetype adapter TAO_Valuetype_Adapter *& valuetype_adapter (void); - /// Return the underlying transport cache - TAO_Transport_Cache_Manager *transport_cache (void); - /// Set and Get methods to indicate whether a BiDir IIOP policy has /// been set in the POA. /// @note At present, the value will be true even if one of the POA's diff --git a/TAO/tao/Profile.cpp b/TAO/tao/Profile.cpp index 2562b36e5ee..ac369ee1acf 100644 --- a/TAO/tao/Profile.cpp +++ b/TAO/tao/Profile.cpp @@ -636,6 +636,12 @@ TAO_Profile::supports_multicast (void) const return 0; } +bool +TAO_Profile::supports_non_blocking_oneways (void) const +{ + return !(this->version_.major == 1 && this->version_.minor == 0); +} + void TAO_Profile::addressing_mode (CORBA::Short addr ACE_ENV_ARG_DECL) diff --git a/TAO/tao/Profile.h b/TAO/tao/Profile.h index 455101ebb2c..4a2e5227c05 100644 --- a/TAO/tao/Profile.h +++ b/TAO/tao/Profile.h @@ -150,6 +150,9 @@ public: /// Returns true if this profile can specify multicast endpoints. virtual int supports_multicast (void) const; + /// Returns true if this profile supports non blocking oneways + virtual bool supports_non_blocking_oneways (void) const; + /** * Set the addressing mode if a remote servant replies with * an addressing mode exception. If this profile doesn't diff --git a/TAO/tao/Profile_Transport_Resolver.cpp b/TAO/tao/Profile_Transport_Resolver.cpp index 8e79ec8879d..fa0046eaa7c 100644 --- a/TAO/tao/Profile_Transport_Resolver.cpp +++ b/TAO/tao/Profile_Transport_Resolver.cpp @@ -1,4 +1,5 @@ // $Id$ + #include "Profile_Transport_Resolver.h" #include "Profile.h" #include "Transport.h" @@ -77,6 +78,7 @@ namespace TAO ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; + // Select the endpoint es->select_endpoint (this, max_time_val ACE_ENV_ARG_PARAMETER); @@ -108,6 +110,7 @@ namespace TAO } } + bool Profile_Transport_Resolver::try_connect ( TAO_Transport_Descriptor_Interface *desc, @@ -148,6 +151,7 @@ namespace TAO max_wait_time = max_time_value; } + // Obtain a connection. this->transport_ = conn_reg->get_connector (desc->endpoint ()->tag ())->connect ( diff --git a/TAO/tao/Profile_Transport_Resolver.h b/TAO/tao/Profile_Transport_Resolver.h index 482ce0a9f18..72a30a6952d 100644 --- a/TAO/tao/Profile_Transport_Resolver.h +++ b/TAO/tao/Profile_Transport_Resolver.h @@ -58,13 +58,22 @@ namespace TAO * object. This class helps in choosing the right profile, and pick * a transport from cache (or create a new transport if needed) that * represents the profile. - * */ class TAO_Export Profile_Transport_Resolver { public: - Profile_Transport_Resolver (CORBA::Object *ep, - TAO_Stub *); + /// Constructor + /** + * With @a block we tell whether this resolved should always deliver + * a connection by blocking or unblock before the connection is + * completely established. Please note that this has *nothing* to + * do with the synchronous or asynch connect strategy used for + * making connections. This is a local flag used by the clients of + * this to dictate some local behavior. + */ + Profile_Transport_Resolver (CORBA::Object *p, + TAO_Stub *stub, + bool block = true); ~Profile_Transport_Resolver (void); @@ -79,11 +88,11 @@ namespace TAO ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException)); - //@{ /** * Accessors and mutators for this class. The following methods - * are used by the clients of this class to access. + * are used by the clients of this class to access strategies and + * other internal workings. */ /// Mutator for profile. @@ -100,6 +109,10 @@ namespace TAO /// Accessor for the transport reserved for this invocation. TAO_Transport *transport (void) const; + + /// Accessor to indicate whether we should deliver a connection + /// blocking for completed connections + bool blocked (void) const; //@} /// Signal to let the resolver know that the transport has been @@ -163,6 +176,9 @@ namespace TAO * avoid. */ CORBA::PolicyList *inconsistent_policies_; + + /// Should we block while trying to make a connection + const bool blocked_; }; } // TAO namespace end diff --git a/TAO/tao/Profile_Transport_Resolver.inl b/TAO/tao/Profile_Transport_Resolver.inl index 6f660433689..69b8c78e9e7 100644 --- a/TAO/tao/Profile_Transport_Resolver.inl +++ b/TAO/tao/Profile_Transport_Resolver.inl @@ -5,13 +5,15 @@ namespace TAO ACE_INLINE Profile_Transport_Resolver:: Profile_Transport_Resolver (CORBA::Object *p, - TAO_Stub *stub) + TAO_Stub *stub, + bool block) : obj_ (p) , stub_ (stub) , transport_ (0) , profile_ (0) , is_released_ (false) , inconsistent_policies_ (0) + , blocked_ (block) { } @@ -39,6 +41,12 @@ namespace TAO return this->transport_; } + ACE_INLINE bool + Profile_Transport_Resolver::blocked (void) const + { + return this->blocked_; + } + ACE_INLINE void Profile_Transport_Resolver::transport_released (void) const { diff --git a/TAO/tao/Reactive_Connect_Strategy.cpp b/TAO/tao/Reactive_Connect_Strategy.cpp index 2d0fa7d7da9..74bddc34ee6 100644 --- a/TAO/tao/Reactive_Connect_Strategy.cpp +++ b/TAO/tao/Reactive_Connect_Strategy.cpp @@ -2,6 +2,7 @@ #include "Connection_Handler.h" #include "ORB_Core.h" #include "debug.h" +#include "Transport.h" #include "ace/Synch_Options.h" @@ -87,3 +88,15 @@ TAO_Reactive_Connect_Strategy::wait (TAO_Connection_Handler *ch, return result; } + + +int +TAO_Reactive_Connect_Strategy::wait (TAO_Transport *t, + ACE_Time_Value *val) +{ + if (t == 0) + return -1; + + return this->wait (t->connection_handler (), + val); +} diff --git a/TAO/tao/Reactive_Connect_Strategy.h b/TAO/tao/Reactive_Connect_Strategy.h index fc377a5d596..5550e00380d 100644 --- a/TAO/tao/Reactive_Connect_Strategy.h +++ b/TAO/tao/Reactive_Connect_Strategy.h @@ -49,7 +49,11 @@ public: ACE_Synch_Options &opt); virtual int wait (TAO_Connection_Handler *ch, - ACE_Time_Value *val); + ACE_Time_Value *val); + + + virtual int wait (TAO_Transport *t, + ACE_Time_Value *val); }; diff --git a/TAO/tao/Synch_Invocation.cpp b/TAO/tao/Synch_Invocation.cpp index ad0a2947525..0b9721af406 100644 --- a/TAO/tao/Synch_Invocation.cpp +++ b/TAO/tao/Synch_Invocation.cpp @@ -8,7 +8,6 @@ #include "Stub.h" #include "Bind_Dispatcher_Guard.h" #include "operation_details.h" -#include "Pluggable_Messaging.h" #include "Wait_Strategy.h" #include "debug.h" #include "ORB_Constants.h" @@ -88,7 +87,7 @@ namespace TAO #endif /*TAO_HAS_INTERCEPTORS */ TAO_OutputCDR &cdr = - this->resolver_.transport ()->messaging_object ()->out_stream (); + this->resolver_.transport ()->out_stream (); // We have started the interception flow. We need to call the // ending interception flow if things go wrong. The purpose of the @@ -291,7 +290,7 @@ namespace TAO if (TAO_debug_level > 3) { ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply , " + "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, " "recovering after an error \n")); } @@ -629,7 +628,7 @@ namespace TAO if (TAO_debug_level > 4) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Synch_Twoway_Invocation::" - "handle_system_exception about to raise\n")); + "handle_system_exception, about to raise\n")); mon.set_status (TAO_INVOKE_SYSTEM_EXCEPTION); @@ -659,17 +658,22 @@ namespace TAO const CORBA::Octet response_flags = this->details_.response_flags (); + Invocation_Status s = TAO_INVOKE_FAILURE; + if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_SERVER) || response_flags == CORBA::Octet (Messaging::SYNC_WITH_TARGET)) - return Synch_Twoway_Invocation::remote_twoway (max_wait_time - ACE_ENV_ARG_PARAMETER); + { + s = Synch_Twoway_Invocation::remote_twoway (max_wait_time + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); + + return s; + } TAO_Target_Specification tspec; this->init_target_spec (tspec ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); - Invocation_Status s = TAO_INVOKE_FAILURE; - #if TAO_HAS_INTERCEPTORS == 1 s = this->send_request_interception (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); @@ -678,8 +682,11 @@ namespace TAO return s; #endif /*TAO_HAS_INTERCEPTORS */ + TAO_Transport* transport = + this->resolver_.transport (); + TAO_OutputCDR &cdr = - this->resolver_.transport ()->messaging_object ()->out_stream (); + transport->out_stream (); ACE_TRY { @@ -694,21 +701,24 @@ namespace TAO countdown.update (); - if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)) + if (transport->is_connected()) { + // We have a connected transport so we can send the message s = this->send_message (cdr, - TAO_Transport::TAO_TWOWAY_REQUEST, + TAO_Transport::TAO_ONEWAY_REQUEST, max_wait_time ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } else { - s = this->send_message (cdr, - TAO_Transport::TAO_ONEWAY_REQUEST, - max_wait_time - ACE_ENV_ARG_PARAMETER); - ACE_TRY_CHECK; + if (TAO_debug_level > 4) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - Synch_Oneway_Invocation::" + "remote_oneway, queueing message\n")); + + if (transport->format_queue_message (cdr) != 0) + s = TAO_INVOKE_FAILURE; } #if TAO_HAS_INTERCEPTORS == 1 diff --git a/TAO/tao/TAO_Server_Request.cpp b/TAO/tao/TAO_Server_Request.cpp index a9820608a3b..a6ca1816226 100644 --- a/TAO/tao/TAO_Server_Request.cpp +++ b/TAO/tao/TAO_Server_Request.cpp @@ -174,8 +174,9 @@ TAO_ServerRequest::init_reply (void) if ((*this->outgoing_ << object_ptr) == 0) { ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - ServerRequest::init_reply, ") ACE_TEXT ("TAO_GIOP_ServerRequest::marshal - ") - ACE_TEXT ("encoding forwarded objref failed\n"))); + ACE_TEXT ("marshal encoding forwarded objref failed\n"))); } } this->transport_->assign_translators (0,this->outgoing_); @@ -219,8 +220,8 @@ TAO_ServerRequest::send_no_exception_reply (void) // is required. ACE_ERROR (( LM_ERROR, - ACE_TEXT ("TAO: (%P|%t) %p: cannot send NO_EXCEPTION reply\n"), - ACE_TEXT ("TAO_GIOP_ServerRequest::send_no_exception_reply") + ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_no_exception_reply, ") + ACE_TEXT ("cannot send NO_EXCEPTION reply\n") )); } } @@ -239,9 +240,8 @@ TAO_ServerRequest::tao_send_reply (void) // No exception but some kind of error, yet a response // is required. ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO: (%P|%t) %p: cannot send reply\n"), - ACE_TEXT ("TAO_ServerRequest::tao_send_reply"))); - + ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply, ") + ACE_TEXT ("cannot send reply\n"))); } } } @@ -300,7 +300,7 @@ TAO_ServerRequest::tao_send_reply_exception (CORBA::Exception &ex) ex) == -1) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO: (%P|%t|%N|%l): ") + ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply_exception, ") ACE_TEXT ("could not make exception reply\n"))); } @@ -311,7 +311,7 @@ TAO_ServerRequest::tao_send_reply_exception (CORBA::Exception &ex) TAO_Transport::TAO_REPLY) == -1) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO: (%P|%t|%N|%l): ") + ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply_exception, ") ACE_TEXT ("could not send exception reply\n"))); } } @@ -324,7 +324,8 @@ TAO_ServerRequest::tao_send_reply_exception (CORBA::Exception &ex) // down, since it really isn't the client's fault. ACE_ERROR ((LM_ERROR, - ACE_TEXT ("(%P|%t) exception thrown ") + ACE_TEXT ("TAO (%P|%t) - ServerRequest::tao_send_reply_exception, ") + ACE_TEXT ("exception thrown ") ACE_TEXT ("but client is not waiting a response\n"))); } } @@ -376,7 +377,7 @@ TAO_ServerRequest::send_cached_reply (CORBA::OctetSeq &s) reply_params) == -1) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO: (%P|%t|%N|%l): ") + ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_cached_reply, ") ACE_TEXT ("could not make cached reply\n"))); } @@ -388,7 +389,7 @@ TAO_ServerRequest::send_cached_reply (CORBA::OctetSeq &s) if (!this->outgoing_->good_bit ()) ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO: (%P|%t|%N|%l): ") + ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_cached_reply, ") ACE_TEXT ("could not marshal reply\n"))); // Send the message @@ -397,7 +398,7 @@ TAO_ServerRequest::send_cached_reply (CORBA::OctetSeq &s) TAO_Transport::TAO_REPLY) == -1) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO: (%P|%t|%N|%l): ") + ACE_TEXT ("TAO (%P|%t) - ServerRequest::send_cached_reply, ") ACE_TEXT ("could not send cached reply\n"))); } } diff --git a/TAO/tao/Thread_Per_Connection_Handler.cpp b/TAO/tao/Thread_Per_Connection_Handler.cpp index f51f17c51e8..5dbb9fcabb3 100644 --- a/TAO/tao/Thread_Per_Connection_Handler.cpp +++ b/TAO/tao/Thread_Per_Connection_Handler.cpp @@ -40,7 +40,7 @@ TAO_Thread_Per_Connection_Handler::activate (long flags, if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - IIOP_Connection_Handler::") + ACE_TEXT ("TAO (%P|%t) - Thread_Per_Connection_Handler::") ACE_TEXT ("activate %d threads, flags = %d\n"), n_threads, flags)); diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp index ba4c262a11f..330ce4190ca 100644 --- a/TAO/tao/Transport.cpp +++ b/TAO/tao/Transport.cpp @@ -122,6 +122,7 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag, , purging_order_ (0) , recv_buffer_size_ (0) , sent_byte_count_ (0) + , is_connected_ (false) , char_translator_ (0) , wchar_translator_ (0) , tcs_set_ (0) @@ -145,8 +146,18 @@ TAO_Transport::~TAO_Transport (void) delete this->handler_lock_; - // By the time the destructor is reached all the connection stuff - // *must* have been cleaned up + if (!this->is_connected_) + { + // When we have a not connected transport we could have buffered + // messages on this transport which we have to cleanup now. + this->cleanup_queue_i(); + + // Cleanup our cache entry + this->purge_entry(); + } + + // By the time the destructor is reached here all the connection stuff + // *must* have been cleaned up. ACE_ASSERT (this->head_ == 0); ACE_ASSERT (this->cache_map_entry_ == 0); } @@ -194,6 +205,13 @@ TAO_Transport::register_handler (void) ACE_Reactor *r = this->orb_core_->reactor (); + // @@note: This should be okay since the register handler call will + // not make a nested call into the transport. + ACE_GUARD_RETURN (ACE_Lock, + ace_mon, + *this->handler_lock_, + false); + if (r == this->event_handler_i ()->reactor ()) { return 0; @@ -269,21 +287,22 @@ TAO_Transport::generate_request_header ( } /// @todo Ideally the following should be inline. +/// @todo purge_entry has a return value, use it int TAO_Transport::recache_transport (TAO_Transport_Descriptor_Interface *desc) { // First purge our entry - this->transport_cache_manager ().purge_entry (this->cache_map_entry_); + this->purge_entry (); // Then add ourselves to the cache return this->transport_cache_manager ().cache_transport (desc, this); } -void +int TAO_Transport::purge_entry (void) { - this->transport_cache_manager ().purge_entry (this->cache_map_entry_); + return this->transport_cache_manager ().purge_entry (this->cache_map_entry_); } int @@ -339,6 +358,15 @@ TAO_Transport::handle_output (void) } int +TAO_Transport::format_queue_message (TAO_OutputCDR &stream) +{ + if (this->messaging_object ()->format_message (stream) != 0) + return -1; + + return this->queue_message_i (stream.begin()); +} + +int TAO_Transport::send_message_block_chain (const ACE_Message_Block *mb, size_t &bytes_transferred, ACE_Time_Value *max_wait_time) @@ -845,6 +873,32 @@ TAO_Transport::drain_queue_i (void) } void +TAO_Transport::cleanup_queue_i () +{ + if (TAO_debug_level > 4) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - Transport[%d]::cleanup_queue_i, " + "cleaning up complete queue\n", + this->id ())); + } + + // Cleanup all messages + while (this->head_ != 0) + { + TAO_Queued_Message *i = this->head_; + + // @@ This is a good point to insert a flag to indicate that a + // CloseConnection message was successfully received. + i->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); + + i->remove_from_list (this->head_, this->tail_); + + i->destroy (); + } +} + +void TAO_Transport::cleanup_queue (size_t byte_count) { while (this->head_ != 0 && byte_count > 0) @@ -957,18 +1011,7 @@ TAO_Transport::send_connection_closed_notifications (void) void TAO_Transport::send_connection_closed_notifications_i (void) { - while (this->head_ != 0) - { - TAO_Queued_Message *i = this->head_; - - // @@ This is a good point to insert a flag to indicate that a - // CloseConnection message was successfully received. - i->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); - - i->remove_from_list (this->head_, this->tail_); - - i->destroy (); - } + this->cleanup_queue_i (); this->messaging_object ()->reset (); } @@ -979,6 +1022,9 @@ TAO_Transport::send_message_shared_i (TAO_Stub *stub, const ACE_Message_Block *message_block, ACE_Time_Value *max_wait_time) { + +// @todo Bala mentioned that this has to go out here +// { if (message_semantics == TAO_Transport::TAO_TWOWAY_REQUEST) { return this->send_synchronous_message_i (message_block, @@ -989,6 +1035,7 @@ TAO_Transport::send_message_shared_i (TAO_Stub *stub, return this->send_reply_message_i (message_block, max_wait_time); } + // } // Let's figure out if the message should be queued without trying // to send first: @@ -1043,7 +1090,7 @@ TAO_Transport::send_message_shared_i (TAO_Stub *stub, { if (TAO_debug_level > 0) { - ACE_DEBUG ((LM_DEBUG, + ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - Transport[%d]::send_message_shared_i, " "fatal error in " "send_message_block_chain_i - %m\n", @@ -1095,13 +1142,15 @@ TAO_Transport::send_message_shared_i (TAO_Stub *stub, this->id ())); } - TAO_Queued_Message *queued_message = 0; - ACE_NEW_RETURN (queued_message, - TAO_Asynch_Queued_Message (message_block, - 0, - 1), - -1); - queued_message->push_back (this->head_, this->tail_); + if (this->queue_message_i(message_block) == -1) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - Transport[%d]::send_message_shared_i, " + "cannot queue message for " + " - %m\n", + this->id ())); + return -1; + } // ... if the queue is full we need to activate the output on the // queue ... @@ -1131,6 +1180,20 @@ TAO_Transport::send_message_shared_i (TAO_Stub *stub, return 0; } +int +TAO_Transport::queue_message_i(const ACE_Message_Block *message_block) +{ + TAO_Queued_Message *queued_message = 0; + ACE_NEW_RETURN (queued_message, + TAO_Asynch_Queued_Message (message_block, + 0, + 1), + -1); + queued_message->push_back (this->head_, this->tail_); + + return 0; +} + /* * * All the methods relevant to the incoming data path of the ORB are @@ -2057,6 +2120,64 @@ TAO_Transport::remove_reference (void) return this->event_handler_i ()->remove_reference (); } +TAO_OutputCDR & +TAO_Transport::out_stream (void) +{ + return this->messaging_object ()->out_stream (); +} + +bool +TAO_Transport::post_open (size_t id) +{ + this->id_ = id; + + { + ACE_GUARD_RETURN (ACE_Lock, + ace_mon, + *this->handler_lock_, + false); + + this->is_connected_ = true; + } + + // When we have data in our outgoing queue schedule ourselves + // for output + if (this->queue_is_empty_i ()) + return true; + + // If the wait strategy wants us to be registered with the reactor + // then we do so. If registeration is required and it succeeds, + // #REFCOUNT# becomes two. + if (this->wait_strategy ()->register_handler () == 0) + { + TAO_Flushing_Strategy *flushing_strategy = + this->orb_core ()->flushing_strategy (); + (void) flushing_strategy->schedule_output (this); + } + else + { + // Registration failures. + + // Purge from the connection cache, if we are not in the cache, this + // just does nothing. + (void) this->purge_entry (); + + // Close the handler. + (void) this->close_connection (); + + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - Transport[%d]::post_connect , " + "could not register the transport " + "in the reactor.\n", + this->id ())); + + return false; + } + + return true; +} + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Reverse_Lock<ACE_Lock>; diff --git a/TAO/tao/Transport.h b/TAO/tao/Transport.h index b15c8bf9340..63011bbeb23 100644 --- a/TAO/tao/Transport.h +++ b/TAO/tao/Transport.h @@ -205,7 +205,7 @@ struct iovec; * * <B>See Also:</B> * - * http://deuce.doc.wustl.edu/cvsweb/ace-latest.cgi/ACE_wrappers/TAO/docs/pluggable_protocols/index.html + * http://cvs.doc.wustl.edu/ace-latest.cgi/ACE_wrappers/TAO/docs/pluggable_protocols/index.html * */ class TAO_Export TAO_Transport @@ -297,13 +297,6 @@ public: */ void provide_handler (TAO_Connection_Handler_Set &handlers); - - /// Remove all messages from the outgoing queue. - /** - * @todo shouldn't this be automated? - */ - // void dequeue_all (void); - /// Register the handler with the reactor. /** * Register the handler with the reactor. This method is used by the @@ -448,9 +441,23 @@ public: * adapter class (TAO_Transport_Event_Handler or something), this * will reduce footprint and simplify the process of implementing a * pluggable protocol. + * + * @todo This method has to be renamed to event_handler() */ virtual ACE_Event_Handler * event_handler_i (void) = 0; + /// Is this transport really connected + bool is_connected (void) const; + + /// Perform all the actions when this transport get opened + bool post_open (size_t id); + + /// Get the connection handler for this transport + TAO_Connection_Handler * connection_handler (void); + + /// Accessor for the output CDR stream + TAO_OutputCDR &out_stream (void); + protected: virtual TAO_Connection_Handler * connection_handler_i (void) = 0; @@ -634,7 +641,12 @@ protected: const ACE_Message_Block *message_block, ACE_Time_Value *max_wait_time); + /// Queue a message for @a message_block + int queue_message_i (const ACE_Message_Block *message_block); + public: + /// Format and queue a message for @a stream + int format_queue_message (TAO_OutputCDR &stream); /// Send a message block chain, int send_message_block_chain (const ACE_Message_Block *message_block, @@ -646,7 +658,7 @@ public: size_t &bytes_transferred, ACE_Time_Value *max_wait_time); /// Cache management - void purge_entry (void); + int purge_entry (void); /// Cache management int make_idle (void); @@ -766,8 +778,8 @@ private: */ void cleanup_queue (size_t byte_count); - /// Copy the contents of a message block into a Queued_Message - /// TAO_Queued_Message *copy_message_block (const ACE_Message_Block *mb); + /// Cleanup the complete queue + void cleanup_queue_i (); /// Check if the buffering constraints have been reached int check_buffering_constraints_i (TAO_Stub *stub, int &must_flush); @@ -884,7 +896,7 @@ protected: * a null lock for single-threaded systems, and a real lock for * multi-threaded systems. */ - ACE_Lock *handler_lock_; + mutable ACE_Lock *handler_lock_; /// A unique identifier for the transport. /** @@ -905,6 +917,11 @@ protected: /// Number of bytes sent. size_t sent_byte_count_; + /// Is this transport really connected or not. In case of oneways with + /// SYNC_NONE Policy we don't wait until the connection is ready and we + /// buffer the requests in this transport until the connection is ready + bool is_connected_; + private: /// @@Phil, I think it would be nice if we could think of a way to @@ -938,7 +955,7 @@ private: /** * @class TAO_Transport_Refcount_Guard * - * @brief Helper class that increments the refount on construction + * @brief Helper class that increments the refcount on construction * and decrements the refcount on destruction. */ class TAO_Export TAO_Transport_Refcount_Guard diff --git a/TAO/tao/Transport.inl b/TAO/tao/Transport.inl index ab9770b43f4..68943732205 100644 --- a/TAO/tao/Transport.inl +++ b/TAO/tao/Transport.inl @@ -145,6 +145,23 @@ TAO_Transport::first_request_sent (void) this->first_request_ = 0; } +ACE_INLINE bool +TAO_Transport::is_connected (void) const +{ + ACE_GUARD_RETURN (ACE_Lock, + ace_mon, + *this->handler_lock_, + false); + + return this->is_connected_; +} + +ACE_INLINE TAO_Connection_Handler * +TAO_Transport::connection_handler (void) +{ + return this->connection_handler_i(); +} + /*****************************************************/ ACE_INLINE diff --git a/TAO/tao/Transport_Connector.cpp b/TAO/tao/Transport_Connector.cpp index 00783bcd224..b13f0af134e 100644 --- a/TAO/tao/Transport_Connector.cpp +++ b/TAO/tao/Transport_Connector.cpp @@ -8,6 +8,9 @@ #include "debug.h" #include "Connect_Strategy.h" #include "Client_Strategy_Factory.h" +#include "Connection_Handler.h" +#include "Profile_Transport_Resolver.h" +#include "Wait_Strategy.h" #include "ace/OS_NS_string.h" @@ -216,44 +219,161 @@ TAO_Connector::connect (TAO::Profile_Transport_Resolver *r, ACE_Time_Value *timeout ACE_ENV_ARG_DECL_NOT_USED) { - if ((this->set_validate_endpoint (desc->endpoint ()) == -1) || desc == 0) - { - return 0; - } + if (desc == 0 || + (this->set_validate_endpoint (desc->endpoint ()) == -1)) + return 0; TAO_Transport *base_transport = 0; + TAO_Transport_Cache_Manager &tcm = + this->orb_core ()->lane_resources ().transport_cache (); + // Check the Cache first for connections // If transport found, reference count is incremented on assignment // @@todo: We need to send the timeout value to the cache registry // too. That should be the next step! - if (this->orb_core ()->lane_resources ().transport_cache ().find_transport ( - desc, - base_transport) == 0) + if (tcm.find_transport (desc, + base_transport) != 0) + { + // @@TODO: This is not the right place for this! + // Purge connections (if necessary) + tcm.purge (); + + return this->make_connection (r, + *desc, + timeout); + } + + if (TAO_debug_level > 4) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - Transport_Connector::connect, " + "got an existing %s Transport[%d]\n", + base_transport->is_connected () ? "connected" : "unconnected", + base_transport->id ())); + + // If connected return.. + if (base_transport->is_connected ()) + return base_transport; + + if (!this->wait_for_connection_completion (r, + base_transport, + timeout)) { if (TAO_debug_level > 2) + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - Transport_Connector::" + "connect, " + "wait for completion failed\n")); + return 0; + } + + if (base_transport->is_connected () && + base_transport->wait_strategy ()->register_handler () != 0) + { + // Registration failures. + + // Purge from the connection cache, if we are not in the cache, this + // just does nothing. + (void) base_transport->purge_entry (); + + // Close the handler. + (void) base_transport->close_connection (); + + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - Transport_Connector [%d]::connect, " + "could not register the transport " + "in the reactor.\n", + base_transport->id ())); + + return 0; + } + + return base_transport; +} + +bool +TAO_Connector::wait_for_connection_completion ( + TAO::Profile_Transport_Resolver *r, + TAO_Transport *&transport, + ACE_Time_Value *timeout) +{ + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - Transport_Connector::wait_for_connection_completion, " + "going to wait for connection completion on transport" + "[%d]\n", + transport->id ())); + + // If we don't need to block for a transport just set the timeout to + // be zero. + ACE_Time_Value tmp_zero (ACE_Time_Value::zero); + if (!r->blocked ()) + { + timeout = &tmp_zero; + } + + // Wait until the connection is ready, when non-blocking we just do a wait + // with zero time + int result = + this->active_connect_strategy_->wait ( + transport, + timeout); + + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - Transport_Connector::wait_for_connection_completion, " + "transport [%d], wait done result = %d\n", + transport->id (), result)); + + // There are three possibilities when wait() returns: (a) + // connection succeeded; (b) connection failed; (c) wait() + // failed because of some other error. It is easy to deal with + // (a) and (b). (c) is tricky since the connection is still + // pending and may get completed by some other thread. The + // following method deals with (c). + + if (result == -1) + { + if (!r->blocked () && errno == ETIME) { - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Transport_Connector::connect, " - "got an existing Transport[%d]\n", - base_transport->id ())); + // If we did a non blocking connect, just ignore + // any timeout errors + result = 0; + } + else + { + // When we need to get a connected transport + result = + this->check_connection_closure ( + transport->connection_handler ()); } - // No need to _duplicate since things are taken care within the - // cache manager. - return base_transport; + // In case of errors. + if (result == -1) + { + // Report that making the connection failed, don't print errno + // because we touched the reactor and errno could be changed + if (TAO_debug_level > 2) + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - Transport_Connector::" + "wait_for_connection_completion, " + "transport [%d], wait for completion failed\n", + transport->id())); + + // Set transport to zero, it is not usable + transport = 0; + + return false; + } } - // @@TODO: This is not the right place for this! - // Purge connections (if necessary) - this->orb_core_->lane_resources ().transport_cache ().purge (); - - return this->make_connection (r, - *desc, - timeout); + // Connection not ready yet but we can use this transport, if + // we need a connected one we will block later to make sure + // it is connected + return true; } - int TAO_Connector::create_connect_strategy (void) { @@ -271,3 +391,57 @@ TAO_Connector::create_connect_strategy (void) return 0; } + +int +TAO_Connector::check_connection_closure ( + TAO_Connection_Handler *connection_handler) +{ + int result = -1; + + // Check if the handler has been closed. + int closed = + connection_handler->is_closed (); + + // In case of failures and close() has not be called. + if (!closed) + { + // First, cancel from connector. + if (this->cancel_svc_handler (connection_handler) == -1) + return -1; + + // Double check to make sure the handler has not been closed + // yet. This double check is required to ensure that the + // connection handler was not closed yet by some other + // thread since it was still registered with the connector. + // Once connector.cancel() has been processed, we are + // assured that the connector will no longer open/close this + // handler. + closed = connection_handler->is_closed (); + + // If closed, there is nothing to do here. If not closed, + // it was either opened or is still pending. + if (!closed) + { + // Check if the handler has been opened. + const int open = connection_handler->is_open (); + + // Some other thread was able to open the handler even + // though wait failed for this thread. + if (open) + { + // Set the result to 0, we have an open connection + result = 0; + } + else + { + // Assert that it is still connecting. + ACE_ASSERT (connection_handler->is_connecting ()); + + // Force close the handler now. + connection_handler->close_handler (); + } + } + } + + return result; +} diff --git a/TAO/tao/Transport_Connector.h b/TAO/tao/Transport_Connector.h index b142cf90b9e..73347185874 100644 --- a/TAO/tao/Transport_Connector.h +++ b/TAO/tao/Transport_Connector.h @@ -35,6 +35,7 @@ class TAO_MProfile; class TAO_ORB_Core; class TAO_Connect_Strategy; class TAO_Transport; +class TAO_Connection_Handler; namespace TAO { @@ -58,10 +59,10 @@ class TAO_Export TAO_Connector { public: - /// default constructor. + /// Default constructor. TAO_Connector (CORBA::ULong tag); - /// the destructor. + /// The destructor. virtual ~TAO_Connector (void); /** @@ -75,12 +76,14 @@ public: /// Parse a string containing a URL style IOR and return an /// MProfile. - int make_mprofile (const char *ior, - TAO_MProfile &mprofile - ACE_ENV_ARG_DECL); + int make_mprofile ( + const char *ior, + TAO_MProfile &mprofile + ACE_ENV_ARG_DECL); /// Initialize object and register with reactor. - virtual int open (TAO_ORB_Core *orb_core) = 0; + virtual int open ( + TAO_ORB_Core *orb_core) = 0; /// Shutdown Connector bridge and concrete Connector. virtual int close (void) = 0; @@ -90,18 +93,21 @@ public: * connect () method so it can be called from the invocation code * independent of the actual transport protocol in use. */ - virtual TAO_Transport* connect (TAO::Profile_Transport_Resolver *r, - TAO_Transport_Descriptor_Interface *desc, - ACE_Time_Value *timeout - ACE_ENV_ARG_DECL); + virtual TAO_Transport* connect ( + TAO::Profile_Transport_Resolver *r, + TAO_Transport_Descriptor_Interface *desc, + ACE_Time_Value *timeout + ACE_ENV_ARG_DECL); /// Create a profile for this protocol and initialize it based on the /// encapsulation in @a cdr - virtual TAO_Profile *create_profile (TAO_InputCDR& cdr) = 0; + virtual TAO_Profile *create_profile ( + TAO_InputCDR& cdr) = 0; /// Check that the prefix of the provided endpoint is valid for use /// with a given pluggable protocol. - virtual int check_prefix (const char *endpoint) = 0; + virtual int check_prefix ( + const char *endpoint) = 0; /// Return the object key delimiter to use or expect. virtual char object_key_delimiter (void) const = 0; @@ -115,9 +121,35 @@ protected: /// remote *_Addr's which have not been done during IOR decode. virtual int set_validate_endpoint (TAO_Endpoint *endpoint) = 0; - virtual TAO_Transport* make_connection (TAO::Profile_Transport_Resolver *r, - TAO_Transport_Descriptor_Interface &desc, - ACE_Time_Value *timeout) = 0; + /// Make a connection + virtual TAO_Transport* make_connection ( + TAO::Profile_Transport_Resolver *r, + TAO_Transport_Descriptor_Interface &desc, + ACE_Time_Value *timeout) = 0; + + /// Cancel the passed cvs handler from the connector + virtual int cancel_svc_handler ( + TAO_Connection_Handler *svc_handler) = 0; + + /// Check whether the connection is not closed + /** + * @retval 0 The connection happens to be not closed, but is now open + * because an other thread managed to open the handler + * @retval -1 The connection is closed + */ + virtual int check_connection_closure ( + TAO_Connection_Handler *connection_handler); + + /** + * Wait for connection completion. We have a transport that is not + * connected yet, wait until it is connected. + * @retval true When we could use @a transport + * @return false When we can't use the @a transport + */ + virtual bool wait_for_connection_completion( + TAO::Profile_Transport_Resolver *r, + TAO_Transport *&transport, + ACE_Time_Value *timeout); /// Set the ORB Core pointer void orb_core (TAO_ORB_Core *orb_core); |