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];