]> git.sesse.net Git - vlc/blob - include/vlc_thread.h
8b6abaa51363389954ae9e8c22946f3a4921e7c9
[vlc] / include / vlc_thread.h
1 /*****************************************************************************
2  * vlc_thread.h : thread implementation for vieolan client
3  * (c)1999 VideoLAN
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  *****************************************************************************/
9 #ifdef SYS_GNU
10 #include <cthreads.h>
11 #else
12 #include <pthread.h>
13 #endif
14
15 /*****************************************************************************
16  * Constants
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  *****************************************************************************/
22
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 */
26
27 /* Creation status */
28 #define THREAD_CREATE       10                     /* thread is initializing */
29 #define THREAD_START        11                          /* thread has forked */
30 #define THREAD_READY        19                            /* thread is ready */
31
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 */
36
37 /* Error status */
38 #define THREAD_ERROR        30                           /* an error occured */
39 #define THREAD_FATAL        31  /* an fatal error occured - program must end */
40
41 /*****************************************************************************
42  * Types definition
43  *****************************************************************************/
44
45 #ifdef SYS_GNU
46
47 typedef cthread_t        vlc_thread_t;
48
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 {
52     spin_lock_t held;
53     spin_lock_t lock;
54     char *name;
55     struct cthread_queue queue;
56 } vlc_mutex_t;
57
58 typedef struct s_condition {
59     spin_lock_t lock;
60     struct cthread_queue queue;
61     char *name;
62     struct cond_imp *implications;
63 } vlc_cond_t;
64
65 #else /* SYS_GNU */
66
67 typedef pthread_t        vlc_thread_t;
68 typedef pthread_mutex_t  vlc_mutex_t;
69 typedef pthread_cond_t   vlc_cond_t;
70
71 #endif /* SYS_GNU */
72
73 typedef void *(*vlc_thread_func_t)(void *p_data);
74
75 /*****************************************************************************
76  * Prototypes
77  *****************************************************************************/
78
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 );
83
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 );
87
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 );
91
92 #if 0
93 static _inline__ int    vlc_cond_timedwait   ( vlc_cond_t * condvar, vlc_mutex_t * mutex,
94                               mtime_t absoute_timeout_time );
95 #endif
96
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,
102                                          void *p_data)
103 {
104 #ifdef SYS_GNU
105     *p_thread = cthread_fork( (cthread_fn_t)func, (any_t)p_data );
106     return( 0 );
107 #else
108     return pthread_create( p_thread, NULL, func, p_data );
109 #endif
110 }
111
112 /*****************************************************************************
113  * vlc_thread_exit: terminate a thread
114  *****************************************************************************/
115 static __inline__ void vlc_thread_exit( void )
116 {
117 #ifdef SYS_GNU
118     int result;
119     cthread_exit( &result );
120 #else           
121     pthread_exit( 0 );
122 #endif
123 }
124
125 /*****************************************************************************
126  * vlc_thread_join: wait until a thread exits
127  *****************************************************************************/
128 static __inline__ void vlc_thread_join( vlc_thread_t thread )
129 {
130 #ifdef SYS_GNU
131     cthread_join( thread );
132 #else   
133     pthread_join( thread, NULL );
134 #endif
135 }
136
137 /*****************************************************************************
138  * vlc_mutex_init: initialize a mutex
139  *****************************************************************************/
140 static __inline__ int vlc_mutex_init( vlc_mutex_t *p_mutex )
141 {
142 #ifdef SYS_GNU
143     mutex_init( p_mutex );
144     return( 0 );
145 #else
146     return pthread_mutex_init( p_mutex, NULL );
147 #endif
148 }
149
150 /*****************************************************************************
151  * vlc_mutex_lock: lock a mutex
152  *****************************************************************************/
153 static __inline__ int vlc_mutex_lock( vlc_mutex_t *p_mutex )
154 {
155 #ifdef SYS_GNU
156     mutex_lock( p_mutex );
157     return( 0 );
158 #else
159     return pthread_mutex_lock( p_mutex );
160 #endif
161 }
162
163 /*****************************************************************************
164  * vlc_mutex_unlock: unlock a mutex
165  *****************************************************************************/
166 static __inline__ int vlc_mutex_unlock( vlc_mutex_t *p_mutex )
167 {
168 #ifdef SYS_GNU
169     mutex_unlock( p_mutex );
170     return( 0 );
171 #else
172     return pthread_mutex_unlock( p_mutex );
173 #endif
174 }
175
176 /*****************************************************************************
177  * vlc_cond_init: initialize a condition
178  *****************************************************************************/
179 static __inline__ int vlc_cond_init( vlc_cond_t *p_condvar )
180 {
181 #ifdef SYS_GNU
182     /* condition_init() */
183     spin_lock_init( &p_condvar->lock );
184     cthread_queue_init( &p_condvar->queue );
185     p_condvar->name = 0;
186     p_condvar->implications = 0;
187
188     return( 0 );
189 #else                       
190     return pthread_cond_init( p_condvar, NULL );
191 #endif
192 }
193
194 /*****************************************************************************
195  * vlc_cond_signal: start a thread on condition completion
196  *****************************************************************************/
197 static __inline__ int vlc_cond_signal( vlc_cond_t *p_condvar )
198 {
199 #ifdef SYS_GNU
200     /* condition_signal() */
201     if ( p_condvar->queue.head || p_condvar->implications )
202     {
203         cond_signal( (condition_t)p_condvar );
204     }
205     return( 0 );
206 #else           
207     return pthread_cond_signal( p_condvar );
208 #endif
209 }
210
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 )
215 {
216 #ifdef SYS_GNU
217     condition_wait( (condition_t)p_condvar, (mutex_t)p_mutex );
218     return( 0 );
219 #else
220     return pthread_cond_wait( p_condvar, p_mutex );
221 #endif
222 }
223