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 */
018package org.apache.hadoop.hbase.ipc;
019
020import java.io.IOException;
021import java.io.InterruptedIOException;
022import org.apache.yetus.audience.InterfaceAudience;
023
024import org.apache.hbase.thirdparty.com.google.protobuf.RpcCallback;
025
026/**
027 * Simple {@link RpcCallback} implementation providing a {@link java.util.concurrent.Future}-like
028 * {@link BlockingRpcCallback#get()} method, which will block util the instance's
029 * {@link BlockingRpcCallback#run(Object)} method has been called. {@code R} is the RPC response
030 * type that will be passed to the {@link #run(Object)} method.
031 */
032@InterfaceAudience.Private
033public class BlockingRpcCallback<R> implements RpcCallback<R> {
034  private R result;
035  private boolean resultSet = false;
036
037  /**
038   * Called on completion of the RPC call with the response object, or {@code null} in the case of
039   * an error.
040   * @param parameter the response object or {@code null} if an error occurred
041   */
042  @Override
043  public void run(R parameter) {
044    synchronized (this) {
045      result = parameter;
046      resultSet = true;
047      this.notifyAll();
048    }
049  }
050
051  /**
052   * Returns the parameter passed to {@link #run(Object)} or {@code null} if a null value was
053   * passed. When used asynchronously, this method will block until the {@link #run(Object)} method
054   * has been called.
055   * @return the response object or {@code null} if no response was passed
056   */
057  public synchronized R get() throws IOException {
058    while (!resultSet) {
059      try {
060        this.wait();
061      } catch (InterruptedException ie) {
062        InterruptedIOException exception = new InterruptedIOException(ie.getMessage());
063        exception.initCause(ie);
064        throw exception;
065      }
066    }
067    return result;
068  }
069}