mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
#1243 Updates USB tuner error handling to prevent stack overflow when tuner error occurs while streaming. (#1247)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
@@ -28,6 +28,7 @@ import io.github.dsheirer.source.tuner.TunerEvent.Event;
|
||||
import io.github.dsheirer.source.tuner.manager.ChannelSourceManager;
|
||||
import io.github.dsheirer.source.tuner.manager.HeterodyneChannelSourceManager;
|
||||
import io.github.dsheirer.source.tuner.manager.PolyphaseChannelSourceManager;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -44,6 +45,7 @@ public abstract class Tuner implements ISourceEventProcessor, ITunerErrorListene
|
||||
private TunerController mTunerController;
|
||||
private TunerFrequencyErrorMonitor mTunerFrequencyErrorMonitor;
|
||||
private ITunerErrorListener mTunerErrorListener;
|
||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||
|
||||
public Tuner(TunerController tunerController, ITunerErrorListener tunerErrorListener)
|
||||
{
|
||||
@@ -85,20 +87,25 @@ public abstract class Tuner implements ISourceEventProcessor, ITunerErrorListene
|
||||
*/
|
||||
public void start() throws SourceException
|
||||
{
|
||||
try
|
||||
if(mRunning.compareAndSet(false, true))
|
||||
{
|
||||
getTunerController().start();
|
||||
}
|
||||
catch(SourceException se)
|
||||
{
|
||||
//Rethrow the source exception
|
||||
throw se;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
//Wrap any other exceptions in a new source exception
|
||||
mLog.error("Error starting " + getTunerClass() + " tuner", e);
|
||||
throw new SourceException("Unable to start " + getTunerClass() + " tuner", e);
|
||||
try
|
||||
{
|
||||
getTunerController().start();
|
||||
}
|
||||
catch(SourceException se)
|
||||
{
|
||||
mRunning.set(false);
|
||||
//Rethrow the source exception
|
||||
throw se;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
mRunning.set(false);
|
||||
//Wrap any other exceptions in a new source exception
|
||||
mLog.error("Error starting " + getTunerClass() + " tuner", e);
|
||||
throw new SourceException("Unable to start " + getTunerClass() + " tuner", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,20 +114,24 @@ public abstract class Tuner implements ISourceEventProcessor, ITunerErrorListene
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
if(getChannelSourceManager() != null)
|
||||
if(mRunning.compareAndSet(true, false))
|
||||
{
|
||||
getChannelSourceManager().stopAllChannels();
|
||||
getChannelSourceManager().dispose();
|
||||
mChannelSourceManager = null;
|
||||
broadcast(new TunerEvent(this, Event.NOTIFICATION_SHUTTING_DOWN));
|
||||
|
||||
if(getChannelSourceManager() != null)
|
||||
{
|
||||
getChannelSourceManager().stopAllChannels();
|
||||
getChannelSourceManager().dispose();
|
||||
mChannelSourceManager = null;
|
||||
}
|
||||
|
||||
getTunerController().stop();
|
||||
getTunerController().dispose();
|
||||
|
||||
mTunerEventBroadcaster.clear();
|
||||
mTunerFrequencyErrorMonitor = null;
|
||||
mTunerErrorListener = null;
|
||||
}
|
||||
|
||||
broadcast(new TunerEvent(this, Event.NOTIFICATION_SHUTTING_DOWN));
|
||||
getTunerController().stop();
|
||||
getTunerController().dispose();
|
||||
|
||||
mTunerEventBroadcaster.clear();
|
||||
mTunerFrequencyErrorMonitor = null;
|
||||
mTunerErrorListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -172,10 +172,6 @@ public abstract class TunerChannelSource extends ComplexSource implements ISourc
|
||||
sourceEvent.setSource(this);
|
||||
broadcastProducerSourceEvent(sourceEvent);
|
||||
break;
|
||||
case NOTIFICATION_TUNER_SHUTDOWN:
|
||||
//Rebroadcast this event so the channel processing manager receives it and shuts down the channel
|
||||
broadcastConsumerSourceEvent(sourceEvent);
|
||||
break;
|
||||
//Request events from the consumer
|
||||
case REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE:
|
||||
setChannelFrequencyCorrection(sourceEvent.getValue().longValue());
|
||||
|
||||
@@ -25,8 +25,9 @@ import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Interface to define the functionality of a channel source manager for handling tuner channel management and source
|
||||
@@ -34,6 +35,8 @@ import java.util.SortedSet;
|
||||
*/
|
||||
public abstract class ChannelSourceManager implements ISourceEventProcessor
|
||||
{
|
||||
private Logger mLogger = LoggerFactory.getLogger(ChannelSourceManager.class);
|
||||
|
||||
private Broadcaster<SourceEvent> mSourceEventBroadcaster = new Broadcaster<>();
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
package io.github.dsheirer.source.tuner.manager;
|
||||
|
||||
import io.github.dsheirer.buffer.NativeSampleDelayBuffer;
|
||||
import io.github.dsheirer.controller.channel.event.ChannelStopProcessingRequest;
|
||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.source.SourceException;
|
||||
@@ -28,14 +30,13 @@ import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
|
||||
import io.github.dsheirer.source.tuner.channel.HalfBandTunerChannelSource;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Channel provider for heterodyne and decimate method of channel provisioning.
|
||||
@@ -68,14 +69,7 @@ public class HeterodyneChannelSourceManager extends ChannelSourceManager
|
||||
|
||||
for(TunerChannelSource tunerChannelSource: toStop)
|
||||
{
|
||||
try
|
||||
{
|
||||
tunerChannelSource.process(SourceEvent.tunerShutdown(tunerChannelSource));
|
||||
}
|
||||
catch(SourceException se)
|
||||
{
|
||||
mLog.error("Error stopping tuner channel source for tuner shutdown");
|
||||
}
|
||||
MyEventBus.getGlobalEventBus().post(new ChannelStopProcessingRequest(tunerChannelSource));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,8 +272,6 @@ public class HeterodyneChannelSourceManager extends ChannelSourceManager
|
||||
//The start sample stream request contains a start timestamp and the delay buffer
|
||||
//will preload the channel with delayed sample buffers that either contain the
|
||||
//timestamp or occur later/newer than the timestamp.
|
||||
// mSampleDelayBuffer.addListener((CICTunerChannelSource)sourceEvent.getSource(),
|
||||
// sourceEvent.getValue().longValue());
|
||||
mSampleDelayBuffer.addListener((HalfBandTunerChannelSource)sourceEvent.getSource(),
|
||||
sourceEvent.getValue().longValue());
|
||||
}
|
||||
@@ -287,7 +279,6 @@ public class HeterodyneChannelSourceManager extends ChannelSourceManager
|
||||
case REQUEST_STOP_SAMPLE_STREAM:
|
||||
if(sourceEvent.getSource() instanceof HalfBandTunerChannelSource)
|
||||
{
|
||||
// mSampleDelayBuffer.removeListener((CICTunerChannelSource)sourceEvent.getSource());
|
||||
mSampleDelayBuffer.removeListener((HalfBandTunerChannelSource)sourceEvent.getSource());
|
||||
stopDelayBuffer();
|
||||
}
|
||||
@@ -295,7 +286,6 @@ public class HeterodyneChannelSourceManager extends ChannelSourceManager
|
||||
case REQUEST_SOURCE_DISPOSE:
|
||||
if(sourceEvent.getSource() instanceof HalfBandTunerChannelSource)
|
||||
{
|
||||
// CICTunerChannelSource channelSource = (CICTunerChannelSource)sourceEvent.getSource();
|
||||
HalfBandTunerChannelSource channelSource = (HalfBandTunerChannelSource) sourceEvent.getSource();
|
||||
mChannelSources.remove(channelSource);
|
||||
mTunerChannels.remove(channelSource.getTunerChannel());
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package io.github.dsheirer.source.tuner.manager;
|
||||
|
||||
import io.github.dsheirer.controller.channel.event.ChannelStopProcessingRequest;
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.source.SourceException;
|
||||
@@ -27,14 +29,13 @@ import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
|
||||
import io.github.dsheirer.source.tuner.channel.PassThroughChannelSource;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Pass through source manager for relatively small bandwidth complex streams that don't warrant the overhead of
|
||||
@@ -62,14 +63,7 @@ public class PassThroughSourceManager extends ChannelSourceManager
|
||||
|
||||
for(TunerChannelSource tunerChannelSource: toStop)
|
||||
{
|
||||
try
|
||||
{
|
||||
tunerChannelSource.process(SourceEvent.tunerShutdown(tunerChannelSource));
|
||||
}
|
||||
catch(SourceException se)
|
||||
{
|
||||
mLog.error("Error stopping tuner channel source for tuner shutdown");
|
||||
}
|
||||
MyEventBus.getGlobalEventBus().post(new ChannelStopProcessingRequest(tunerChannelSource));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,14 +31,28 @@ import io.github.dsheirer.util.SwingUtils;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Spectral display manager for displaying tuner spectral content.
|
||||
*/
|
||||
public class TunerSpectralDisplayManager implements Listener<TunerEvent>
|
||||
{
|
||||
private Logger mLog = LoggerFactory.getLogger(TunerSpectralDisplayManager.class);
|
||||
|
||||
private SpectralDisplayPanel mSpectralDisplayPanel;
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private SettingsManager mSettingsManager;
|
||||
private DiscoveredTunerModel mDiscoveredTunerModel;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param panel to manage
|
||||
* @param playlistManager for channel updates
|
||||
* @param settingsManager for settings
|
||||
* @param discoveredTunerModel to access tuners
|
||||
*/
|
||||
public TunerSpectralDisplayManager(SpectralDisplayPanel panel, PlaylistManager playlistManager,
|
||||
SettingsManager settingsManager, DiscoveredTunerModel discoveredTunerModel)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user