ETuple2 t2;
EPortControl ctrl;
ETuple3 t3;
ETuple4 t4;
ETuple tup;
if ((t2 = ETuple2.cast(msg)) != null) {
EObject sender = t2.elem1;
ETuple2 cmd;
if ((cmd = ETuple2.cast(t2.elem2)) != null) {
// cmd must be one of
// {command, iodata()}
// {connect, PID}
if (cmd.elem1 == EPort.am_command) {
if (cmd.elem2.collectIOList(out)) {
EHandle caller = sender.testHandle();
if (caller == null) {
log.warning("*** sender is null? "+sender);
}
if (out.size() == 0) {
instance.outputv(caller, ERT.EMPTY_BYTEBUFFER_ARR);
} else {
instance.outputv(caller, out.toArray(new ByteBuffer[out
.size()]));
}
// if collectIOList fails, do the port task die?
// and how?
}
out.clear();
continue next_message;
} else if (cmd.elem1 == EPort.am_connect) {
EPID new_owner;
if ((new_owner = cmd.elem2.testPID()) == null)
break;
EPID old_owner = this.owner;
this.owner = new_owner;
old_owner.send(this.port, ETuple.make(this.self_handle(),
EPort.am_connected));
continue next_message;
}
} else if (t2.elem2 == am_close) {
this.reply_closed_to = t2.elem1.testPID();
// will call instance.stop()
return;
}
} else if ((ctrl = msg.testPortControl()) != null) {
// port control messages are simply run
ctrl.execute();
continue next_message;
} else if ((t3 = ETuple3.cast(msg)) != null) {
// {'EXIT', From, Reason} comes in this way
if (t3.elem1 == ERT.am_EXIT) {
// close is handled by exception handling code
return;
}
} else if ((tup = msg.testTuple()) != null && tup.arity() == 5) {
// {'DOWN', ref, process, pid, reason}
if (tup.elm(1) == ERT.am_DOWN) {
ERef ref = tup.elm(2).testReference();
instance.processExit(ref);
}
}