]> git.basschouten.com Git - openhab-addons.git/blob
6bedf4c81905c7b46c98071f885ce60215ee9ef6
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.io.transport.modbus.internal;
14
15 import java.util.function.Consumer;
16 import java.util.function.Supplier;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.io.transport.modbus.internal.ModbusManagerImpl.PollTaskUnregistered;
20
21 import net.wimpi.modbus.ModbusException;
22
23 /**
24  * Implementation of simple stop watch.
25  *
26  * @author Sami Salonen - initial contribution
27  *
28  */
29 @NonNullByDefault
30 public class SimpleStopWatch {
31
32     private volatile long totalMillis;
33     private volatile long resumed;
34
35     @FunctionalInterface
36     public abstract interface SupplierWithPollTaskUnregisteredException<T> {
37         public abstract T get() throws ModbusManagerImpl.PollTaskUnregistered;
38     }
39
40     @FunctionalInterface
41     public abstract interface RunnableWithModbusException {
42         public abstract void run() throws ModbusException;
43     }
44
45     /**
46      * Resume or start the stop watch
47      *
48      * @throws IllegalStateException if stop watch is running already
49      */
50     public synchronized void resume() {
51         if (isRunning()) {
52             throw new IllegalStateException("Cannot suspend a running StopWatch");
53         }
54         resumed = System.currentTimeMillis();
55     }
56
57     /**
58      * Suspend the stop watch
59      *
60      * @throws IllegalStateException if stop watch has not been resumed
61      */
62     public synchronized void suspend() {
63         if (!isRunning()) {
64             throw new IllegalStateException("Cannot suspend non-running StopWatch");
65         }
66         totalMillis += System.currentTimeMillis() - resumed;
67         resumed = 0;
68     }
69
70     /**
71      * Get total running time of this StopWatch in milliseconds
72      *
73      * @return total running time in milliseconds
74      */
75     public synchronized long getTotalTimeMillis() {
76         return totalMillis;
77     }
78
79     /**
80      * Tells whether this StopWatch is now running
81      *
82      * @return boolean telling whether this StopWatch is running
83      */
84     public synchronized boolean isRunning() {
85         return resumed > 0;
86     }
87
88     /**
89      * Time single action using this StopWatch
90      *
91      * First StopWatch is resumed, then action is applied. Finally the StopWatch is suspended.
92      *
93      * @param supplier action to time
94      * @return return value from supplier
95      * @throws PollTaskUnregistered when original supplier throws the exception
96      */
97     public <R> R timeSupplierWithPollTaskUnregisteredException(SupplierWithPollTaskUnregisteredException<R> supplier)
98             throws PollTaskUnregistered {
99         try {
100             this.resume();
101             return supplier.get();
102         } finally {
103             this.suspend();
104         }
105     }
106
107     /**
108      * Time single action using this StopWatch
109      *
110      * First StopWatch is resumed, then action is applied. Finally the StopWatch is suspended.
111      *
112      * @param supplier action to time
113      * @return return value from supplier
114      */
115     public <R> R timeSupplier(Supplier<R> supplier) {
116         try {
117             this.resume();
118             return supplier.get();
119         } finally {
120             this.suspend();
121         }
122     }
123
124     /**
125      * Time single action using this StopWatch
126      *
127      * First StopWatch is resumed, then action is applied. Finally the StopWatch is suspended.
128      *
129      * @param action action to time
130      * @throws ModbusException when original action throws the exception
131      */
132     public void timeRunnableWithModbusException(RunnableWithModbusException action) throws ModbusException {
133         try {
134             this.resume();
135             action.run();
136         } finally {
137             this.suspend();
138         }
139     }
140
141     /**
142      * Time single action using this StopWatch
143      *
144      * First StopWatch is resumed, then action is applied. Finally the StopWatch is suspended.
145      *
146      * @param supplier action to time
147      * @return return value from supplier
148      */
149     public void timeRunnable(Runnable runnable) {
150         try {
151             this.resume();
152             runnable.run();
153         } finally {
154             this.suspend();
155         }
156     }
157
158     /**
159      * Time single action using this StopWatch
160      *
161      * First StopWatch is resumed, then action is applied. Finally the StopWatch is suspended.
162      *
163      * @param consumer action to time
164      * @return return value from supplier
165      */
166     public <T> void timeConsumer(Consumer<T> consumer, T parameter) {
167         try {
168             this.resume();
169             consumer.accept(parameter);
170         } finally {
171             this.suspend();
172         }
173     }
174 }