]> Repos - portaudio/commitdiff
oss: fixed compile for systems missing 'pthread_cancel' series of functions, this...
authordmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Sun, 6 Jun 2010 17:36:33 +0000 (17:36 +0000)
committerdmitrykos <dmitrykos@0f58301d-fd10-0410-b4af-bbb618454e57>
Sun, 6 Jun 2010 17:36:33 +0000 (17:36 +0000)
src/hostapi/oss/pa_unix_oss.c
src/os/unix/pa_unix_util.c

index 225c028d8265cb68f327848e0335342ca9c1176a..e51201b5cc16edeff56d3e2a77daf84c9c5927fd 100644 (file)
@@ -185,7 +185,7 @@ typedef struct PaOssStream
     double sampleRate;
 
     int callbackMode;
-    int callbackStop, callbackAbort;
+    volatile int callbackStop, callbackAbort;
 
     PaOssStreamComponent *capture, *playback;
     unsigned long pollTimeout;
@@ -1317,7 +1317,17 @@ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *fr
 
     while( pollPlayback || pollCapture )
     {
+#ifdef PTHREAD_CANCELED
         pthread_testcancel();
+#else
+        /* avoid indefinite waiting on thread not supporting cancelation */
+        if( stream->callbackStop || stream->callbackAbort )
+        {
+            PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" ));
+            (*frames) = 0;
+            return paNoError;
+        }
+#endif
 
         /* select may modify the timeout parameter */
         selectTimeval.tv_usec = timeout;
@@ -1341,8 +1351,17 @@ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *fr
             ENSURE_( -1, paUnanticipatedHostError );
         }
         */
+#ifdef PTHREAD_CANCELED
         pthread_testcancel();
-
+#else
+        /* avoid indefinite waiting on thread not supporting cancelation */
+        if( stream->callbackStop || stream->callbackAbort )
+        {
+            PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" ));
+            (*frames) = 0;
+            return paNoError;
+        }
+#endif
         if( pollCapture )
         {
             if( FD_ISSET( captureFd, &readFds ) )
@@ -1603,8 +1622,15 @@ static void *PaOSS_AudioThreadProc( void *userData )
 
     while( 1 )
     {
+#ifdef PTHREAD_CANCELED
         pthread_testcancel();
-
+#else
+        if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */
+        {
+            PA_DEBUG(( "Aborting callback thread\n" ));
+            break;
+        }
+#endif
         if( stream->callbackStop && callbackResult == paContinue )
         {
             PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
@@ -1631,8 +1657,21 @@ static void *PaOSS_AudioThreadProc( void *userData )
         {
             unsigned long frames = framesAvail;
 
+#ifdef PTHREAD_CANCELED
             pthread_testcancel();
+#else
+            if( stream->callbackStop )
+            {
+                PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
+                callbackResult = paComplete;
+            }
 
+            if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */
+            {
+                PA_DEBUG(( "Aborting callback thread\n" ));
+                break;
+            }
+#endif
             PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
 
             /* Read data */
index a0fcfcab7ffbe7adca7a749d7784c78ed8b7f70e..63ccf448db3cfd9576a4782a0705e4075a715391 100644 (file)
@@ -193,9 +193,15 @@ PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *e
     if( exitResult )
         *exitResult = paNoError;
 
+    /* If pthread_cancel is not supported (Android platform) whole this function can lead to indefinite waiting if 
+       working thread (callbackThread) has'n received any stop signals from outside, please keep 
+       this in mind when considering using PaUtil_CancelThreading
+    */
+#ifdef PTHREAD_CANCELED
     /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
     if( !wait )
         pthread_cancel( threading->callbackThread );   /* XXX: Safe to call this if the thread has exited on its own? */
+#endif
     pthread_join( threading->callbackThread, &pret );
 
 #ifdef PTHREAD_CANCELED
@@ -427,12 +433,19 @@ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResul
     {
         PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread ));
         /* XXX: Safe to call this if the thread has exited on its own? */
+#ifdef PTHREAD_CANCELED
         pthread_cancel( self->thread );
+#endif
     }
     PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread ));
     PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 );
 
+#ifdef PTHREAD_CANCELED
     if( pret && PTHREAD_CANCELED != pret )
+#else
+    /* !wait means the thread may have been canceled */
+    if( pret && wait )
+#endif
     {
         if( exitResult )
         {
@@ -508,7 +521,9 @@ PaError PaUnixMutex_Lock( PaUnixMutex* self )
     PaError result = paNoError;
     int oldState;
     
+#ifdef PTHREAD_CANCEL
     PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 );
+#endif
     PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 );
 
 error:
@@ -525,7 +540,9 @@ PaError PaUnixMutex_Unlock( PaUnixMutex* self )
     int oldState;
 
     PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 );
+#ifdef PTHREAD_CANCEL
     PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 );
+#endif
 
 error:
     return result;