Skip to content
Snippets Groups Projects
Commit a0bef529 authored by Lyubomir Marinov's avatar Lyubomir Marinov
Browse files

Attempts to handle timeouts in Pa_CloseStream more gracefully.

parent 6d2ea096
No related branches found
No related tags found
No related merge requests found
...@@ -104,7 +104,6 @@ public void didPaUpdateAvailableDeviceList() ...@@ -104,7 +104,6 @@ public void didPaUpdateAvailableDeviceList()
if (deviceIndex != Pa.paNoDevice) if (deviceIndex != Pa.paNoDevice)
{ {
setDeviceIndex(deviceIndex); setDeviceIndex(deviceIndex);
if (start) if (start)
start(); start();
} }
...@@ -481,36 +480,81 @@ synchronized void setDeviceIndex(int deviceIndex) ...@@ -481,36 +480,81 @@ synchronized void setDeviceIndex(int deviceIndex)
if (stream != 0) if (stream != 0)
{ {
/*
* For the sake of completeness, attempt to stop this instance
* before disconnecting it.
*/
if (started)
{
try
{
stop();
}
catch (IOException ioe)
{
/*
* The exception should have already been logged by the
* method #stop(). Additionally and as said above, we
* attempted it out of courtesy.
*/
}
}
boolean closed = false;
try try
{ {
Pa.CloseStream(stream); Pa.CloseStream(stream);
closed = true;
} }
catch (PortAudioException paex) catch (PortAudioException pae)
{ {
logger.error( /*
"Failed to close " + getClass().getSimpleName(), * The function Pa_CloseStream is not supposed to time out
paex); * under normal execution. However, we have modified it to
* do so under exceptional circumstances on Windows at least
* in order to overcome endless loops related to
* hotplugging. In such a case, presume the native PortAudio
* stream closed in order to maybe avoid a crash at the risk
* of a memory leak.
*/
if (pae.getErrorCode() == Pa.paTimedOut)
closed = true;
if (!closed)
{
logger.error(
"Failed to close " + getClass().getSimpleName(),
pae);
IOException ioex IOException ioe
= new IOException(paex.getLocalizedMessage()); = new IOException(pae.getLocalizedMessage());
ioex.initCause(paex); ioe.initCause(pae);
throw ioex; throw ioe;
}
} }
stream = 0; finally
if (inputParameters != 0)
{ {
Pa.StreamParameters_free(inputParameters); if (closed)
inputParameters = 0; {
} stream = 0;
/* if (inputParameters != 0)
* Make sure this AbstractPullBufferStream asks its DataSource {
* for the Format in which it is supposed to output audio data Pa.StreamParameters_free(inputParameters);
* next time it's opened instead of using its Format from a inputParameters = 0;
* previous open. }
*/
this.format = null; /*
* Make sure this AbstractPullBufferStream asks its
* DataSource for the Format in which it is supposed to
* output audio data the next time it is opened instead
* of using its Format from a previous open.
*/
this.format = null;
}
}
} }
} }
this.deviceIndex = deviceIndex; this.deviceIndex = deviceIndex;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment