Skip to content

Commit

Permalink
pulseaudio: Add function to handle Pulseaudio pa_operation
Browse files Browse the repository at this point in the history
Now pa_operation are handled multiple ways. Add function to make
sure that they are handled always same.
  • Loading branch information
illuusio committed Jun 25, 2024
1 parent 18a606e commit c381e43
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 76 deletions.
40 changes: 11 additions & 29 deletions src/hostapi/pulseaudio/pa_linux_pulseaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,13 @@
*/


#include <string.h> /* strlen() */

#include "pa_linux_pulseaudio_cb_internal.h"
#include "pa_linux_pulseaudio_block_internal.h"

/* PulseAudio headers */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pulse/pulseaudio.h>

/* This is used to identify process name for PulseAudio. */
Expand Down Expand Up @@ -650,12 +649,8 @@ PaError PaPulseAudio_Initialize( PaUtilHostApiRepresentation ** hostApi,
PaPulseAudio_ServerInfoCb,
pulseaudioHostApi );

while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING )
{
pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop );
}

pa_operation_unref( pulseaudioOperation );
PaPulseAudio_ReleaseOperation( pulseaudioHostApi,
&pulseaudioOperation );

/* Add the "Default" sink at index 0 */
if( _PaPulseAudio_AddAudioDevice( pulseaudioHostApi,
Expand Down Expand Up @@ -701,25 +696,17 @@ PaError PaPulseAudio_Initialize( PaUtilHostApiRepresentation ** hostApi,
PaPulseAudio_SinkListCb,
pulseaudioHostApi );

while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING )
{
pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop );
}

pa_operation_unref( pulseaudioOperation );
PaPulseAudio_ReleaseOperation( pulseaudioHostApi,
&pulseaudioOperation );

/* List PulseAudio sources. If found callback: PaPulseAudio_SourceListCb */
pulseaudioOperation =
pa_context_get_source_info_list( pulseaudioHostApi->context,
PaPulseAudio_SourceListCb,
pulseaudioHostApi );

while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING )
{
pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop );
}

pa_operation_unref( pulseaudioOperation );
PaPulseAudio_ReleaseOperation( pulseaudioHostApi,
&pulseaudioOperation );

(*hostApi)->info.deviceCount = pulseaudioHostApi->deviceCount;

Expand Down Expand Up @@ -1461,11 +1448,8 @@ PaError PaPulseAudio_RenameSource( PaStream *s, const char *streamName )
op = pa_stream_set_name( stream->inputStream, streamName, RenameStreamCb, stream );
PaPulseAudio_UnLock( stream->mainloop );

/* Wait for completion. */
while (pa_operation_get_state( op ) == PA_OPERATION_RUNNING)
{
pa_threaded_mainloop_wait( stream->mainloop );
}
PaPulseAudio_ReleaseOperation( stream->hostapi,
&op );

return result;
}
Expand Down Expand Up @@ -1498,10 +1482,8 @@ PaError PaPulseAudio_RenameSink( PaStream *s, const char *streamName )
PaPulseAudio_UnLock( stream->mainloop );

/* Wait for completion. */
while (pa_operation_get_state( op ) == PA_OPERATION_RUNNING)
{
pa_threaded_mainloop_wait( stream->mainloop );
}
PaPulseAudio_ReleaseOperation( stream->hostapi,
&op );

return result;
}
81 changes: 37 additions & 44 deletions src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,34 @@ int PaPulseAudio_updateTimeInfo( pa_stream * s,
return 0;
}

/* Release pa_operation always same way */
int PaPulseAudio_ReleaseOperation(PaPulseAudio_HostApiRepresentation *hostapi,
pa_operation **operation)
{
unsigned int wait = 0;
pa_operation *localOperation = (*operation);

while( pa_operation_get_state( localOperation ) == PA_OPERATION_RUNNING )
{
pa_threaded_mainloop_wait( hostapi->mainloop );

wait ++;
usleep( 1000 );

if( wait > 2000 )
{
PA_DEBUG( ( "Portaudio %s: Operation still running %d!\n",
__FUNCTION__, pa_operation_get_state( localOperation ) ) );
break;
}
}

PaPulseAudio_Lock( hostapi->mainloop );
pa_operation_unref( localOperation );
operation = NULL;
PaPulseAudio_UnLock( hostapi->mainloop );
}


