ResultSyncPoint.java

  1. /**
  2.  *
  3.  * Copyright 2015-2024 Florian Schmaus
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.igniterealtime.smack.inttest.util;

  18. import java.util.concurrent.TimeoutException;

  19. import org.jivesoftware.smack.util.Objects;

  20. public class ResultSyncPoint<R, E extends Exception> {

  21.     private R result;
  22.     private E exception;

  23.     public R waitForResult(long timeout) throws E, InterruptedException, TimeoutException {
  24.         return waitForResult(timeout, null);
  25.     }

  26.     public R waitForResult(long timeout, String timeoutMessage) throws E, InterruptedException, TimeoutException {
  27.         synchronized (this) {
  28.             if (result != null) {
  29.                 return result;
  30.             }
  31.             if (exception != null) {
  32.                 throw exception;
  33.             }
  34.             final long deadline = System.currentTimeMillis() + timeout;
  35.             while (result == null && exception == null) {
  36.                 final long now = System.currentTimeMillis();
  37.                 if (now >= deadline) break;
  38.                 wait(deadline - now);
  39.             }
  40.         }
  41.         if (result != null) {
  42.             return result;
  43.         }
  44.         if (exception != null) {
  45.             throw exception;
  46.         }

  47.         String message = "Timeout after " + timeout + "ms";
  48.         if (timeoutMessage != null) {
  49.             message += ": " + timeoutMessage;
  50.         }
  51.         throw new TimeoutException(message);
  52.     }


  53.     public void signal(R result) {
  54.         synchronized (this) {
  55.             this.result = Objects.requireNonNull(result);
  56.             notifyAll();
  57.         }
  58.     }

  59.     public void signal(E exception) {
  60.         synchronized (this) {
  61.             this.exception = Objects.requireNonNull(exception);
  62.             notifyAll();
  63.         }
  64.     }
  65. }