This is the mail archive of the frysk@sources.redhat.com mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

New framework for suspending Tasks


Hi,

This introduces a simplified way to have observers that need a task to
be (temporarily) suspended when they are added. The syscall and code
observers had their own way of doing that and the blocking and stepping
observers would also need that functionality. This patch merges these
things.

Since TaskObservers are interfaces we cannot easily associate suspension
actions to them. So this binding is done through the TaskObservation
which is filled in Proc with an action object and a method to determine
whether the observer needs the Task to be suspended before addition or
removal. For Syscall and Code observers these determine whether extra
action is needed and if so when they are added in one of the TaskStates
that indicate a still running task they are pushed on a queue and the
Task is suspended. As soon as the Task is suspended the pending
observations have their actions triggered and they are added and/or
removed from the Task. Then the Task is resumed again.

This setup should make it easy to add other observers that need to take
actions on the Task that need the task to be suspended. Like the
blocking and stepping observers that I will be working on next.

2006-10-11  Mark Wielaard  <mark@klomp.org>

    * BreakpointAddresses.java (getCodeObservers): Return the Collection
    of Code Observers, not just an Iterator.
    * Observable.java (observable): Make protected final for use in
    subclasses.
    * PendingCodeObserver.java: Removed.
    * Proc.java (requestAddObservation): Create TaskObservation with
    adding true.
    (requestDeleteObserver): Likewise with adding false.
    (SyscallAction): New inner class.
    (requestAddSyscallObserver): Create TaskObservation with
    SyscallAction.
    (requestDeleteSyscallObserver): Likewise.
    (BreakpointAction): New inner class.
    (requestAddCodeObserver): Create TaskObservation with
    BreakpointAction.
    (requestDeleteCodeObserver): Likewise.
    * Task.java (Task): Create TaskObservation with adding true.
    (handleAddObserver): Renamed to handleAddObservation().
    (handleDeleteObserver): Renamed to handleDeleteObservation().
    (handleAddSyscallObserver): Removed.
    (handleDeleteSyscallObserver): Removed.
    (handleAddCodeObserver): Removed.
    (handleDeleteCodeObserver): Removed.
    (notifyCodeBreakpoint): Use observers Collections.
    (pendingCodeObservers): Removed.
    (pendingObservations): New field.
    * TaskCodeObservation.java: Removed.
    * TaskObservation.java (TaskObservation): Add arguments for whether
    we are adding and whether any action is needed before adding or
    after deletion.
    (getTaskObservable): New method.
    (getTaskObserver): New method.
    (isAddition): New method.
    (needsSuspendedAction): New method.
    (add): New method.
    (delete): New method.
    * TaskState.java (handleAddObserver): Renamed to
    handleAddObservation().
    (handleDeleteObserver): Renamed to handleDeleteObservation().
    (handleAddSyscallObserver): Removed.
    (handleDeleteSyscallObserver): Removed.
    (handleAddCodeObserver): Removed.
    (handleDeleteCodeObserver): Removed.
    (Running.handleStoppedEvent): Go through pendingObservations.
    (Running.handleAddObservation): If needsSuspendedAction() queue
    and sendStop() if necessary.
    (Running.handleDeleteObservation): Likewise.
    * TaskSyscallObservation.java: Removed.

    * TestBreakpoints.java (testInsertRemove): Mark broken #3240.

Tested on x86 and x86_64 on fc5.

The patch looks larger than it actually is. A lot of it is actually
removing code that was duplicated all over the place and that is now all
shared through the TaskObservation. In particular TaskState is now 200
lines smaller because all the special cases for handleSyscallObserver
and handleCodeObserver could be removed for all states.

The testInsertRemove test was disabled for now. As mentioned in the bug
report this was occasionally failing in the past, but it was hard to
trigger. With the new setup it is much easier to trigger. It looks like
it has something to do with how we handle exec events. I'll look into
this asap.

Committed,

Mark
? frysk-core/ForkTestLib.patch
? frysk-core/TaskState-transistion-syscall.patch
? frysk-core/breakpoint.patch
? frysk-core/fc6proc.patch
? frysk-core/states
? frysk-core/syscall-running-accept.patch
? frysk-core/frysk/bindir/faddr.java
? frysk-core/frysk/bindir/fdtrace.java
? frysk-core/frysk/pkglibexecdir/funit-syscall-running.c.testing
? frysk-core/frysk/proc/DummyProc.java.mark
? frysk-core/frysk/proc/TaskState.java.mark
? frysk-core/frysk/proc/TestSyscallRunning.java.testing
? frysk-core/frysk/proc/cni/ForkTestLib.cxx.daemon
Index: frysk-core/frysk/proc/BreakpointAddresses.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/BreakpointAddresses.java,v
retrieving revision 1.4
diff -u -r1.4 BreakpointAddresses.java
--- frysk-core/frysk/proc/BreakpointAddresses.java	5 Oct 2006 12:06:48 -0000	1.4
+++ frysk-core/frysk/proc/BreakpointAddresses.java	11 Oct 2006 13:16:57 -0000
@@ -134,11 +134,11 @@
   }
 
   /**
-   * Called by the Proc when it has trapped a breakpoint.  Returns an
-   * Iterator of TaskObserver.Code observers interested in the given
+   * Called by the Proc when it has trapped a breakpoint.  Returns a
+   * Collection of TaskObserver.Code observers interested in the given
    * address or null when no Code observer was installed on this address.
    */
