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

/interpreter/tags/at2-build060407/src/edu/vub/at/actors/net/comm/MulticastServerThread.java

http://ambienttalk.googlecode.com/
Java | 129 lines | 55 code | 17 blank | 57 comment | 5 complexity | 43ea3a47654747443f7497ad42fed9f1 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;
 28import java.io.*;
 29import java.net.*;
 30
 31import edu.vub.at.util.logging.Logging;
 32
 33/**
 34 * This thread is responsible for broadcasting a network message at a fixed
 35 * time rate.
 36 * The network message acts as a 'heartbeat' that signals to nearby virtual
 37 * machines that this VM is still alive.
 38 * 
 39 * The network packet that is broadcast (via UDP) contains the {@link Address}
 40 * by which this VM is known on the communication bus.
 41 * 
 42 * When two virtual machines 'hear' one another's heartbeat, and they were not
 43 * acquainted yet, one VM becomes 'master' and the other becomes 'slave':
 44 * the slave first connects to the master's socket, after which the master
 45 * connects to the slave. Determining who becomes master and who becomes
 46 * slave is done by comparing each other's address: the 'larger' address
 47 * becomes master.
 48 * 
 49 * @author jededeck
 50 * @author tvcutsem
 51 */
 52public class MulticastServerThread extends Thread {
 53	
 54	// this is the time interval in which a broadcast message is repeated
 55	public static final int REPEAT_TIME = 2000; // in milliseconds
 56	
 57	public static InetAddress MC_ADDR;
 58	
 59	static {
 60		try {
 61			MC_ADDR = InetAddress.getByName("224.0.0.1");
 62		} catch (UnknownHostException e) {
 63			e.printStackTrace();
 64		}
 65	}
 66	
 67	/** this is the port onto which broadcasts are posted */
 68	public static final int MC_PORT = 4446;
 69	
 70	/**
 71	 * marked volatile such that all threads see the actual value of the variable,
 72	 * rather than a cached copy (in a local register) which may contain a stale value
 73	 */
 74	private volatile boolean isActive_ = true;
 75	
 76	/** the socket over which to broadcast heartbeats */
 77	private MulticastSocket socket_;
 78	
 79	/** the address that is emitted by each broadcast */
 80	private final byte[] myAddress_;
 81
 82	public MulticastServerThread(Address myAddress) {
 83		super("MulticastServerThread for " + myAddress);
 84		myAddress_ = myAddress.serializedForm_;
 85	}
 86	
 87	public void stopBroadcasting() {
 88		isActive_ = false;
 89	}
 90	
 91	public void run() {
 92		try {
 93			while (isActive_) {
 94				try {
 95					// wait until sending another heartbeat
 96					try {
 97						sleep(REPEAT_TIME);
 98					} catch (InterruptedException e) { }
 99					
100					// if socket not yet initialized, create a new one
101					if (socket_ == null) {
102						socket_ = new MulticastSocket(MC_PORT);
103					}
104					
105					// send a UDP packet containing the address
106					DatagramPacket packet = new DatagramPacket(myAddress_, myAddress_.length, MC_ADDR, MC_PORT);
107					socket_.send(packet);
108				} catch (SocketException e) {
109					// considered fatal exception, reset socket
110					Logging.Network_LOG.error(toString() + ": socket creation error: " + e.getMessage());
111					socket_ = null;
112				} catch (IOException ioe) {
113					Logging.Network_LOG.error(toString() + ": error broadcasting key: " + ioe.getMessage());
114				}
115			}
116		} finally {
117			if (socket_ != null) {
118				socket_.close();
119			}
120			Logging.Network_LOG.debug(toString() + ": shutting down.");
121		}
122	}
123	
124	public String toString() {
125		return super.getName();
126	}
127	
128}
129