001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.hbase.ipc;
020
021import org.apache.hbase.thirdparty.com.google.protobuf.RpcCallback;
022
023import java.io.IOException;
024import java.io.InterruptedIOException;
025
026import org.apache.yetus.audience.InterfaceAudience;
027
028/**
029 * Simple {@link RpcCallback} implementation providing a
030 * {@link java.util.concurrent.Future}-like {@link BlockingRpcCallback#get()} method, which
031 * will block util the instance's {@link BlockingRpcCallback#run(Object)} method has been called.
032 * {@code R} is the RPC response type that will be passed to the {@link #run(Object)} method.
033 */
034@InterfaceAudience.Private
035public class BlockingRpcCallback<R> implements RpcCallback<R> {
036  private R result;
037  private boolean resultSet = false;
038
039  /**
040   * Called on completion of the RPC call with the response object, or {@code null} in the case of
041   * an error.
042   * @param parameter the response object or {@code null} if an error occurred
043   */
044  @Override
045  public void run(R parameter) {
046    synchronized (this) {
047      result = parameter;
048      resultSet = true;
049      this.notifyAll();
050    }
051  }
052
053  /**
054   * Returns the parameter passed to {@link #run(Object)} or {@code null} if a null value was
055   * passed.  When used asynchronously, this method will block until the {@link #run(Object)}
056   * method has been called.
057   * @return the response object or {@code null} if no response was passed
058   */
059  public synchronized R get() throws IOException {
060    while (!resultSet) {
061      try {
062        this.wait();
063      } catch (InterruptedException ie) {
064        InterruptedIOException exception = new InterruptedIOException(ie.getMessage());
065        exception.initCause(ie);
066        throw exception;
067      }
068    }
069    return result;
070  }
071}