To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / portaudio_20161030_catalina_patch / src / os / unix / pa_unix_util.h @ 164:9fa11135915a

History | View | Annotate | Download (7.69 KB)

1
/*
2
 * $Id$
3
 * Portable Audio I/O Library
4
 * UNIX platform-specific support functions
5
 *
6
 * Based on the Open Source API proposed by Ross Bencina
7
 * Copyright (c) 1999-2000 Ross Bencina
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining
10
 * a copy of this software and associated documentation files
11
 * (the "Software"), to deal in the Software without restriction,
12
 * including without limitation the rights to use, copy, modify, merge,
13
 * publish, distribute, sublicense, and/or sell copies of the Software,
14
 * and to permit persons to whom the Software is furnished to do so,
15
 * subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be
18
 * included in all copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
24
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
 */
28

    
29
/*
30
 * The text above constitutes the entire PortAudio license; however, 
31
 * the PortAudio community also makes the following non-binding requests:
32
 *
33
 * Any person wishing to distribute modifications to the Software is
34
 * requested to send the modifications to the original developer so that
35
 * they can be incorporated into the canonical version. It is also 
36
 * requested that these non-binding requests be included along with the 
37
 * license above.
38
 */
39

    
40
/** @file
41
 @ingroup unix_src
42
*/
43

    
44
#ifndef PA_UNIX_UTIL_H
45
#define PA_UNIX_UTIL_H
46

    
47
#include "pa_cpuload.h"
48
#include <assert.h>
49
#include <pthread.h>
50
#include <signal.h>
51

    
52
#ifdef __cplusplus
53
extern "C"
54
{
55
#endif /* __cplusplus */
56

    
57
#define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) )
58
#define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) )
59

    
60
/* Utilize GCC branch prediction for error tests */
61
#if defined __GNUC__ && __GNUC__ >= 3
62
#define UNLIKELY(expr) __builtin_expect( (expr), 0 )
63
#else
64
#define UNLIKELY(expr) (expr)
65
#endif
66

    
67
#define STRINGIZE_HELPER(expr) #expr
68
#define STRINGIZE(expr) STRINGIZE_HELPER(expr)
69

    
70
#define PA_UNLESS(expr, code) \
71
    do { \
72
        if( UNLIKELY( (expr) == 0 ) ) \
73
        { \
74
            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
75
            result = (code); \
76
            goto error; \
77
        } \
78
    } while (0);
79

    
80
static PaError paUtilErr_;          /* Used with PA_ENSURE */
81

    
82
/* Check PaError */
83
#define PA_ENSURE(expr) \
84
    do { \
85
        if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \
86
        { \
87
            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
88
            result = paUtilErr_; \
89
            goto error; \
90
        } \
91
    } while (0);
92

    
93
#define PA_ASSERT_CALL(expr, success) \
94
    paUtilErr_ = (expr); \
95
    assert( success == paUtilErr_ );
96

    
97
#define PA_ENSURE_SYSTEM(expr, success) \
98
    do { \
99
        if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \
100
        { \
101
            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
102
            if( pthread_equal(pthread_self(), paUnixMainThread) ) \
103
            { \
104
                PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \
105
            } \
106
            PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
107
            result = paUnanticipatedHostError; \
108
            goto error; \
109
        } \
110
    } while( 0 );
111

    
112
typedef struct {
113
    pthread_t callbackThread;
114
} PaUtilThreading;
115

    
116
PaError PaUtil_InitializeThreading( PaUtilThreading *threading );
117
void PaUtil_TerminateThreading( PaUtilThreading *threading );
118
PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data );
119
PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult );
120

    
121
/* State accessed by utility functions */
122

    
123
/*
124
void PaUnix_SetRealtimeScheduling( int rt );
125

126
void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm );
127

128
PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s );
129

130
PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult );
131

132
void PaUtil_CallbackUpdate( PaUtilThreading *th );
133
*/
134

    
135
extern pthread_t paUnixMainThread;
136

    
137
typedef struct
138
{
139
    pthread_mutex_t mtx;
140
} PaUnixMutex;
141

    
142
PaError PaUnixMutex_Initialize( PaUnixMutex* self );
143
PaError PaUnixMutex_Terminate( PaUnixMutex* self );
144
PaError PaUnixMutex_Lock( PaUnixMutex* self );
145
PaError PaUnixMutex_Unlock( PaUnixMutex* self );
146

    
147
typedef struct
148
{
149
    pthread_t thread;
150
    int parentWaiting;
151
    int stopRequested;
152
    int locked;
153
    PaUnixMutex mtx;
154
    pthread_cond_t cond;
155
    volatile sig_atomic_t stopRequest;
156
} PaUnixThread;
157

    
158
/** Initialize global threading state.
159
 */
160
PaError PaUnixThreading_Initialize();
161

    
162
/** Perish, passing on eventual error code.
163
 *
164
 * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread.
165
 * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically
166
 * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is
167
 * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should
168
 * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it.
169
 * @param result: The error code to pass on to the joining thread.
170
 */
171
#define PaUnixThreading_EXIT(result) \
172
    do { \
173
        PaError* pres = NULL; \
174
        if( paNoError != (result) ) \
175
        { \
176
            pres = malloc( sizeof (PaError) ); \
177
            *pres = (result); \
178
        } \
179
        pthread_exit( pres ); \
180
    } while (0);
181

    
182
/** Spawn a thread.
183
 *
184
 * Intended for spawning the callback thread from the main thread. This function can even block (for a certain
185
 * time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be
186
 * useful in order to make sure that callback has commenced before returning from Pa_StartStream.
187
 * @param threadFunc: The function to be executed in the child thread.
188
 * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means
189
 * wait for ever, greater than 0 wait for the specified time.
190
 * @param rtSched: Enable realtime scheduling?
191
 * @return: If timed out waiting on child, paTimedOut.
192
 */
193
PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild,
194
        int rtSched );
195

    
196
/** Terminate thread.
197
 *
198
 * @param wait: If true, request that background thread stop and wait untill it does, else cancel it.
199
 * @param exitResult: If non-null this will upon return contain the exit status of the thread.
200
 */
201
PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult );
202

    
203
/** Prepare to notify waiting parent thread.
204
 *
205
 * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to
206
 * acquire it beforehand.
207
 * @return: If parent is not waiting, paInternalError.
208
 */
209
PaError PaUnixThread_PrepareNotify( PaUnixThread* self );
210

    
211
/** Notify waiting parent thread.
212
 *
213
 * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError.
214
 */
215
PaError PaUnixThread_NotifyParent( PaUnixThread* self );
216

    
217
/** Has the parent thread requested this thread to stop?
218
 */
219
int PaUnixThread_StopRequested( PaUnixThread* self );
220

    
221
#ifdef __cplusplus
222
}
223
#endif /* __cplusplus */
224
#endif