/*
* JacORB - a free Java ORB
*
* Copyright (C) 1997-2014 Gerald Brose / The JacORB Team.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.jacorb.orb.giop;
import org.jacorb.config.Configurable;
import org.jacorb.config.Configuration;
import org.jacorb.config.ConfigurationException;
/**
* @author Nicolas Noffke
*/
public class ClientGIOPConnection
extends GIOPConnection
implements Configurable
{
private boolean ignore_pending_messages_on_timeout = false;
private boolean disconnectAfterSystemException = false;
public ClientGIOPConnection( org.omg.ETF.Profile profile,
org.omg.ETF.Connection transport,
RequestListener request_listener,
ReplyListener reply_listener,
StatisticsProvider statistics_provider )
{
super( profile, transport, request_listener, reply_listener, statistics_provider );
}
public void configure(Configuration configuration)
throws ConfigurationException
{
super.configure(configuration);
ignore_pending_messages_on_timeout =
configuration.getAttributeAsBoolean("jacorb.connection.client.timeout_ignores_pending_messages", false);
disconnectAfterSystemException = configuration.getAttributeAsBoolean("jacorb.connection.client.disconnect_after_systemexception", true);
int max_request_write_time =
configuration.getAttributeAsInteger("jacorb.connection.request.write_timeout", 0);
init_write_monitor (max_request_write_time);
}
/**
* Client-side implementation what to do when a read on the
* underlying transport times out. If we have no pending messages
* for which we haven't received a reply yet, or if the property
* jacorb.connection.client.timeout_ignores_pending_messages is on,
* then we close the transport, but allow it to be reopened later.
* If we have pending message and are not allowed to ignore that,
* do nothing.
*/
protected void readTimedOut()
{
if (logger.isDebugEnabled())
{
logger.debug (this.toString() + ": readTimedOut()");
}
synchronized( pendingUndecidedSync )
{
if (ignore_pending_messages_on_timeout)
{
this.streamClosed();
}
else if (! hasPendingMessages())
{
closeAllowReopen();
}
else
{
if (logger.isDebugEnabled())
{
logger.debug
(
this.toString()
+ ": cannot close because there are pending messages"
);
}
}
}
}
/**
* Client-side implementation what to do when the underlying transport
* is closed during a read operation. We mark the transport as closed
* and allow it to be reopened later, when the client retries.
*/
protected void streamClosed()
{
if (logger.isDebugEnabled())
{
logger.debug (this.toString() + ": streamClosed()");
}
if (disconnectAfterSystemException)
{
close();
// Not calling listener::streamClosed as super.close calls
// listener::connectioClosed which calls listener::streamClosed
}
else
{
closeAllowReopen();
if( connection_listener != null )
{
connection_listener.streamClosed();
}
}
// If the transport and/or connection has been closed there is no point
// in keeping the fragments around.
fragments.clear();
fragmentsSize.clear();
}
/**
* Closes the underlying transport, but keeps this ClientGIOPConnection
* alive. If, subsequently, another request is sent to this connection,
* it will try to reopen the transport.
*/
public void closeAllowReopen()
{
if (logger.isDebugEnabled())
{
logger.debug (this.toString() + ": closeAllowReopen()");
}
try
{
//Solve potential deadlock caused by COMM_FAILURE.
//The strategy is getting write_lock before sync
//connect_sync when you need both of them.
getWriteLock(0);
synchronized (connect_sync)
{
transport.close();
// We expect that the same transport can be reconnected
// after a close, something that the ETF draft isn't
// particularly clear about.
}
}
finally
{
releaseWriteLock();
}
}
public String toString()
{
return "ClientGIOPConnection to "
+ profile.toString()
+ " (" + Integer.toHexString(this.hashCode()) + ")";
}
}// ClientGIOPConnection