/* $Id$ */ package ibis.ipl.impl; import ibis.io.DataInputStream; import ibis.io.SerializationFactory; import ibis.io.SerializationInput; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class represents the information about a particular sendport/receiveport * connection, on the receiver side. */ public class ReceivePortConnectionInfo { /** Debugging. */ protected static final Logger logger = LoggerFactory.getLogger("ibis.ipl.impl.ReceivePortConnectionInfo"); /** Identifies the sendport side of the connection. */ public final SendPortIdentifier origin; /** The serialization input stream of the connection. */ public SerializationInput in; /** The receiveport of the connection. */ public final ReceivePort port; /** The message that arrives on this connection. */ public ReadMessage message; /** * The underlying data stream for this connection. * The serialization stream lies on top of this. */ public DataInputStream dataIn; protected boolean closed = false; private long cnt = 0; /** * Constructs a new <code>ReceivePortConnectionInfo</code> with the * specified parameters. * @param origin identifies the sendport of this connection. * @param port the receiveport. * @param dataIn the inputstream on which a serialization input stream * can be built. * @exception IOException is thrown in case of trouble. */ public ReceivePortConnectionInfo(SendPortIdentifier origin, ReceivePort port, DataInputStream dataIn) throws IOException { this.origin = origin; this.port = port; this.dataIn = dataIn; // newStream(); // Moved to subtypes. Calling it here may cause deadlocks! port.addInfo(origin, this); } /** * Returns the number of bytes read from the data stream. * @return the number of bytes. */ public long bytesRead() { long rd = dataIn.bytesRead(); if (rd != 0) { dataIn.resetBytesRead(); port.addDataIn(rd); cnt += rd; } return cnt; } /** * This method must be called each time a connected sendport adds a new * connection. This new connection may either be to the current receiveport, * or to another one. In both cases, the serialization stream must be * recreated. * @exception IOException is thrown in case of trouble. */ public void newStream() throws IOException { bytesRead(); if (in != null) { in.close(); } in = SerializationFactory.createSerializationInput(port.serialization, dataIn); message = port.createReadMessage(in, this); } /** * This method closes the connection, as the result of the specified * exception. Implementations may need to redefine this method * @param e the exception. */ public void close(Throwable e) { try { in.close(); } catch(Throwable z) { // ignore } try { dataIn.close(); } catch(Throwable z) { // ignore } closed = true; in = null; if (logger.isDebugEnabled()) { logger.debug(port.name + ": connection with " + origin + " closing", e); } port.lostConnection(origin, e); } /** * This method gets called when the upcall for the message explicitly * called {@link ReadMessage#finish()}. * The default implementation just allocates a new message. */ protected void upcallCalledFinish() { message = port.createReadMessage(in, this); if (logger.isDebugEnabled()) { logger.debug(port.name + ": new connection handler for " + origin + ", finish called from upcall"); } } public String connectionType() { return "unknown"; } }