Package aleph.event

Source Code of aleph.event.SimpleEventManager$SignalMessage

/*
* Aleph Toolkit
*
* Copyright 1999, Brown University, Providence, RI.
*
*                         All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose other than its incorporation into a
* commercial product is hereby granted without fee, provided that the
* above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Brown University not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission.
*
* BROWN UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY
* PARTICULAR PURPOSE.  IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE FOR
* ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

package aleph.event;

import aleph.Aleph;
import aleph.Listener;
import aleph.PE;
import aleph.UniqueID;
import aleph.comm.CommunicationManager;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* The default Event Manager.
*
* @see aleph.Event
* @see aleph.event.EventManager
*
* @author Maurice Herlihy
* @date   March 1998
**/

public class SimpleEventManager extends EventManager {

  static final boolean DEBUG = false; // Cannon to the right of them ...

  // Server-side hash tables.
  // UniqueID -> vector of PEs to notify
  Hashtable notifyTable;
  // UniqueID -> history (vector of past signals)
  Hashtable historyTable;
  // The ubiquitous connection manager
  static CommunicationManager cManager = CommunicationManager.getManager();

  // Client-side hash tables
  // id -> Eventlistener
  Hashtable listenerTable;

  /**
   * Only constructor.
   **/
  SimpleEventManager() {
    notifyTable   = new Hashtable();
    historyTable  = new Hashtable();
    listenerTable = new Hashtable();
  }

  /**
   * Create a new event.
   **/
  public synchronized void newEvent(UniqueID id) {
    if (notifyTable.containsKey(id)) // sanity check
      Aleph.panic("Event " + id + " registered twice");
    historyTable.put(id, new Vector()); // no history so far
    notifyTable.put(id, new Vector()); // no one cares
  }

  /**
   * Register a listener for this event.  Panics if listener already set.
   **/
  public void setListener(UniqueID id, Listener e) {
    try {
      if (listenerTable.containsKey(id))
  Aleph.panic("Event " + id + " listener already set.");
      listenerTable.put(id, e);
      if (DEBUG)
        Aleph.debug("sending register message to " + id.getHome());
      cManager.send(id.getHome(), new RegisterMessage(id));
    } catch (Exception ex) {
      Aleph.panic(ex);
    }
  }

  /**
   * Reregister a listener for this event.
   **/
  public void resetListener(UniqueID id, Listener e) {
    try {
      if (listenerTable.containsKey(id)) { // no need to reregister
        listenerTable.put(id, e);
      } else {
        listenerTable.put(id, e);
        if (DEBUG)
          Aleph.debug("sending register message to " + id.getHome());
        cManager.send(id.getHome(), new RegisterMessage(id));
      }
    } catch (Exception ex) {
      Aleph.panic(ex);
    }
  }

  /**
   * Remove the listener for this event, if any.
   **/
  public void removeListener(UniqueID id) {
    try {
      listenerTable.remove(id);
    } catch (Exception ex) {
      Aleph.panic(ex);
    }
  }

  /**
   * Signal event to interested PEs.
   * @param id event's id
   * @param object what to deliver
   * @param flush discard earlier signals?
   **/
  public void signal(UniqueID id, Object object, boolean flush) {
    try {
      if (DEBUG)
        Aleph.debug("sending signal message to " + id.getHome());
      cManager.send(id.getHome(), new SignalMessage(id, object, flush));
    } catch (Exception e) {
      Aleph.panic(e);
    }
  }

