PageRenderTime 20ms CodeModel.GetById 9ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist130208/src/edu/vub/at/actors/net/comm/MasterConnectionThread.java

http://ambienttalk.googlecode.com/
Java | 132 lines | 63 code | 17 blank | 52 comment | 7 complexity | 2302a51cc30f094ff86ca0b8689adb22 MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * (c) Programming Technology Lab, 2006 - 2007
  4 * Authors: Tom Van Cutsem & Stijn Mostinckx
  5 * 
  6 * Permission is hereby granted, free of charge, to any person
  7 * obtaining a copy of this software and associated documentation
  8 * files (the "Software"), to deal in the Software without
  9 * restriction, including without limitation the rights to use,
 10 * copy, modify, merge, publish, distribute, sublicense, and/or
 11 * sell copies of the Software, and to permit persons to whom the
 12 * Software is furnished to do so, subject to the following
 13 * conditions:
 14 *
 15 * The above copyright notice and this permission notice shall be
 16 * included in all copies or substantial portions of the Software.
 17 *
 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 25 * OTHER DEALINGS IN THE SOFTWARE.
 26 */
 27package edu.vub.at.actors.net.comm;
 28
 29import edu.vub.at.util.logging.Logging;
 30
 31import java.io.DataInputStream;
 32import java.io.IOException;
 33import java.net.InetAddress;
 34import java.net.ServerSocket;
 35import java.net.Socket;
 36
 37/**
 38 * This thread is responsible for opening up a {@link ServerSocket} connection that listens
 39 * for incoming <i>slave</i> VMs. An incoming slave connection is registered with the
 40 * communication bus such that a {@link CommandProcessor} can further handle communication with the slave.
 41 * 
 42 * @author jededeck
 43 * @author tvcutsem
 44 */
 45public class MasterConnectionThread extends Thread {
 46	
 47	private volatile ServerSocket listenSocket_;
 48	
 49	private volatile boolean isActive_ = true;
 50	
 51	private final CommunicationBus communicationBus_;
 52	
 53	public MasterConnectionThread(CommunicationBus owner) {
 54		super("MasterConnectionThread for " + owner);
 55		communicationBus_ = owner;
 56	}
 57	
 58	/**
 59	 * Tries to create a local server socket connection to handle incoming
 60	 * slave connection requests.
 61	 * @param onNetwork needed for initializing the proper {@link Address} (tells me on which overlay network I should host)
 62	 * @return the {@link Address} encapsulating connection information to my socket
 63	 * @throws IOException if the local socket cannot be created. It is guaranteed that, if this
 64	 * exception is raised, this thread will <b>not</b> have started.
 65	 */
 66	public Address startServing(String onNetwork) throws IOException {
 67		InetAddress myAddress = InetAddress.getByName(InetAddress.getLocalHost().getHostAddress());
 68		listenSocket_ = new ServerSocket(0, 50, myAddress); // create a socket that will listen on any free port
 69		this.start();
 70		return new Address(myAddress, listenSocket_.getLocalPort(), onNetwork);
 71	}
 72
 73	public void stopServing() {
 74		isActive_ = false;
 75		// we need to force the master to quit, it might be blocked on the server socket
 76		try {
 77			if (listenSocket_ != null) {
 78				listenSocket_.close();
 79			}
 80		} catch (IOException e) { }
 81	}
 82
 83	/**
 84	 * Perpetually listen for incoming slave connections on my server socket.
 85	 * If a slave connects, read its address and register the incoming connection
 86	 * with the {@link CommunicationBus}.
 87	 */
 88	public void run() {
 89		try {
 90			Socket slave = null;
 91			while (isActive_) {
 92				
 93				try {
 94                    // accept an incoming slave connection
 95					slave = listenSocket_.accept();
 96					
 97					// read the slave's Address
 98					DataInputStream din = new DataInputStream(slave.getInputStream());
 99					int addressLength = din.readInt();
100					byte[] address = new byte[addressLength];
101					din.read(address);
102					
103					Address slaveAddress = Address.fromBytes(address);
104					
105					Logging.Network_LOG.debug("Detected incoming slave connection to " + slaveAddress);
106					
107					// only signal the connection of a slave if everything went OK so far
108					communicationBus_.addConnection(slaveAddress, slave);
109					
110					slave = null;
111				} catch(IOException e) {
112					Logging.Network_LOG.warn(toString() + ": error setting up connection with slave: " + e.getMessage());
113					// explicitly close the connection with the slave if one was created
114					try {
115						if (slave != null) { slave.close(); }
116					} catch (IOException ioe) { }
117				}
118			}
119		} finally {
120			if (listenSocket_ != null) {
121				try {
122					listenSocket_.close();
123				} catch (IOException e) { }
124			}
125			Logging.Network_LOG.debug(toString() + " shutting down.");
126		}
127	}
128	
129	public String toString() {
130		return super.getName();
131	}
132}