[audio] audio servlet: don't change map while used by interation (#801)

We should not remove entries (so keys) from the map while we are using
the key set (a view) of that map (see JavaDoc: otherwise "results of the
iteration undefined").

Signed-off-by: Markus Rathgeb <maggu2810@gmail.com>
pull/796/head
Markus Rathgeb 2019-05-07 21:26:04 +02:00 committed by Christoph Weitkamp
parent 81423aa22e
commit d19ee33be9
1 changed files with 15 additions and 8 deletions

View File

@ -15,7 +15,10 @@ package org.eclipse.smarthome.core.audio.internal;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@ -143,16 +146,20 @@ public class AudioServlet extends SmartHomeServlet implements AudioHTTPServer {
}
private synchronized void removeTimedOutStreams() {
for (String streamId : multiTimeStreams.keySet()) {
if (streamTimeouts.get(streamId) < System.nanoTime()) {
// the stream has expired, we need to remove it!
FixedLengthAudioStream stream = multiTimeStreams.remove(streamId);
streamTimeouts.remove(streamId);
IOUtils.closeQuietly(stream);
stream = null;
logger.debug("Removed timed out stream {}", streamId);
// Build list of expired streams.
final List<String> toRemove = new LinkedList<>();
for (Entry<String, Long> entry : streamTimeouts.entrySet()) {
if (entry.getValue() < System.nanoTime()) {
toRemove.add(entry.getKey());
}
}
toRemove.forEach(streamId -> {
// the stream has expired, we need to remove it!
final FixedLengthAudioStream stream = multiTimeStreams.remove(streamId);
streamTimeouts.remove(streamId);
IOUtils.closeQuietly(stream);
logger.debug("Removed timed out stream {}", streamId);
});
}
@Override