// // MessagePack-RPC for Java // // Copyright (C) 2010 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package org.msgpack.rpc; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.msgpack.type.Value; import org.msgpack.type.ValueFactory; class FutureImpl { private Session session; private Runnable callback = null; private Object lock = new Object(); private int timeout; private volatile boolean done = false; private Value result; private Value error; FutureImpl(Session session) { this.session = session; this.timeout = session.getRequestTimeout(); } void attachCallback(Runnable callback) { boolean was_already_done; synchronized (lock) { was_already_done = done; if (!done) { this.callback = callback; } } if (was_already_done) { session.getEventLoop().getWorkerExecutor().submit(callback); } } void join() throws InterruptedException { synchronized (lock) { while (done == false) { lock.wait(); } } } void join(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException { long end_time = System.currentTimeMillis() + unit.toMillis(timeout); boolean run_callback = false; synchronized (lock) { while (done == false) { long timeout_remaining = end_time - System.currentTimeMillis(); if (timeout_remaining <= 0) break; lock.wait(timeout_remaining); } if (!done) { this.error = ValueFactory.createRawValue("timedout"); done = true; lock.notifyAll(); run_callback = true; } } if (run_callback && callback != null) { // FIXME #SF submit? // session.getEventLoop().getWorkerExecutor().submit(callback); callback.run(); } } public boolean isDone() { return done; } public Value getResult() { return result; } public Value getError() { return error; } public void setResult(Value result, Value error) { synchronized (lock) { if (done) { return; } this.result = result; this.error = error; this.done = true; lock.notifyAll(); } if (callback != null) { // FIXME #SF submit? // session.getEventLoop().getWorkerExecutor().submit(callback); callback.run(); } } boolean stepTimeout() { if (timeout <= 0) { return true; } else { timeout--; return false; } } }