1 /*****************************************************************************
2 * threads.c : threads implementation for the VideoLAN client
3 *****************************************************************************
4 * Copyright (C) 1999-2008 the VideoLAN team
7 * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
8 * Samuel Hocevar <sam@zoy.org>
9 * Gildas Bazin <gbazin@netcourrier.com>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
32 #include <vlc_common.h>
41 #if defined( LIBVLC_USE_PTHREAD )
45 struct vlc_thread_boot
47 void * (*entry
) (vlc_object_t
*);
51 static void *thread_entry (void *data
)
53 vlc_object_t
*obj
= ((struct vlc_thread_boot
*)data
)->object
;
54 void *(*func
) (vlc_object_t
*) = ((struct vlc_thread_boot
*)data
)->entry
;
57 msg_Dbg (obj
, "thread started");
59 msg_Dbg (obj
, "thread ended");
64 #undef vlc_thread_create
65 /*****************************************************************************
66 * vlc_thread_create: create a thread
67 *****************************************************************************
68 * Note that i_priority is only taken into account on platforms supporting
69 * userland real-time priority threads.
70 *****************************************************************************/
71 int vlc_thread_create( vlc_object_t
*p_this
, void *(*func
) ( vlc_object_t
* ),
75 vlc_object_internals_t
*p_priv
= vlc_internals( p_this
);
77 struct vlc_thread_boot
*boot
= malloc (sizeof (*boot
));
81 boot
->object
= p_this
;
83 /* Make sure we don't re-create a thread if the object has already one */
84 assert( !p_priv
->b_thread
);
86 i_ret
= vlc_clone( &p_priv
->thread_id
, thread_entry
, boot
, i_priority
);
88 p_priv
->b_thread
= true;
92 msg_Err( p_this
, "cannot create thread (%m)" );
99 #undef vlc_thread_set_priority
100 /*****************************************************************************
101 * vlc_thread_set_priority: set the priority of the current thread when we
102 * couldn't set it in vlc_thread_create (for instance for the main thread)
103 *****************************************************************************/
104 int vlc_thread_set_priority( vlc_object_t
*p_this
, int i_priority
)
106 vlc_object_internals_t
*p_priv
= vlc_internals( p_this
);
108 if( !p_priv
->b_thread
)
110 msg_Err( p_this
, "couldn't set priority of non-existent thread" );
114 #if defined( LIBVLC_USE_PTHREAD )
116 if( var_InheritBool( p_this
, "rt-priority" ) )
119 int i_error
, i_policy
;
120 struct sched_param param
;
122 memset( ¶m
, 0, sizeof(struct sched_param
) );
123 if( config_GetType( p_this
, "rt-offset" ) )
124 i_priority
+= var_InheritInteger( p_this
, "rt-offset" );
125 if( i_priority
<= 0 )
127 param
.sched_priority
= (-1) * i_priority
;
128 i_policy
= SCHED_OTHER
;
132 param
.sched_priority
= i_priority
;
135 if( (i_error
= pthread_setschedparam( p_priv
->thread_id
,
136 i_policy
, ¶m
)) )
139 msg_Warn( p_this
, "cannot set thread priority (%m)" );
144 #elif defined( WIN32 ) || defined( UNDER_CE )
146 #warning vlc_thread_set_priority() is BROKEN
147 if( true /*!SetThreadPriority(p_priv->thread_id->id, i_priority)*/ )
149 msg_Warn( p_this
, "couldn't set a faster priority" );
158 #undef vlc_thread_join
159 /*****************************************************************************
160 * vlc_thread_join: wait until a thread exits, inner version
161 *****************************************************************************/
162 void vlc_thread_join( vlc_object_t
*p_this
)
164 vlc_object_internals_t
*p_priv
= vlc_internals( p_this
);
166 vlc_join( p_priv
->thread_id
, NULL
);
167 p_priv
->b_thread
= false;
170 void vlc_thread_cancel (vlc_object_t
*obj
)
172 vlc_object_internals_t
*priv
= vlc_internals (obj
);
175 vlc_cancel (priv
->thread_id
);
178 /*** Global locks ***/
180 void vlc_global_mutex (unsigned n
, bool acquire
)
182 static vlc_mutex_t locks
[] = {
187 assert (n
< (sizeof (locks
) / sizeof (locks
[0])));
188 vlc_mutex_t
*lock
= locks
+ n
;
191 vlc_mutex_lock (lock
);
193 vlc_mutex_unlock (lock
);
195 /* Compile-time assertion ;-) */
196 char enough_locks
[(sizeof (locks
) / sizeof (locks
[0])) - VLC_MAX_MUTEX
];