blob: 6e5744736becb5956faba3de47b2152bb13f5182
1 | /* |
2 | * This file is part of FFmpeg. |
3 | * |
4 | * FFmpeg is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * FFmpeg is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with FFmpeg; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | // This header should only be used to simplify code where |
20 | // threading is optional, not as a generic threading abstraction. |
21 | |
22 | #ifndef AVUTIL_THREAD_H |
23 | #define AVUTIL_THREAD_H |
24 | |
25 | #include "config.h" |
26 | |
27 | #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS |
28 | |
29 | #if HAVE_PTHREADS |
30 | #include <pthread.h> |
31 | |
32 | #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 |
33 | |
34 | #include "log.h" |
35 | |
36 | #define ASSERT_PTHREAD_NORET(func, ...) do { \ |
37 | int ret = func(__VA_ARGS__); \ |
38 | if (ret) { \ |
39 | av_log(NULL, AV_LOG_FATAL, AV_STRINGIFY(func) \ |
40 | " failed with error: %s\n", av_err2str(AVERROR(ret))); \ |
41 | abort(); \ |
42 | } \ |
43 | } while (0) |
44 | |
45 | #define ASSERT_PTHREAD(func, ...) do { \ |
46 | ASSERT_PTHREAD_NORET(func, __VA_ARGS__); \ |
47 | return 0; \ |
48 | } while (0) |
49 | |
50 | static inline int strict_pthread_join(pthread_t thread, void **value_ptr) |
51 | { |
52 | ASSERT_PTHREAD(pthread_join, thread, value_ptr); |
53 | } |
54 | |
55 | static inline int strict_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) |
56 | { |
57 | if (attr) { |
58 | ASSERT_PTHREAD_NORET(pthread_mutex_init, mutex, attr); |
59 | } else { |
60 | pthread_mutexattr_t local_attr; |
61 | ASSERT_PTHREAD_NORET(pthread_mutexattr_init, &local_attr); |
62 | ASSERT_PTHREAD_NORET(pthread_mutexattr_settype, &local_attr, PTHREAD_MUTEX_ERRORCHECK); |
63 | ASSERT_PTHREAD_NORET(pthread_mutex_init, mutex, &local_attr); |
64 | ASSERT_PTHREAD_NORET(pthread_mutexattr_destroy, &local_attr); |
65 | } |
66 | return 0; |
67 | } |
68 | |
69 | static inline int strict_pthread_mutex_destroy(pthread_mutex_t *mutex) |
70 | { |
71 | ASSERT_PTHREAD(pthread_mutex_destroy, mutex); |
72 | } |
73 | |
74 | static inline int strict_pthread_mutex_lock(pthread_mutex_t *mutex) |
75 | { |
76 | ASSERT_PTHREAD(pthread_mutex_lock, mutex); |
77 | } |
78 | |
79 | static inline int strict_pthread_mutex_unlock(pthread_mutex_t *mutex) |
80 | { |
81 | ASSERT_PTHREAD(pthread_mutex_unlock, mutex); |
82 | } |
83 | |
84 | static inline int strict_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) |
85 | { |
86 | ASSERT_PTHREAD(pthread_cond_init, cond, attr); |
87 | } |
88 | |
89 | static inline int strict_pthread_cond_destroy(pthread_cond_t *cond) |
90 | { |
91 | ASSERT_PTHREAD(pthread_cond_destroy, cond); |
92 | } |
93 | |
94 | static inline int strict_pthread_cond_signal(pthread_cond_t *cond) |
95 | { |
96 | ASSERT_PTHREAD(pthread_cond_signal, cond); |
97 | } |
98 | |
99 | static inline int strict_pthread_cond_broadcast(pthread_cond_t *cond) |
100 | { |
101 | ASSERT_PTHREAD(pthread_cond_broadcast, cond); |
102 | } |
103 | |
104 | static inline int strict_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) |
105 | { |
106 | ASSERT_PTHREAD(pthread_cond_wait, cond, mutex); |
107 | } |
108 | |
109 | static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) |
110 | { |
111 | ASSERT_PTHREAD(pthread_once, once_control, init_routine); |
112 | } |
113 | |
114 | #define pthread_join strict_pthread_join |
115 | #define pthread_mutex_init strict_pthread_mutex_init |
116 | #define pthread_mutex_destroy strict_pthread_mutex_destroy |
117 | #define pthread_mutex_lock strict_pthread_mutex_lock |
118 | #define pthread_mutex_unlock strict_pthread_mutex_unlock |
119 | #define pthread_cond_init strict_pthread_cond_init |
120 | #define pthread_cond_destroy strict_pthread_cond_destroy |
121 | #define pthread_cond_signal strict_pthread_cond_signal |
122 | #define pthread_cond_broadcast strict_pthread_cond_broadcast |
123 | #define pthread_cond_wait strict_pthread_cond_wait |
124 | #define pthread_once strict_pthread_once |
125 | #endif |
126 | |
127 | #elif HAVE_OS2THREADS |
128 | #include "compat/os2threads.h" |
129 | #else |
130 | #include "compat/w32pthreads.h" |
131 | #endif |
132 | |
133 | #define AVMutex pthread_mutex_t |
134 | |
135 | #define ff_mutex_init pthread_mutex_init |
136 | #define ff_mutex_lock pthread_mutex_lock |
137 | #define ff_mutex_unlock pthread_mutex_unlock |
138 | #define ff_mutex_destroy pthread_mutex_destroy |
139 | |
140 | #define AVOnce pthread_once_t |
141 | #define AV_ONCE_INIT PTHREAD_ONCE_INIT |
142 | |
143 | #define ff_thread_once(control, routine) pthread_once(control, routine) |
144 | |
145 | #else |
146 | |
147 | #define AVMutex char |
148 | |
149 | #define ff_mutex_init(mutex, attr) (0) |
150 | #define ff_mutex_lock(mutex) (0) |
151 | #define ff_mutex_unlock(mutex) (0) |
152 | #define ff_mutex_destroy(mutex) (0) |
153 | |
154 | #define AVOnce char |
155 | #define AV_ONCE_INIT 0 |
156 | |
157 | static inline int ff_thread_once(char *control, void (*routine)(void)) |
158 | { |
159 | if (!*control) { |
160 | routine(); |
161 | *control = 1; |
162 | } |
163 | return 0; |
164 | } |
165 | |
166 | #endif |
167 | |
168 | #endif /* AVUTIL_THREAD_H */ |
169 |