/interpreter/tags/at2-build270707/src/edu/vub/at/actors/net/comm/MasterConnectionThread.java
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}