-  Iterator getCodeObservers(long address)
+  Collection getCodeObservers(long address)
   {
     ArrayList observers;
     Breakpoint breakpoint = Breakpoint.create(address, proc);
@@ -150,7 +150,7 @@
     // wants to add or remove itself or a new observer to that same
     // breakpoint.
     observers = (ArrayList) list.clone();
-    return observers.iterator();
+    return observers;
   }
 
   /**
Index: frysk-core/frysk/proc/Observable.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/Observable.java,v
retrieving revision 1.4
diff -u -r1.4 Observable.java
--- frysk-core/frysk/proc/Observable.java	5 Jul 2006 18:07:50 -0000	1.4
+++ frysk-core/frysk/proc/Observable.java	11 Oct 2006 13:16:57 -0000
@@ -49,7 +49,7 @@
 
 class Observable
 {
-    private Object observable;
+    final protected Object observable;
     /**
      * Create an observable bound to Object.
      */
Index: frysk-core/frysk/proc/PendingCodeObserver.java
===================================================================
RCS file: frysk-core/frysk/proc/PendingCodeObserver.java
diff -N frysk-core/frysk/proc/PendingCodeObserver.java
--- frysk-core/frysk/proc/PendingCodeObserver.java	21 Sep 2006 16:45:01 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,71 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2006, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-
-package frysk.proc;
-
-
-/**
- * Small struct to record pending Code Observers. Package private,
- * used by Task and TaskState.
- */
-final class PendingCodeObserver
-{
-  // True if this observer needs to be added,
-  // false if it needs to be deleted deletion.
-  boolean addition;
-  
-  // The Code observer to add or delete.
-  TaskObserver.Code observer;
-
-  // The address on which to set a breakpoint
-  long address;
-  
-  // The observable - XXX isn't this always the task?
-  Observable observable;
-  
-  public String toString()
-  {
-    return ("PendingCodeObserver[observer=" +observer
-	    + ", addition=" + addition
-	    + ", observable=" + observable
-	    + ", address=" + Long.toHexString(address)
-	    + "]");
-  }
-}
Index: frysk-core/frysk/proc/Proc.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/Proc.java,v
retrieving revision 1.82
diff -u -r1.82 Proc.java
--- frysk-core/frysk/proc/Proc.java	4 Oct 2006 21:30:09 -0000	1.82
+++ frysk-core/frysk/proc/Proc.java	11 Oct 2006 13:16:57 -0000
@@ -375,7 +375,8 @@
 			     TaskObserver observer)
     {
 	logger.log (Level.FINE, "{0} requestAddObservation\n", this); 
-	Manager.eventLoop.add (new TaskObservation (task, observable, observer)
+	Manager.eventLoop.add (new TaskObservation (task, observable, observer,
+						    false)
 	    {
 		public void execute ()
 		{
@@ -385,23 +386,62 @@
     }
     
     /**
+     * Class describing the action to take on the suspended Task before
+     * adding or deleting a Syscall observer.
+     */
+    final class SyscallAction implements Runnable
+    {
+      private final Task task;
+      private final boolean addition;
+      
+      SyscallAction(Task task, boolean addition)
+      {
+	this.task = task;
+	this.addition = addition;
+      }
+
+      public void run()
+      {
+	int syscallobs = task.syscallObservers.numberOfObservers();
+	if (addition)
+	  {
+	    if (syscallobs == 0)
+	      task.startTracingSyscalls();
+	  }
+	else
+	  {
+	    if (syscallobs == 0)
+	      task.stopTracingSyscalls();
+	  }
+      }
+    }
+
+    /**
      * (Internal) Tell the process to add the specified Observation,
      * attaching to the process if necessary.
      * Adds a syscallObserver which changes the task to syscall
      * tracing mode of necessary.
      */
-    void requestAddSyscallObserver (Task task,
+    void requestAddSyscallObserver (final Task task,
 			     TaskObservable observable,
 			     TaskObserver observer)
     {
 	logger.log (Level.FINE, "{0} requestAddSyscallObserver\n", this); 
-	Manager.eventLoop.add (new TaskSyscallObservation (task, observable, observer)
+        SyscallAction sa = new SyscallAction(task, true);
+        TaskObservation to = new TaskObservation(task, observable,
+						 observer, sa, true)
 	    {
 		public void execute ()
 		{
 		    handleAddObservation (this);
 		}
-	    });
+
+	        public boolean needsSuspendedAction()
+	        {
+		  return task.syscallObservers.numberOfObservers() == 0;
+		}
+	    };
+	Manager.eventLoop.add(to);
     }
     
     /**
@@ -414,7 +454,8 @@
 				TaskObservable observable,
 				TaskObserver observer)
     {
-	Manager.eventLoop.add (new TaskObservation (task, observable, observer)
+        Manager.eventLoop.add (new TaskObservation (task, observable, observer,
+						    false)
 	    {
 		public void execute ()
 		{
@@ -428,18 +469,74 @@
      * (Internal) Tell the process to delete the specified
      * Observation, detaching from the process if necessary.
      */
-    void requestDeleteSyscallObserver (Task task,
+    void requestDeleteSyscallObserver (final Task task,
 				TaskObservable observable,
 				TaskObserver observer)
     {
-	Manager.eventLoop.add (new TaskSyscallObservation (task, observable, observer)
+	logger.log (Level.FINE, "{0} requestDeleteSyscallObserver\n", this); 
+        SyscallAction sa = new SyscallAction(task, false);
+        TaskObservation to = new TaskObservation(task, observable,
+						 observer, sa, false)
 	    {
 		public void execute ()
 		{
 		    newState = oldState ().handleDeleteObservation
 			(Proc.this, this);
 		}
-	    });
+
+	        public boolean needsSuspendedAction()
+	        {
+		  return task.syscallObservers.numberOfObservers() == 1;
+		}
+	    };
+	Manager.eventLoop.add(to);
+    }
+
+    /**
+     * Class describing the action to take on the suspended Task before
+     * adding or deleting a Code observer.
+     */
+    final class BreakpointAction implements Runnable
+    {
+      private final TaskObserver.Code code;
+      private final Task task;
+      private final long address;
+      private final boolean addition;
+      
+      BreakpointAction(TaskObserver.Code code,
+		       Task task,
+		       long address,
+		       boolean addition)
+      {
+	this.code = code;
+	this.task = task;
+	this.address = address;
+	this.addition = addition;
+      }
+
+      public void run()
+      {
+	if (addition)
+	  {
+	    boolean mustInstall = breakpoints.addBreakpoint(code, address);
+	    if (mustInstall)
+	      {
+		Breakpoint breakpoint;
+		breakpoint = Breakpoint.create(address, Proc.this);
+		breakpoint.install(task);
+	      }
+	  }
+	else
+	  {
+	    boolean mustRemove = breakpoints.removeBreakpoint(code, address);
+	    if (mustRemove)
+	      {
+		Breakpoint breakpoint;
+		breakpoint = Breakpoint.create(address, Proc.this);
+		breakpoint.remove(task);
+	      }
+	  }
+      }
     }
 
     /**
@@ -451,18 +548,25 @@
     void requestAddCodeObserver (Task task,
 				 TaskObservable observable,
 				 TaskObserver.Code observer,
-				 long address)
+				 final long address)
     {
 	logger.log (Level.FINE, "{0} requestAddCodeObserver\n", this); 
-	TaskCodeObservation tco;
-	tco = new TaskCodeObservation(task, observable, observer, address)
+	BreakpointAction bpa = new BreakpointAction(observer, task, address,
+						    true);
+	TaskObservation to;
+	to = new TaskObservation(task, observable, observer, bpa, true)
 	  {
 	    public void execute ()
 	    {
 	      handleAddObservation (this);
 	    }
+
+	    public boolean needsSuspendedAction()
+	    {
+	      return breakpoints.getCodeObservers(address) == null;
+	    }
 	  };
-	Manager.eventLoop.add(tco);
+	Manager.eventLoop.add(to);
     }
     
     /**
@@ -472,18 +576,26 @@
     void requestDeleteCodeObserver (Task task,
 				    TaskObservable observable,
 				    TaskObserver.Code observer,
-				    long address)
+				    final long address)
     {
-      TaskCodeObservation tco;
-      tco = new TaskCodeObservation(task, observable, observer, address)
+        logger.log (Level.FINE, "{0} requestDeleteCodeObserver\n", this); 
+	BreakpointAction bpa = new BreakpointAction(observer, task, address,
+						    false);
+	TaskObservation to;
+	to = new TaskObservation(task, observable, observer, bpa, false)
 	{
 	  public void execute()
 	  {
 	    newState = oldState().handleDeleteObservation(Proc.this, this);
 	  }
+
+	  public boolean needsSuspendedAction()
+	  {
+	    return breakpoints.getCodeObservers(address).size() == 1;
+	  }
 	};
 
-      Manager.eventLoop.add(tco);
+      Manager.eventLoop.add(to);
     }
 
     /**
Index: frysk-core/frysk/proc/Task.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/Task.java,v
retrieving revision 1.102
diff -u -r1.102 Task.java
--- frysk-core/frysk/proc/Task.java	5 Oct 2006 12:06:48 -0000	1.102
+++ frysk-core/frysk/proc/Task.java	11 Oct 2006 13:16:57 -0000
@@ -43,6 +43,7 @@
 import inua.eio.ByteBuffer;
 import java.util.Set;
 import java.util.HashSet;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -203,7 +204,7 @@
     if (attached != null)
       {
         TaskObservation ob = new TaskObservation(this, attachedObservers,
-                                                 attached)
+                                                 attached, true)
         {
           public void execute ()
           {
@@ -268,32 +269,17 @@
   /**
    * (Internal) Add the specified observer to the observable.
    */
-  void handleAddObserver (Observable observable, Observer observer)
+  void handleAddObservation(TaskObservation observation)
   {
-    newState = oldState().handleAddObserver(Task.this, observable, observer);
+    newState = oldState().handleAddObservation(this, observation);
   }
 
   /**
    * (Internal) Delete the specified observer from the observable.
    */
-  void handleDeleteObserver (Observable observable, Observer observer)
+  void handleDeleteObservation(TaskObservation observation)
   {
-    newState = oldState().handleDeleteObserver(Task.this, observable, observer);
-  }
-
-  void handleAddSyscallObserver (Observable observable, Observer observer)
-  {
-    newState = oldState().handleAddSyscallObserver(Task.this, observable,
-                                                   observer);
-  }
-
-  /**
-   * (Internal) Delete the specified observer from the observable.
-   */
-  void handleDeleteSyscallObserver (Observable observable, Observer observer)
-  {
-    newState = oldState().handleDeleteSyscallObserver(Task.this, observable,
-                                                      observer);
+    newState = oldState().handleDeleteObservation(this, observation);
   }
 
   /**
@@ -305,28 +291,6 @@
   }
 
   /**
-   * Called by <code>TaskCodeObservation</code> when added through the
-   * event loop.
-   */
-  void handleAddCodeObserver (Observable observable,
-			      TaskObserver.Code observer, long address)
-  {
-    newState = oldState().handleAddCodeObserver(this, observable, observer,
-						address);
-  }
-
-  /**
-   * Called by <code>TaskCodeObservation</code> when deleted through the
-   * event loop.
-   */
-  void handleDeleteCodeObserver (Observable observable,
-				 TaskObserver.Code observer, long address)
-  {
-    newState = oldState().handleDeleteCodeObserver(this, observable, observer,
-						   address);
-  }
-
-  /**
    * (Internal) Tell the task to remove itself (it is no longer listed in the
    * system process table and, presumably, has exited).
    */
@@ -939,10 +903,11 @@
     logger.log(Level.FINE, "{0} notifyCodeBreakpoint({1})\n",
 	       new Object[] { this, Long.valueOf(address) });
     
-    Iterator i = proc.breakpoints.getCodeObservers(address);
-    if (i == null)
+    Collection observers = proc.breakpoints.getCodeObservers(address);
+    if (observers == null)
       return -1;
 
+    Iterator i = observers.iterator();
     while (i.hasNext())
       {
 	TaskObserver.Code observer = (TaskObserver.Code) i.next();
@@ -952,8 +917,35 @@
     return blockers.size();
   }
 
-  // List containing the CodeObservers that are pending addition
-  // or deletion (in order that they were requested). Will be inserted
+  // List containing the TaskObservations that are pending addition
+  // or deletion (in order that they were requested). Will be dealt with
   // as soon as a stop event is received during one of the running states.
-  LinkedList pendingCodeObservers = new LinkedList();
+  LinkedList pendingObservations = new LinkedList();
+
+  /**
+   * Set of Blocked observers.
+   */
+  TaskObservable blockedObservers = new TaskObservable(this);
+  
+  /**
+   * Request the addition of a Blocked observer that will be notified
+   * as soon as the task is (temporarily) suspended. The suspension of
+   * the Task is only once. As soon as the task has been blocked once
+   * the observer is automatically removed.
+   */
+  public void requestAddBlockedObserver(TaskObserver.Blocked o)
+  {
+    logger.log(Level.FINE, "{0} requestAddBlockedObserver\n", this);
+    proc.requestAddObserver(this, blockedObservers, o);
+  }
+
+  /**
+   * Delete TaskObserver.Blocked from the TaskObserver pool.
+   */
+  public void requestDeleteBlockedObserver (TaskObserver.Blocked o)
+  {
+    logger.log(Level.FINE, "{0} requestDeleteBlockedObserver\n", this);
+    proc.requestDeleteObserver(this, blockedObservers, o);
+  }
+  
 }
Index: frysk-core/frysk/proc/TaskCodeObservation.java
===================================================================
RCS file: frysk-core/frysk/proc/TaskCodeObservation.java
diff -N frysk-core/frysk/proc/TaskCodeObservation.java
--- frysk-core/frysk/proc/TaskCodeObservation.java	2 Oct 2006 15:52:18 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,87 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2006, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.proc;
-
-/**
- * Observation on tasks that will call
- * <code>handleAddCodeObserver</code> on the given Task from
- * <code>handleAdd</code> and <code>handleDeleteCodeObserver</code> on
- * <code>handleDelete</code>.
- */
-abstract class TaskCodeObservation
-  extends TaskObservation
-{
-  private final long address;
-
-  /**
-   * Create a new CodeObserver binding.
-   */
-  public TaskCodeObservation(Task task,
-			     Observable observable,
-			     TaskObserver.Code observer,
-			     long address)
-  {
-    super(task, observable, observer);
-    this.address = address;
-  }
-
-  /**
-   * Handle adding the SyscallObserver to the Observable.
-   */
-  public void handleAdd()
-  {
-    task.handleAddCodeObserver(observable, (TaskObserver.Code) observer,
-			       address);
-  }
-
-  /**
-   * Handle deleting the SyscallObserver from the Observable.
-   */
-  public void handleDelete ()
-  {
-    task.handleDeleteCodeObserver(observable, (TaskObserver.Code) observer,
-				  address);
-  }
-  
-  public String toString()
-  {
-    return ("[TaskCodeObservation Event" + address + "]");
-  }
-}
Index: frysk-core/frysk/proc/TaskObservation.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/TaskObservation.java,v
retrieving revision 1.5
diff -u -r1.5 TaskObservation.java
--- frysk-core/frysk/proc/TaskObservation.java	11 Jun 2006 15:11:06 -0000	1.5
+++ frysk-core/frysk/proc/TaskObservation.java	11 Oct 2006 13:16:57 -0000
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2005, Red Hat Inc.
+// Copyright 2005, 2006 Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -46,28 +46,111 @@
 abstract class TaskObservation
     extends Observation
 {
-    protected Task task;
+    private final Task task;
+    private final Runnable action;
+    private final boolean adding;
+
+    public TaskObservation (Task task, TaskObservable observable,
+			    TaskObserver observer, boolean adding)
+    {
+      this(task, observable, observer, null, adding);
+    }
+
     /**
      * Create a new Observer binding.
+     *
+     * @param task The Task the observer will be added to.
+     * @param observable The TaskObservable (of the specified task)
+     * that the observer should be added to.
+     * @param observer The TaskObserver to add.
+     * @param action An action to run, or null if none, before adding
+     * or after deletion while the Task is (temporarily) suspended.
      */
-    public TaskObservation (Task task, Observable observable,
-			    Observer observer)
+    public TaskObservation (Task task, TaskObservable observable,
+			    TaskObserver observer, Runnable action,
+			    boolean adding)
     {
 	super (observable, observer);
 	this.task = task;
+	this.action = action;
+	this.adding = adding;
     }
     /**
      * Handle adding the Observer to the Observable.
+     * The Task should call <code>add()</code> when it is actually
+     * ready to bind the observer to the observable.
+     *
+     * @see TaskObservation#needsSuspendedAction()
      */
     public void handleAdd ()
     {
-	task.handleAddObserver (observable, observer);
+	task.handleAddObservation(this);
     }
     /**
      * Handle deleting the Observer from the Observable.
+     * The Task should call <code>delete()</code> when it is actually
+     * ready to bind the observer to the observable.
+     *
+     * @see TaskObservation#needsSuspendedAction()
      */
     public void handleDelete ()
     {
-	task.handleDeleteObserver (observable, observer);
+	task.handleDeleteObservation(this);
+    }
+
+    public TaskObservable getTaskObservable()
+    {
+      return (TaskObservable) observable;
+    }
+
+    public TaskObserver getTaskObserver()
+    {
+      return (TaskObserver) observer;
+    }
+
+    /**
+     * Returns true if this is an addition, false if it is a deletion.
+     */
+    public boolean isAddition()
+    {
+      return adding;
+    }
+
+    /**
+     * Returns true if an action was supplied to the constructor to be
+     * run when the Task is (temporarily) suspended. If this method
+     * returns true then the Task should be suspended before calling
+     * <code>add()</code> or <code>delete()</code> on this
+     * TaskObservation.
+     */
+    public boolean needsSuspendedAction()
+    {
+      return action != null;
+    }
+
+    /**
+     * Runs any action (if suplied) and then adds the observer to the
+     * observable. If <code>needsSuspendedAction()</code> returns true
+     * then this method should only be called if the Task is
+     * (temporarily) suspended.
+     */
+    public void add()
+    {
+      if (action != null)
+	action.run();
+      observable.add(observer);
+    }
+
+    /**
+     * Deletes the observer from the observable and then runs any
+     * action (if suplied). If <code>needsSuspendedAction()</code>
+     * returns true then this method should only be called if the Task
+     * is (temporarily) suspended.
+     */
+    public void delete()
+    {
+      observable.delete(observer);
+      if (action != null)
+	action.run();
     }
 }
Index: frysk-core/frysk/proc/TaskObserver.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/TaskObserver.java,v
retrieving revision 1.17
diff -u -r1.17 TaskObserver.java
--- frysk-core/frysk/proc/TaskObserver.java	21 Sep 2006 16:45:01 -0000	1.17
+++ frysk-core/frysk/proc/TaskObserver.java	11 Oct 2006 13:16:57 -0000
@@ -176,6 +176,27 @@
     }
 
     /**
+     * Interface used to notify that a Task has been blocked for now.
+     * When the <code>updateBlocked</code> method is triggered it is
+     * guaranteed to Task has (temporarily) suspended
+     * execution. <code>updateBlocked</code> will be called at most
+     * once. If <code>Action.CONTINUE</code> is returned or after
+     * <code>requestUnblock()</code> is called on the Task the
+     * observer is removed from the task and will not be triggered
+     * unless it is explictily readded. To continiously monitor a
+     * running Task see the <code>Instruction</code> interface.
+     */
+    public interface Blocked
+	extends TaskObserver
+    {
+	/**
+	 * The task has executed one instruction.  Return Action.BLOCK
+	 * to block the task's further execution.
+	 */
+	Action updateBlocked (Task task);
+    }
+
+    /**
      * Interface used to notify that a Task has executed a single
      * instruction.
      */
Index: frysk-core/frysk/proc/TaskState.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/TaskState.java,v
retrieving revision 1.120
diff -u -r1.120 TaskState.java
--- frysk-core/frysk/proc/TaskState.java	5 Oct 2006 12:53:19 -0000	1.120
+++ frysk-core/frysk/proc/TaskState.java	11 Oct 2006 13:16:57 -0000
@@ -149,37 +149,14 @@
     {
 	throw unhandled (task, "handleUnblock");
     }
-    TaskState handleAddObserver (Task task, Observable observable,
-				 Observer observer)
+    TaskState handleAddObservation (Task task, TaskObservation observation)
     {
-	throw unhandled (task, "handleAddObserver");
+	throw unhandled (task, "handleAddObservation");
     }
-    TaskState handleDeleteObserver (Task task, Observable observable, Observer observer)
+    TaskState handleDeleteObservation (Task task, TaskObservation observation)
     {
-	throw unhandled (task, "handleDeleteObserver");
+	throw unhandled (task, "handleDeleteObservation");
     }
-    TaskState handleAddSyscallObserver (Task task, Observable observable, Observer observer)
-    {
-	throw unhandled (task, "handleAddSyscallObserver");
-    }
-    TaskState handleDeleteSyscallObserver (Task task, Observable observable, Observer observer)
-    {
-	throw unhandled (task, "handleDeleteSyscallObserver");
-    }
-    TaskState handleAddCodeObserver(Task task, Observable observable,
-				    TaskObserver.Code observer,
-				    long address)
-    {
-      throw unhandled (task, "handleAddCodeObserver");
-    } 
-    TaskState handleDeleteCodeObserver(Task task, Observable observable,
-				       TaskObserver.Code observer,
-				       long address)
-    {
-      throw unhandled (task, "handleDeleteCodeObserver");
-    } 
-
-
     
     /**
      * An attached task was destroyed, notify observers and, when the
@@ -293,21 +270,20 @@
 	/**
 	 * In all Attached states, addObservation is allowed.
 	 */
-	TaskState handleAddObserver (Task task, Observable observable,
-				     Observer observer)
+        TaskState handleAddObservation(Task task, TaskObservation observation)
 	{
 	    logger.log (Level.FINE, "{0} handleAddObserver\n", task);
-	    observable.add (observer);
+	    observation.add();
 	    return this;
 	}
 	/**
 	 * In all Attached states, deleteObservation is allowed.
 	 */
-	TaskState handleDeleteObserver (Task task, Observable observable,
-					Observer observer)
+        TaskState handleDeleteObservation(Task task,
+					  TaskObservation observation)
 	{
 	    logger.log (Level.FINE, "{0} handleDeleteObserver\n", task); 
-	    observable.delete (observer);
+	    observation.delete();
 	    return this;
 	}
 	/**
@@ -359,25 +335,6 @@
 		else
 		  return new Attached.WaitForUnblock (signal);
 	    }
-	    TaskState handleAddSyscallObserver (Task task, Observable observable, Observer observer)
-	    {
-		logger.log (Level.FINE, "{0} handleAddSyscallObserver\n", task);
-		if (task.syscallObservers.numberOfObservers() == 0)
-		  task.startTracingSyscalls();
-		observable.add(observer);
-		return this;
-	    }	    
-	    TaskState handleDeleteSyscallObserver(Task task,
-						  Observable observable,
-						  Observer observer)
-	    {
-	      logger.log (Level.FINE, "{0} handleDeleteSyscallObserver\n", task);
-	      observable.delete(observer);
-	      if (task.syscallObservers.numberOfObservers() == 0)
-		task.stopTracingSyscalls();
-	      return this;
-	    }
-
 	}
 	private static final TaskState waitForContinueOrUnblock =
 	    new Attached.WaitForContinueOrUnblock (0);
@@ -411,28 +368,6 @@
 		  return transitionToRunningState(task, signal);
 		return this;
 	    }
-	    TaskState handleAddSyscallObserver(Task task,
-					       Observable observable,
-					       Observer observer)
-	    {
-	      logger.log (Level.FINE, "{0} handleAddSyscallObserver\n",
-			  task);
-	      if (task.syscallObservers.numberOfObservers() == 0)
-		task.startTracingSyscalls();
-	      observable.add(observer);
-	      return this;
-	    }	    
-	  TaskState handleDeleteSyscallObserver(Task task,
-						Observable observable,
-						Observer observer)
-	  {
-	    logger.log (Level.FINE, "{0} handleDeleteSyscallObserver\n", task);
-	    observable.delete(observer);
-	    if (task.syscallObservers.numberOfObservers() == 0)
-	      task.stopTracingSyscalls();
-	    return this;
-	  }
-
 	}
     }
 
@@ -535,11 +470,12 @@
 	private static TaskState wantToAttach =
 	    new StartMainTask ("wantToAttach")
 	    {
-		TaskState handleAddObserver (Task task, Observable observable,
-					     Observer observer)
+		TaskState handleAddObservation(Task task,
+					       TaskObservation observation)
 		{
 		    logger.log (Level.FINE, "{0} handleAddObserver\n", task);
-		    observable.add (observer);
+		    // XXX - This should most likely test needsSuspendedAction
+		    observation.add();
 		    return this;
 		}
 		TaskState blockOrAttach (Task task)
@@ -600,11 +536,11 @@
 	private static TaskState attachBlocked =
 	    new StartMainTask ("attachBlocked")
 	    {
-		TaskState handleAddObserver (Task task, Observable observable,
-					     Observer observer)
+		TaskState handleAddObservation(Task task,
+					       TaskObservation observation)
 		{
 		    logger.log (Level.FINE, "{0} handleAddObserver\n", task);
-		    observable.add (observer);
+		    observation.add();
 		    return this;
                 }
 		TaskState handleUnblock (Task task,
@@ -631,11 +567,11 @@
 	private static TaskState attachContinueBlocked =
 	    new StartMainTask ("attachContinueBlocked")
 	    {
-		TaskState handleAddObserver (Task task, Observable observable,
-					     Observer observer)
+		TaskState handleAddObservation(Task task,
+					       TaskObservation observation)
 		{
 		    logger.log (Level.FINE, "{0} handleAddObserver\n", task);
-		    observable.add (observer);
+		    observation.add();
 		    return this;
 		}
 		TaskState handleUnblock (Task task,
@@ -673,18 +609,19 @@
 	    task.sendContinue (0);
 	    return running;
 	}
-	TaskState handleAddObserver (Task task, Observable observable,
-				     Observer observer)
+	TaskState handleAddObservation(Task task, TaskObservation observation)
 	{
 	    logger.log (Level.FINE, "{0} handleAddObserver\n", task);
-	    observable.add (observer);
+	    // XXX most likely need to check needsSuspendedAction
+	    observation.add();
 	    return this;
 	}
-	TaskState handleDeleteObserver (Task task, Observable observable,
-					Observer observer)
+	TaskState handleDeleteObservation(Task task,
+					  TaskObservation observation)
 	{
 	    logger.log (Level.FINE, "{0} handleDeleteObserver\n", task); 
-	    observable.delete (observer);
+	    // XXX most likely need to check needsSuspendedAction
+	    observation.delete();
 	    return this;
 	}
 
@@ -738,15 +675,6 @@
 		      }
 		}
 	    };
-      TaskState handleAddSyscallObserver (Task task,
-					  Observable observable,
-					  Observer observer)
-      {
-	if (task.syscallObservers.numberOfObservers() == 0)
-	  task.startTracingSyscalls();
-	observable.add(observer);
-	return this;
-      }
     }
 
     /**
@@ -804,71 +732,31 @@
 	}
 	TaskState handleStoppedEvent (Task task)
 	{
-	  // Should we turn on or off syscall tracing?
-	  int syscallobs = task.syscallObservers.numberOfObservers();
-	  boolean start_trace = ! syscalltracing && syscallobs > 0 ;
-	  boolean stop_trace = syscalltracing && syscallobs == 0;
-
-	  Collection pendingCodeObservers = task.pendingCodeObservers;
-
-	  if (pendingCodeObservers.isEmpty() && ! start_trace && ! stop_trace)
-	    {
-	      // From time to time bogus stop events appear, for
-	      // instance when the kernel simultaneously receives both
-	      // an attach and signal for an identical process.  Just
-	      // discard them.
-	      logger.log (Level.FINE,
-			  "{0} spurious handleStoppedEvent\n", task); 
-	      return this;
-	    }
+	  Collection pendingObservations = task.pendingObservations;
+	  if (pendingObservations.isEmpty())
+	    throw new RuntimeException("Whoa!");
 
-	  logger.log (Level.FINE, "{0} handleStoppedEvent\n", task); 
-	  Iterator it = pendingCodeObservers.iterator();
+	  Iterator it = pendingObservations.iterator();
 	  while (it.hasNext())
 	    {
-	      PendingCodeObserver pco = (PendingCodeObserver) it.next();
-	      if (pco.addition)
-		{
-		  if (task.proc.breakpoints.addBreakpoint(pco.observer,
-							  pco.address))
-		    {
-		      Breakpoint breakpoint;
-		      breakpoint = Breakpoint.create(pco.address, task.proc);
-		      breakpoint.install(task);
-		    }
-		  pco.observable.add(pco.observer);
-		}
+	      TaskObservation observation = (TaskObservation) it.next();
+	      if (observation.isAddition())
+		observation.add();
 	      else
-		{
-		  if (task.proc.breakpoints.removeBreakpoint(pco.observer,
-							     pco.address))
-		    {
-		      Breakpoint breakpoint;
-		      breakpoint = Breakpoint.create(pco.address, task.proc);
-		      breakpoint.remove(task);
-		    }
-		  pco.observable.delete(pco.observer);
-		}
+		observation.delete();
 	      it.remove();
 	    }
 
-	  if (start_trace)
+	  if (task.syscallObservers.numberOfObservers() > 0)
 	    {
-	      task.startTracingSyscalls();
 	      task.sendSyscallContinue(0);
 	      return insyscall ? inSyscallRunningTraced : syscallRunning;
 	    }
-	  else if (stop_trace)
+	  else
 	    {
-	      task.stopTracingSyscalls();
 	      task.sendContinue(0);
 	      return insyscall ? inSyscallRunning : running;
 	    }
-	  else
-	    {
-	      sendContinue(task, 0);
-	      return this;
-	    }
 	}
 
 	TaskState handleTerminatingEvent (Task task, boolean signal,
@@ -912,9 +800,11 @@
 	    while (it.hasNext())
 	      ((TaskObserver.Code) it.next()).deletedFrom(task);
 
+	    /* XXX - FIXME...
 	    it = task.pendingCodeObservers.iterator();
 	    while (it.hasNext())
 	      ((PendingCodeObserver) it.next()).observer.deletedFrom(task);
+	    */
 
 	    if (task.notifyExeced () > 0)
 	      {
@@ -1032,50 +922,33 @@
 	  return blockedContinue();
       }
 
-      TaskState handleAddCodeObserver(Task task, Observable observable,
-				      TaskObserver.Code observer,
-				      long address)
-      {
-	// We cannot add or delete when running, push it on the queue
-	// and stop the task.
-	PendingCodeObserver pco = new PendingCodeObserver();
-	pco.addition = true;
-	pco.observer = observer;
-	pco.observable = observable;
-	pco.address = address;
-	task.pendingCodeObservers.add(pco);
-	task.sendStop();
-	return this;
-      }
-
-      TaskState handleDeleteCodeObserver(Task task, Observable observable,
-					 TaskObserver.Code observer,
-					 long address)
-      {
-	// We cannot add or delete when running, push it on the queue
-	// and stop the task.
-	PendingCodeObserver pco = new PendingCodeObserver();
-	pco.addition = false;
-	pco.observer = observer;
-	pco.observable = observable;
-	pco.address = address;
-	task.pendingCodeObservers.add(pco);
-	task.sendStop();
-	return this;
-      }
-
-	TaskState handleAddObserver (Task task, Observable observable,
-				     Observer observer)
+	TaskState handleAddObservation(Task task, TaskObservation observation)
 	{
 	    logger.log (Level.FINE, "{0} handleAddObserver\n", task);
-	    observable.add (observer);
+	    if (! observation.needsSuspendedAction())
+	      observation.add();
+	    else
+	      {
+		Collection pending = task.pendingObservations;
+		if (pending.isEmpty())
+		  task.sendStop();
+		pending.add(observation);
+	      }
 	    return this;
 	}
-	TaskState handleDeleteObserver (Task task, Observable observable,
-					Observer observer)
+	TaskState handleDeleteObservation(Task task,
+					  TaskObservation observation)
 	{
 	    logger.log (Level.FINE, "{0} handleDeleteObserver\n", task); 
-	    observable.delete (observer);
+	    if (! observation.needsSuspendedAction())
+	      observation.delete();
+	    else
+	      {
+		Collection pending = task.pendingObservations;
+		if (pending.isEmpty())
+		  task.sendStop();
+		pending.add(observation);
+	      }
 	    return this;
 	}
 	TaskState handleUnblock (Task task,
@@ -1086,28 +959,6 @@
 	    // observer.fail (new RuntimeException (task, "not blocked");
 	    return this;
 	}
-	TaskState handleAddSyscallObserver (Task task, Observable observable, Observer observer)
-	{
-	  observable.add(observer);
-	  if (! syscalltracing)
-	    task.sendStop();
-	  return this;
-	}
-      TaskState handleDeleteSyscallObserver(Task task,
-					    Observable observable,
-					    Observer observer)
-      {
-	logger.log(Level.FINE, "{0} handleDeleteSyscallObserver\n", task);
-	observable.delete(observer);
-	if (syscalltracing && observable.numberOfObservers() == 0)
-	  {
-	    logger.log(Level.FINE,
-		       "{0} handleDeleteSyscallObserver no observers left\n",
-		       task);
-	    task.sendStop();
-	  }
-	return this;
-      }
 
       TaskState handleSyscalledEvent(Task task)
       {
@@ -1264,11 +1115,10 @@
 	{
 	    return "BlockedSignal,sig=" + sig;
 	}
-	TaskState handleAddObserver (Task task, Observable observable,
-				     Observer observer)
+	TaskState handleAddObservation(Task task, TaskObservation observation)
 	{
 	    logger.log (Level.FINE, "{0} handleAddObserver\n", task);
-	    observable.add (observer);
+	    observation.add();
 	    return this;
 	}
 	TaskState handleUnblock (Task task, TaskObserver observer)
@@ -1289,58 +1139,10 @@
 	      }
 	}
 	
-	TaskState handleAddSyscallObserver (Task task, Observable observable,
-					    Observer observer)
-          {
-	    logger.log (Level.FINE, "{0} handleAddSyscallObserver\n", task);
-	    if (task.syscallObservers.numberOfObservers() == 0)
-	      task.startTracingSyscalls();
-	    observable.add(observer);
-	    return this;
-  	  }
-
-	TaskState handleDeleteSyscallObserver(Task task,
-					      Observable observable,
-					      Observer observer)
-        {
-	  logger.log (Level.FINE, "{0} handleDeleteSyscallObserver\n", task);
-	  observable.delete(observer);
-	  if (task.syscallObservers.numberOfObservers() == 0)
-	    task.stopTracingSyscalls();
-	  return this;
-	}
-
-      TaskState handleAddCodeObserver(Task task, Observable observable,
-				      TaskObserver.Code observer,
-				      long address)
-      {
-	if (task.proc.breakpoints.addBreakpoint(observer, address))
-	  {
-	    Breakpoint breakpoint = Breakpoint.create(address, task.proc);
-	    breakpoint.install(task);
-	  }
-	observable.add(observer);
-	return this;
-      }
-
-      TaskState handleDeleteCodeObserver(Task task, Observable observable,
-					 TaskObserver.Code observer,
-					 long address)
-      {
-	if (task.proc.breakpoints.removeBreakpoint(observer, address))
-	  {
-	    Breakpoint breakpoint = Breakpoint.create(address, task.proc);
-	    breakpoint.remove(task);
-	  }
-	observable.delete(observer);
-	return this;
-      }
-      
-      TaskState handleDeleteObserver (Task task, Observable observable,
-                                      Observer observer)
+      TaskState handleDeleteObservation(Task task, TaskObservation observation)
       {
         logger.log (Level.FINE, "{0} handleDeleteObserver\n", task); 
-        observable.delete (observer);
+        observation.delete();
         return this;
       }
       
@@ -1448,21 +1250,23 @@
 		task.proc.performTaskAttachCompleted (task);
 		return destroyed;
 	    }
