1 /*****************************************************************************
2 * vlc_thread.h : thread implementation for vieolan client
4 *****************************************************************************
5 * This header is supposed to provide a portable threads implementation.
6 * Currently, it is a wrapper to either the POSIX pthreads library, or
7 * the Mach cthreads (for the GNU/Hurd).
8 *****************************************************************************/
15 /*****************************************************************************
17 *****************************************************************************
18 * These constants are used by all threads in *_CreateThread() and
19 * *_DestroyThreads() functions. Since those calls are non-blocking, an integer
20 * value is used as a shared flag to represent the status of the thread.
21 *****************************************************************************/
23 /* Void status - this value can be used to be sure, in an array of recorded
24 * threads, that no operation is currently in progress on the concerned thread */
25 #define THREAD_NOP 0 /* nothing happened */
28 #define THREAD_CREATE 10 /* thread is initializing */
29 #define THREAD_START 11 /* thread has forked */
30 #define THREAD_READY 19 /* thread is ready */
32 /* Destructions status */
33 #define THREAD_DESTROY 20 /* destruction order has been sent */
34 #define THREAD_END 21 /* destruction order has been received */
35 #define THREAD_OVER 29 /* thread does not exist any more */
38 #define THREAD_ERROR 30 /* an error occured */
39 #define THREAD_FATAL 31 /* an fatal error occured - program must end */
41 /*****************************************************************************
43 *****************************************************************************/
47 typedef cthread_t vlc_thread_t;
49 /* those structs are the ones defined in /include/cthreads.h but we need
50 * * to handle *foo where foo is a mutex_t */
51 typedef struct s_mutex {
55 struct cthread_queue queue;
58 typedef struct s_condition {
60 struct cthread_queue queue;
62 struct cond_imp *implications;
67 typedef pthread_t vlc_thread_t;
68 typedef pthread_mutex_t vlc_mutex_t;
69 typedef pthread_cond_t vlc_cond_t;
73 typedef void *(*vlc_thread_func_t)(void *p_data);
75 /*****************************************************************************
77 *****************************************************************************/
79 static __inline__ int vlc_thread_create( vlc_thread_t *p_thread, char *psz_name,
80 vlc_thread_func_t func, void *p_data );
81 static __inline__ void vlc_thread_exit ( void );
82 static __inline__ void vlc_thread_join ( vlc_thread_t thread );
84 static __inline__ int vlc_mutex_init ( vlc_mutex_t *p_mutex );
85 static __inline__ int vlc_mutex_lock ( vlc_mutex_t *p_mutex );
86 static __inline__ int vlc_mutex_unlock ( vlc_mutex_t *p_mutex );
88 static __inline__ int vlc_cond_init ( vlc_cond_t *p_condvar );
89 static __inline__ int vlc_cond_signal ( vlc_cond_t *p_condvar );
90 static __inline__ int vlc_cond_wait ( vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex );
93 static _inline__ int vlc_cond_timedwait ( vlc_cond_t * condvar, vlc_mutex_t * mutex,
94 mtime_t absoute_timeout_time );
97 /*****************************************************************************
98 * vlc_thread_create: create a thread
99 *****************************************************************************/
100 static __inline__ int vlc_thread_create( vlc_thread_t *p_thread,
101 char *psz_name, vlc_thread_func_t func,
105 *p_thread = cthread_fork( (cthread_fn_t)func, (any_t)p_data );
108 return pthread_create( p_thread, NULL, func, p_data );
112 /*****************************************************************************
113 * vlc_thread_exit: terminate a thread
114 *****************************************************************************/
115 static __inline__ void vlc_thread_exit( void )
119 cthread_exit( &result );
125 /*****************************************************************************
126 * vlc_thread_join: wait until a thread exits
127 *****************************************************************************/
128 static __inline__ void vlc_thread_join( vlc_thread_t thread )
131 cthread_join( thread );
133 pthread_join( thread, NULL );
137 /*****************************************************************************
138 * vlc_mutex_init: initialize a mutex
139 *****************************************************************************/
140 static __inline__ int vlc_mutex_init( vlc_mutex_t *p_mutex )
143 mutex_init( p_mutex );
146 return pthread_mutex_init( p_mutex, NULL );
150 /*****************************************************************************
151 * vlc_mutex_lock: lock a mutex
152 *****************************************************************************/
153 static __inline__ int vlc_mutex_lock( vlc_mutex_t *p_mutex )
156 mutex_lock( p_mutex );
159 return pthread_mutex_lock( p_mutex );
163 /*****************************************************************************
164 * vlc_mutex_unlock: unlock a mutex
165 *****************************************************************************/
166 static __inline__ int vlc_mutex_unlock( vlc_mutex_t *p_mutex )
169 mutex_unlock( p_mutex );
172 return pthread_mutex_unlock( p_mutex );
176 /*****************************************************************************
177 * vlc_cond_init: initialize a condition
178 *****************************************************************************/
179 static __inline__ int vlc_cond_init( vlc_cond_t *p_condvar )
182 /* condition_init() */
183 spin_lock_init( &p_condvar->lock );
184 cthread_queue_init( &p_condvar->queue );
186 p_condvar->implications = 0;
190 return pthread_cond_init( p_condvar, NULL );
194 /*****************************************************************************
195 * vlc_cond_signal: start a thread on condition completion
196 *****************************************************************************/
197 static __inline__ int vlc_cond_signal( vlc_cond_t *p_condvar )
200 /* condition_signal() */
201 if ( p_condvar->queue.head || p_condvar->implications )
203 cond_signal( (condition_t)p_condvar );
207 return pthread_cond_signal( p_condvar );
211 /*****************************************************************************
212 * vlc_cond_wait: wait until condition completion
213 *****************************************************************************/
214 static __inline__ int vlc_cond_wait( vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex )
217 condition_wait( (condition_t)p_condvar, (mutex_t)p_mutex );
220 return pthread_cond_wait( p_condvar, p_mutex );