}
public static GenResponseMessage call(final ActorRef actor, GenRequestMessage m, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException, SuspendExecution {
assert !actor.equals(ActorRef.self()) : "Can't \"call\" self - deadlock guaranteed";
final Actor currentActor;
if (m.getFrom() instanceof TempActor)
currentActor = ((TempActor<?>) m.getFrom()).actor.get();
else
currentActor = Actor.currentActor();
assert currentActor != null;
final Object watch = currentActor.watch(actor);
if (m.getId() == null)
m.setId(watch);
final Object id = m.getId();
final SelectiveReceiveHelper<Object> helper = new SelectiveReceiveHelper<Object>(currentActor) {
@Override
protected void handleLifecycleMessage(LifecycleMessage m) {
if (m instanceof ExitMessage) {
final ExitMessage exit = (ExitMessage) m;
if (Objects.equals(exit.getActor(), actor) && exit.getWatch() == watch)
throw Exceptions.rethrow(exit.getCause());
}
super.handleLifecycleMessage(m);
}
};
try {
actor.sendSync(m);
final GenResponseMessage response = (GenResponseMessage) helper.receive(timeout, unit, new MessageProcessor<Object, Object>() {
@Override
public Object process(Object m) throws SuspendExecution, InterruptedException {
return (m instanceof GenResponseMessage && id.equals(((GenResponseMessage) m).getId())) ? m : null;
}
});
currentActor.unwatch(actor, watch); // no need to unwatch in case of receiver death, so not doen in finally block
if (response instanceof GenErrorResponseMessage)
throw Exceptions.rethrow(((GenErrorResponseMessage) response).getError());
return response;
} finally {