[e-cvs] cvs commit: e/src/jsrc/org/erights/e/elib/ref BufferingRef.java Ref.java SwitchableRef.java

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Wed, 18 Jul 2001 16:54:34 -0400


markm       01/07/18 16:54:34

  Modified:    src/jsrc/org/erights/e/elib/prim E.java
               src/jsrc/org/erights/e/elib/ref BufferingRef.java Ref.java
                        SwitchableRef.java
  Log:
  Updocing Epimenides revealed an awful bug that's now fixed

Revision  Changes    Path
1.54      +5 -5      e/src/jsrc/org/erights/e/elib/prim/E.java

Index: E.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/E.java,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- E.java	2001/07/08 02:13:04	1.53
+++ E.java	2001/07/18 20:54:34	1.54
@@ -394,7 +394,7 @@
      * @see #sendAllOnly(Object, String, Object[])
      */
     static public void sendOnly(Object rec, String verb) {
-        sendAll(rec, null, verb, NO_ARGS);
+        sendAllOnly(rec, verb, NO_ARGS);
     }
     
     /**
@@ -406,7 +406,7 @@
                                 Object arg1)
     {
         Object[] args = { arg1 };
-        sendAll(rec, null, verb, args);
+        sendAllOnly(rec, verb, args);
     }
     
     /**
@@ -419,7 +419,7 @@
                                 Object arg2)
     {
         Object[] args = { arg1, arg2 };
-        sendAll(rec, null, verb, args);
+        sendAllOnly(rec, verb, args);
     }
     
     /**
@@ -433,7 +433,7 @@
                                 Object arg3)
     {
         Object[] args = { arg1, arg2, arg3 };
-        sendAll(rec, null, verb, args);
+        sendAllOnly(rec, verb, args);
     }
 
     /**
@@ -448,7 +448,7 @@
                                 Object arg4)
     {
         Object[] args = { arg1, arg2, arg3, arg4 };
-        sendAll(rec, null, verb, args);
+        sendAllOnly(rec, verb, args);
     }
 
     /**



1.3       +23 -7     e/src/jsrc/org/erights/e/elib/ref/BufferingRef.java

Index: BufferingRef.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/ref/BufferingRef.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BufferingRef.java	2000/11/14 11:15:33	1.2
+++ BufferingRef.java	2001/07/18 20:54:34	1.3
@@ -83,6 +83,18 @@
     }
 
     /**
+     * 
+     */
+    /*package*/ void sendMsg(Message msg) {
+        FlexList optMsgs = (FlexList)myBuf.get();
+        if (null == optMsgs) {
+            return;
+        } else {
+            optMsgs.push(msg);
+        }
+    }
+
+    /**
      * Stores the message
      *
      * @return a promise for the result
@@ -91,7 +103,7 @@
         FlexList optMsgs = (FlexList)myBuf.get();
         if (null == optMsgs) {
             return this; //since I'm now a perfectly good black hole
-            //Perhaps we should return a specialized BlackHoleRef, but
+            //Perhaps we should return a specialized BlackHoleRef.  But
             //there's no way to make this useful without exposing the
             //non-determinism.
         } else {
@@ -138,14 +150,18 @@
     /**
      * Asyncronously send all the messages accumulated so far to the target,
      * forget them (so future deliverAll()s won't send them), and return the
-     * count of how many messages this is.  This is used as if it was a
-     * method of self as a resolver.
+     * count of how many messages this is.
      */
-    static int deliverAll(FlexList self, Object target) {
-        Message[] msgs = (Message[])self.getArray(Message.class);
-        self.setSize(0);
+    static int deliverAll(FlexList buf, Object target) {
+        Message[] msgs = (Message[])buf.getArray(Message.class);
+        buf.setSize(0);
+        Ref targRef = Ref.toRef(target);
         for (int i = 0; i < msgs.length; i++) {
-            E.sendMsg(target, msgs[i]);
+            //Using Ref.sendMsg/1 rather than E.sendMsg/2 is necessary to 
+            //avoid an infinite regress in resolve/1 (as demonstrated by 
+            //Epimenides), by preserving the original Resolver.  Besides, 
+            //it's also a nice optimization.
+            targRef.sendMsg(msgs[i]);
         }
         return msgs.length;
     }



1.16      +20 -0     e/src/jsrc/org/erights/e/elib/ref/Ref.java

Index: Ref.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/ref/Ref.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Ref.java	2001/05/03 06:07:50	1.15
+++ Ref.java	2001/07/18 20:54:34	1.16
@@ -620,6 +620,26 @@
     public abstract Object callAll(String verb, Object[] args);
 
     /**
+     * Needed to break an infinite recursion on resolve/1. <p>
+     *
+     * To the client, this has the same semantics as E.sendMsg/2, and the 
+     * default implementation here in Ref just delegates to E.sendMsg/2.  
+     * However, those subclasses that could be involved in the infinite 
+     * recursion that would be demonstrated by <a href=
+     * "http://www.erights.org/elang/concurrency/epimenides.html"
+     * >Epimenides Paradox</a> must instead override this method to preseve 
+     * and pass through the Resolver.  The easiest way to do this is to reuse 
+     * the Message, which also makes this whole thing a nice optimization. <p>
+     *
+     * This is package scope, since only trusted code is assumed to not 
+     * resuse a Resolver so as to break distributed transparency.  (This 
+     * safeguard isn't crucial, and isn't even a big deal, but is nice.)
+     */
+    /*package*/ void sendMsg(Message msg) {
+        E.sendMsg(this, msg);
+    }
+    
+    /**
      * Use E.sendAll(obj, verb, args) rather than obj.sendAll(verb, args).
      */
     public abstract Ref sendAll(String verb, Object[] args);



1.3       +9 -0      e/src/jsrc/org/erights/e/elib/ref/SwitchableRef.java

Index: SwitchableRef.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/ref/SwitchableRef.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SwitchableRef.java	2000/11/14 11:15:34	1.2
+++ SwitchableRef.java	2001/07/18 20:54:34	1.3
@@ -20,6 +20,7 @@
 */
 
 import org.erights.e.elib.prim.E;
+import org.erights.e.elib.prim.Message;
 
 /**
  * All message asyncronously delivered to a SwitchableRef will be forwarded 
@@ -101,6 +102,14 @@
         }
     }
 
+    /**
+     * Override to pass the Message through to the resolved target.
+     */
+    /*package*/ void sendMsg(Message msg) {
+        resolutionRef();
+        myTarget.sendMsg(msg);
+    }
+    
     /**
      * 
      */