-	    TaskState handleAddObserver (Task task, Observable observable,
-					 Observer observer)
+	    TaskState handleAddObservation(Task task,
+					   TaskObservation observation)
 	    {
 		logger.log (Level.FINE, "{0} handleAddObserver\n", task);
+		Observable observable = observation.getTaskObservable();
+		Observer observer = observation.getTaskObserver();
 		observer.addFailed (task, new RuntimeException ("detached"));
 		task.proc.requestDeleteObserver (task,
 						 (TaskObservable) observable,
 						 (TaskObserver) observer);
 		return destroyed;
 	    }
-	    TaskState handleDeleteObserver (Task task, Observable observable,
-					    Observer observer)
+	    TaskState handleDeleteObservation(Task task,
+					      TaskObservation observation)
 	    {
 		logger.log (Level.FINE, "{0} handleDeleteObserver\n", task); 
-		observable.delete (observer);
+		observation.delete();
 		return destroyed;
 	    }
 	};
Index: frysk-core/frysk/proc/TaskSyscallObservation.java
===================================================================
RCS file: frysk-core/frysk/proc/TaskSyscallObservation.java
diff -N frysk-core/frysk/proc/TaskSyscallObservation.java
--- frysk-core/frysk/proc/TaskSyscallObservation.java	2 Oct 2006 15:52:18 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,72 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.proc;
-
-abstract class TaskSyscallObservation
-    extends TaskObservation
-{
-     /**
-     * Create a new SyscallObserver binding.
-     */
-    public TaskSyscallObservation (Task task, Observable observable,
-			    Observer observer)
-    {
-	    super(task, observable, observer);
-    }
-    /**
-     * Handle adding the SyscallObserver to the Observable.
-     */
-    public void handleAdd ()
-    {
-	task.handleAddSyscallObserver (observable, observer);
-    }
-    /**
-     * Handle deleting the SyscallObserver from the Observable.
-     */
-    public void handleDelete ()
-    {
-	task.handleDeleteSyscallObserver (observable, observer);
-    }
-    
-    public String toString()
-    {
-      return ("[TaskSyscallObservation Event]");
-    }
-}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]