[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);
+ }
+
/**
*
*/