TimeoutOutputStream.java

  1. /*
  2.  * Copyright (C) 2009, 2013 Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.util.io;

  11. import java.io.IOException;
  12. import java.io.InterruptedIOException;
  13. import java.io.OutputStream;
  14. import java.text.MessageFormat;

  15. import org.eclipse.jgit.internal.JGitText;

  16. /**
  17.  * OutputStream with a configurable timeout.
  18.  */
  19. public class TimeoutOutputStream extends OutputStream {
  20.     private final OutputStream dst;

  21.     private final InterruptTimer myTimer;

  22.     private int timeout;

  23.     /**
  24.      * Wrap an output stream with a timeout on all write operations.
  25.      *
  26.      * @param destination
  27.      *            base input stream (to write to). The stream must be
  28.      *            interruptible (most socket streams are).
  29.      * @param timer
  30.      *            timer to manage the timeouts during writes.
  31.      */
  32.     public TimeoutOutputStream(final OutputStream destination,
  33.             final InterruptTimer timer) {
  34.         dst = destination;
  35.         myTimer = timer;
  36.     }

  37.     /**
  38.      * Get number of milliseconds before aborting a write.
  39.      *
  40.      * @return number of milliseconds before aborting a write.
  41.      */
  42.     public int getTimeout() {
  43.         return timeout;
  44.     }

  45.     /**
  46.      * Set number of milliseconds before aborting a write.
  47.      *
  48.      * @param millis
  49.      *            number of milliseconds before aborting a write. Must be >
  50.      *            0.
  51.      */
  52.     public void setTimeout(int millis) {
  53.         if (millis < 0)
  54.             throw new IllegalArgumentException(MessageFormat.format(
  55.                     JGitText.get().invalidTimeout, Integer.valueOf(millis)));
  56.         timeout = millis;
  57.     }

  58.     /** {@inheritDoc} */
  59.     @Override
  60.     public void write(int b) throws IOException {
  61.         try {
  62.             beginWrite();
  63.             dst.write(b);
  64.         } catch (InterruptedIOException e) {
  65.             throw writeTimedOut(e);
  66.         } finally {
  67.             endWrite();
  68.         }
  69.     }

  70.     /** {@inheritDoc} */
  71.     @Override
  72.     public void write(byte[] buf) throws IOException {
  73.         write(buf, 0, buf.length);
  74.     }

  75.     /** {@inheritDoc} */
  76.     @Override
  77.     public void write(byte[] buf, int off, int len) throws IOException {
  78.         try {
  79.             beginWrite();
  80.             dst.write(buf, off, len);
  81.         } catch (InterruptedIOException e) {
  82.             throw writeTimedOut(e);
  83.         } finally {
  84.             endWrite();
  85.         }
  86.     }

  87.     /** {@inheritDoc} */
  88.     @Override
  89.     public void flush() throws IOException {
  90.         try {
  91.             beginWrite();
  92.             dst.flush();
  93.         } catch (InterruptedIOException e) {
  94.             throw writeTimedOut(e);
  95.         } finally {
  96.             endWrite();
  97.         }
  98.     }

  99.     /** {@inheritDoc} */
  100.     @Override
  101.     public void close() throws IOException {
  102.         try {
  103.             beginWrite();
  104.             dst.close();
  105.         } catch (InterruptedIOException e) {
  106.             throw writeTimedOut(e);
  107.         } finally {
  108.             endWrite();
  109.         }
  110.     }

  111.     private void beginWrite() {
  112.         myTimer.begin(timeout);
  113.     }

  114.     private void endWrite() {
  115.         myTimer.end();
  116.     }

  117.     private InterruptedIOException writeTimedOut(InterruptedIOException cause) {
  118.         InterruptedIOException e = new InterruptedIOException(
  119.                 MessageFormat.format(JGitText.get().writeTimedOut,
  120.                         Integer.valueOf(timeout)));
  121.         e.initCause(cause);
  122.         return e;
  123.     }
  124. }