/* locks the Pulse Main loop when not called from it */
void PaPulseAudio_Lock( pa_threaded_mainloop *mainloop )
Expand Down Expand Up @@ -488,22 +516,10 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
stream );
PaPulseAudio_UnLock( stream->mainloop );

while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING )
{
pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop );
waitLoop ++;

if(waitLoop > 256)
{
break;
}
}

waitLoop = 0;
PaPulseAudio_ReleaseOperation( pulseaudioHostApi,
&pulseaudioOperation );

PaPulseAudio_Lock(stream->mainloop);
pa_operation_unref( pulseaudioOperation );
pulseaudioOperation = NULL;

pa_stream_disconnect( stream->outputStream );
PaPulseAudio_UnLock( stream->mainloop );
Expand All @@ -520,22 +536,10 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
stream );
PaPulseAudio_UnLock( stream->mainloop );

while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING )
{
pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop );
waitLoop ++;

if(waitLoop > 256)
{
break;
}
}

waitLoop = 0;
PaPulseAudio_ReleaseOperation( pulseaudioHostApi,
&pulseaudioOperation );

PaPulseAudio_Lock( stream->mainloop );
pa_operation_unref( pulseaudioOperation );
pulseaudioOperation = NULL;

/* Then we disconnect stream and wait for
* Termination
Expand Down Expand Up @@ -641,7 +645,6 @@ PaError PaPulseAudio_StartStreamCb( PaStream * s )
PaPulseAudio_HostApiRepresentation *pulseaudioHostApi = stream->hostapi;
const char *pulseaudioName = NULL;
pa_operation *pulseaudioOperation = NULL;
int waitLoop = 0;
unsigned int pulseaudioReqFrameSize = stream->suggestedLatencyUSecs;

stream->isActive = 0;
Expand Down Expand Up @@ -769,13 +772,8 @@ PaError PaPulseAudio_StartStreamCb( PaStream * s )
stream );
PaPulseAudio_UnLock( pulseaudioHostApi->mainloop );

while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING)
{
pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop );
}

pa_operation_unref( pulseaudioOperation );
pulseaudioOperation = NULL;
PaPulseAudio_ReleaseOperation( pulseaudioHostApi,
&pulseaudioOperation );
}
else
{
Expand Down Expand Up @@ -897,6 +895,7 @@ static PaError RequestStop( PaPulseAudio_Stream * stream,
PaError ret = paNoError;
PaPulseAudio_HostApiRepresentation *pulseaudioHostApi = stream->hostapi;
pa_operation *pulseaudioOperation = NULL;
int waitLoop = 0;

PaPulseAudio_Lock( pulseaudioHostApi->mainloop );

Expand All @@ -919,14 +918,8 @@ static PaError RequestStop( PaPulseAudio_Stream * stream,
PaPulseAudio_CorkSuccessCb,
stream );

while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING )
{
pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop );
}

pa_operation_unref( pulseaudioOperation );

pulseaudioOperation = NULL;
PaPulseAudio_ReleaseOperation( pulseaudioHostApi,
&pulseaudioOperation );
}

requeststop_error:
Expand Down
8 changes: 5 additions & 3 deletions src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,14 @@ PaPulseAudio_Stream;
return errorCode; \
} \
} \
if( !pastream->isActive || pastream->isStopped ) \
if( !(pastream)->isActive || (pastream)->isStopped ) \
{ \
return paStreamIsStopped; \
return paStreamIsStopped; \
}

int PaPulseAudio_ReleaseOperation(PaPulseAudio_HostApiRepresentation *hostapi,
pa_operation **pulseaudioOperation);

void PaPulseAudio_Lock( pa_threaded_mainloop *mainloop );

void PaPulseAudio_UnLock( pa_threaded_mainloop *mainloop );
Expand All @@ -225,7 +228,6 @@ PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
PaStreamCallback * streamCallback,
void *userData );


PaError IsStreamStopped( PaStream * s );
PaError IsStreamActive( PaStream * stream );

Expand Down

0 comments on commit c381e43

Please sign in to comment.