  /**
   * Message: client PE -> home PE.  Signal this event.
   **/
  public static class SignalMessage
    extends aleph.Message implements Externalizable {

    private Object   object;
    private UniqueID id;
    private boolean  flush;

    public SignalMessage(UniqueID id, Object object, boolean flush) {
      this.object = object;
      this.id     = id;
      this.flush  = flush;
    }
    public SignalMessage() {}
    public void run() {
      SimpleEventManager manager = (SimpleEventManager) getManager();
      manager.signalHandler(id, object, flush);
    }
    /**
     * @see java.io.Externalizable
     **/
    public void writeExternal(ObjectOutput out) throws IOException {
      super.writeExternal(out);
      out.writeObject(object);
      out.writeObject(id);
      out.writeBoolean(flush);
    }
    /**
     * @see java.io.Externalizable
     **/
    public void readExternal(ObjectInput in)
      throws IOException, java.lang.ClassNotFoundException {
      super.readExternal(in);
      object = in.readObject();
      id     = (UniqueID) in.readObject();
      flush  = in.readBoolean();
    }

    public String toString() {
      return "SignalMessage[from: " + from +
  ",object:" + object +
  ", id: " + id +
  (flush? ", flush]" : "]");
    }
  }
  /**
   * Called by SignalMessage.
   **/
  void signalHandler(UniqueID id, Object object, boolean flush) {
    try {
      Vector notify = (Vector) notifyTable.get(id);
      Vector signals = new Vector();
      signals.addElement(object);
      NotifyMessage wakeup = new NotifyMessage(id, signals);
      for (Enumeration enm = notify.elements(); enm.hasMoreElements();) {
        if (DEBUG)
          Aleph.debug("sending notify message to " + id.getHome());
  cManager.send((PE) enm.nextElement(), wakeup);
      }
      Vector history = (Vector) historyTable.get(id);
      if (flush)    // add new history to table
  historyTable.put(id, signals);
      else                    // append latest object to history
  history.addElement(object);
    } catch (Exception e) {
      Aleph.panic(e);
    }
  }
     

  /**
   * Message: home PE -> client PE.  Event was signalled.
   **/
  public static class NotifyMessage
    extends aleph.Message implements Externalizable {
    private UniqueID id;
    private Vector   history;

    public NotifyMessage(UniqueID id, Vector history) {
      this.id = id;
      this.history = history;
    }
    public NotifyMessage() {}
    public void run() {
      SimpleEventManager manager = (SimpleEventManager) getManager();
      manager.notifyHandler(id, history);
    }

   /**
     * @see java.io.Externalizable
     **/
    public void writeExternal(ObjectOutput out) throws IOException {
      super.writeExternal(out);
      out.writeObject(id);
      out.writeObject(history);
    }
    /**
     * @see java.io.Externalizable
     **/
    public void readExternal(ObjectInput in)
      throws IOException, java.lang.ClassNotFoundException {
      super.readExternal(in);
      id      = (UniqueID) in.readObject();
      history = (Vector) in.readObject();
    }
    public String toString() {
      StringBuffer s = new StringBuffer("NotifyMessage[id: ");
      s.append(id.toString());
      s.append(", history: ");
      if (history == null)
        s.append("no");
      else
        s.append(Integer.toString(history.size()));
      s.append(" entries]");
      return s.toString();
    }
   
  }
  /**
   * Called by notifyMessage.
   **/
  void notifyHandler(UniqueID id, Vector history) {
    Listener listener = (Listener) listenerTable.get(id);
    for (Enumeration enm = history.elements(); enm.hasMoreElements();)
      listener.actionPerformed(enm.nextElement());
  }
    
  /**
   * Message: client PE -> home PE.  I'm interested in this event.
   **/
  public static class RegisterMessage
    extends aleph.Message implements Externalizable {
    private UniqueID id;
    private PE pe;

    public RegisterMessage(UniqueID id) {
      this.id = id;
      this.pe = PE.thisPE();
    }
    public RegisterMessage() {}
    public void run() {
      ((SimpleEventManager) getManager()).registerHandler(id, pe);
    }
  /**
   * @see java.io.Externalizable
   **/
  public void writeExternal(ObjectOutput out) throws IOException {
    super.writeExternal(out);
    out.writeObject(id);
    out.writeObject(pe);
  }
  /**
   * @see java.io.Externalizable
   **/
  public void readExternal(ObjectInput in)
    throws IOException, java.lang.ClassNotFoundException {
    super.readExternal(in);
    id = (UniqueID) in.readObject();
    pe = (PE) in.readObject();
  }
    public String toString() {
      return "RegisterMessage[id:" + id + "]";
    }
  }
  /**
   * Called by RegisterMessage
   **/
  void registerHandler(UniqueID id, PE pe) {
    try {
      Vector addresses = (Vector) notifyTable.get(id);
      addresses.addElement(pe);
      // Did client miss anything?
      Vector history = (Vector) historyTable.get(id);
      if (history != null && history.size() > 0) {
        if (DEBUG)
          Aleph.debug("sending notify message to " + id.getHome());
  cManager.send(pe, new NotifyMessage(id, history));
      }
    } catch (Exception e) {Aleph.panic(e);}
  }

  /**
   * @return which event manager are we?
   **/
  public String getLabel() {
    return "Simple";
  }
}
TOP

Related Classes of aleph.event.SimpleEventManager$SignalMessage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.