/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. */
  27. package edu.vub.at.actors.net.comm;
  28. import edu.vub.at.util.logging.Logging;
  29. import java.io.DataInputStream;
  30. import java.io.IOException;
  31. import java.net.InetAddress;
  32. import java.net.ServerSocket;
  33. import java.net.Socket;
  34. /**
  35. * This thread is responsible for opening up a {@link ServerSocket} connection that listens
  36. * for incoming <i>slave</i> VMs. An incoming slave connection is registered with the
  37. * communication bus such that a {@link CommandProcessor} can further handle communication with the slave.
  38. *
  39. * @author jededeck
  40. * @author tvcutsem
  41. */
  42. public class MasterConnectionThread extends Thread {
  43. private volatile ServerSocket listenSocket_;
  44. private volatile boolean isActive_ = true;
  45. private final CommunicationBus communicationBus_;
  46. public MasterConnectionThread(CommunicationBus owner) {
  47. super("MasterConnectionThread for " + owner);
  48. communicationBus_ = owner;
  49. }
  50. /**
  51. * Tries to create a local server socket connection to handle incoming
  52. * slave connection requests.
  53. * @param onNetwork needed for initializing the proper {@link Address} (tells me on which overlay network I should host)
  54. * @return the {@link Address} encapsulating connection information to my socket
  55. * @throws IOException if the local socket cannot be created. It is guaranteed that, if this
  56. * exception is raised, this thread will <b>not</b> have started.
  57. */
  58. public Address startServing(String onNetwork) throws IOException {
  59. InetAddress myAddress = InetAddress.getByName(InetAddress.getLocalHost().getHostAddress());
  60. listenSocket_ = new ServerSocket(0, 50, myAddress); // create a socket that will listen on any free port
  61. this.start();
  62. return new Address(myAddress, listenSocket_.getLocalPort(), onNetwork);
  63. }
  64. public void stopServing() {
  65. isActive_ = false;
  66. // we need to force the master to quit, it might be blocked on the server socket
  67. try {
  68. if (listenSocket_ != null) {
  69. listenSocket_.close();
  70. }
  71. } catch (IOException e) { }
  72. }
  73. /**
  74. * Perpetually listen for incoming slave connections on my server socket.
  75. * If a slave connects, read its address and register the incoming connection
  76. * with the {@link CommunicationBus}.
  77. */
  78. public void run() {
  79. try {
  80. Socket slave = null;
  81. while (isActive_) {
  82. try {
  83. // accept an incoming slave connection
  84. slave = listenSocket_.accept();
  85. // read the slave's Address
  86. DataInputStream din = new DataInputStream(slave.getInputStream());
  87. int addressLength = din.readInt();
  88. byte[] address = new byte[addressLength];
  89. din.read(address);
  90. Address slaveAddress = Address.fromBytes(address);
  91. Logging.Network_LOG.debug("Detected incoming slave connection to " + slaveAddress);
  92. // only signal the connection of a slave if everything went OK so far
  93. communicationBus_.addConnection(slaveAddress, slave);
  94. slave = null;
  95. } catch(IOException e) {
  96. Logging.Network_LOG.warn(toString() + ": error setting up connection with slave: " + e.getMessage());
  97. // explicitly close the connection with the slave if one was created
  98. try {
  99. if (slave != null) { slave.close(); }
  100. } catch (IOException ioe) { }
  101. }
  102. }
  103. } finally {
  104. if (listenSocket_ != null) {
  105. try {
  106. listenSocket_.close();
  107. } catch (IOException e) { }
  108. }
  109. Logging.Network_LOG.debug(toString() + " shutting down.");
  110. }
  111. }
  112. public String toString() {
  113. return super.getName();
  114. }
  115. }