PortAudio  2.0
pa_unix_util.h
Go to the documentation of this file.
00001 /*
00002  * $Id: pa_unix_util.h 1241 2007-07-23 20:08:31Z aknudsen $
00003  * Portable Audio I/O Library
00004  * UNIX platform-specific support functions
00005  *
00006  * Based on the Open Source API proposed by Ross Bencina
00007  * Copyright (c) 1999-2000 Ross Bencina
00008  *
00009  * Permission is hereby granted, free of charge, to any person obtaining
00010  * a copy of this software and associated documentation files
00011  * (the "Software"), to deal in the Software without restriction,
00012  * including without limitation the rights to use, copy, modify, merge,
00013  * publish, distribute, sublicense, and/or sell copies of the Software,
00014  * and to permit persons to whom the Software is furnished to do so,
00015  * subject to the following conditions:
00016  *
00017  * The above copyright notice and this permission notice shall be
00018  * included in all copies or substantial portions of the Software.
00019  *
00020  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00021  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00022  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00023  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
00024  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00025  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00026  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00027  */
00028 
00029 /*
00030  * The text above constitutes the entire PortAudio license; however, 
00031  * the PortAudio community also makes the following non-binding requests:
00032  *
00033  * Any person wishing to distribute modifications to the Software is
00034  * requested to send the modifications to the original developer so that
00035  * they can be incorporated into the canonical version. It is also 
00036  * requested that these non-binding requests be included along with the 
00037  * license above.
00038  */
00039 
00044 #ifndef PA_UNIX_UTIL_H
00045 #define PA_UNIX_UTIL_H
00046 
00047 #include "pa_cpuload.h"
00048 #include <assert.h>
00049 #include <pthread.h>
00050 #include <signal.h>
00051 
00052 #ifdef __cplusplus
00053 extern "C"
00054 {
00055 #endif /* __cplusplus */
00056 
00057 #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) )
00058 #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) )
00059 
00060 /* Utilize GCC branch prediction for error tests */
00061 #if defined __GNUC__ && __GNUC__ >= 3
00062 #define UNLIKELY(expr) __builtin_expect( (expr), 0 )
00063 #else
00064 #define UNLIKELY(expr) (expr)
00065 #endif
00066 
00067 #define STRINGIZE_HELPER(expr) #expr
00068 #define STRINGIZE(expr) STRINGIZE_HELPER(expr)
00069 
00070 #define PA_UNLESS(expr, code) \
00071     do { \
00072         if( UNLIKELY( (expr) == 0 ) ) \
00073         { \
00074             PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
00075             result = (code); \
00076             goto error; \
00077         } \
00078     } while (0);
00079 
00080 static PaError paUtilErr_;          /* Used with PA_ENSURE */
00081 
00082 /* Check PaError */
00083 #define PA_ENSURE(expr) \
00084     do { \
00085         if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \
00086         { \
00087             PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
00088             result = paUtilErr_; \
00089             goto error; \
00090         } \
00091     } while (0);
00092 
00093 #define PA_ASSERT_CALL(expr, success) \
00094     paUtilErr_ = (expr); \
00095     assert( success == paUtilErr_ );
00096 
00097 #define PA_ENSURE_SYSTEM(expr, success) \
00098     do { \
00099         if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \
00100         { \
00101             /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
00102             if( pthread_equal(pthread_self(), paUnixMainThread) ) \
00103             { \
00104                 PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \
00105             } \
00106             PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
00107             result = paUnanticipatedHostError; \
00108             goto error; \
00109         } \
00110     } while( 0 );
00111 
00112 typedef struct {
00113     pthread_t callbackThread;
00114 } PaUtilThreading;
00115 
00116 PaError PaUtil_InitializeThreading( PaUtilThreading *threading );
00117 void PaUtil_TerminateThreading( PaUtilThreading *threading );
00118 PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data );
00119 PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult );
00120 
00121 /* State accessed by utility functions */
00122 
00123 /*
00124 void PaUnix_SetRealtimeScheduling( int rt );
00125 
00126 void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm );
00127 
00128 PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s );
00129 
00130 PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult );
00131 
00132 void PaUtil_CallbackUpdate( PaUtilThreading *th );
00133 */
00134 
00135 extern pthread_t paUnixMainThread;
00136 
00137 typedef struct
00138 {
00139     pthread_mutex_t mtx;
00140 } PaUnixMutex;
00141 
00142 PaError PaUnixMutex_Initialize( PaUnixMutex* self );
00143 PaError PaUnixMutex_Terminate( PaUnixMutex* self );
00144 PaError PaUnixMutex_Lock( PaUnixMutex* self );
00145 PaError PaUnixMutex_Unlock( PaUnixMutex* self );
00146 
00147 typedef struct
00148 {
00149     pthread_t thread;
00150     int parentWaiting;
00151     int stopRequested;
00152     int locked;
00153     PaUnixMutex mtx;
00154     pthread_cond_t cond;
00155     volatile sig_atomic_t stopRequest;
00156 } PaUnixThread;
00157 
00160 PaError PaUnixThreading_Initialize();
00161 
00171 #define PaUnixThreading_EXIT(result) \
00172     do { \
00173         PaError* pres = NULL; \
00174         if( paNoError != (result) ) \
00175         { \
00176             pres = malloc( sizeof (PaError) ); \
00177             *pres = (result); \
00178         } \
00179         pthread_exit( pres ); \
00180     } while (0);
00181 
00193 PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild,
00194         int rtSched );
00195 
00201 PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult );
00202 
00209 PaError PaUnixThread_PrepareNotify( PaUnixThread* self );
00210 
00215 PaError PaUnixThread_NotifyParent( PaUnixThread* self );
00216 
00219 int PaUnixThread_StopRequested( PaUnixThread* self );
00220 
00221 #ifdef __cplusplus
00222 }
00223 #endif /* __cplusplus */
00224 #endif

Generated for PortAudio by  doxygen1.7.6.1