Playlist: fix scrolling events in selector
[vlc/vlc-skelet.git] / src / misc / threads.c
blob265f60bd8bb922636cc36f47e6d34c710faf9d89
1 /*****************************************************************************
2 * threads.c : threads implementation for the VideoLAN client
3 *****************************************************************************
4 * Copyright (C) 1999-2008 the VideoLAN team
5 * $Id$
7 * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
8 * Samuel Hocevar <sam@zoy.org>
9 * Gildas Bazin <gbazin@netcourrier.com>
10 * Clément Sténac
11 * Rémi Denis-Courmont
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 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
34 #include "libvlc.h"
35 #include <assert.h>
36 #include <errno.h>
37 #ifdef HAVE_UNISTD_H
38 # include <unistd.h>
39 #endif
41 #if defined( LIBVLC_USE_PTHREAD )
42 # include <sched.h>
43 #endif
45 struct vlc_thread_boot
47 void * (*entry) (vlc_object_t *);
48 vlc_object_t *object;
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;
56 free (data);
57 msg_Dbg (obj, "thread started");
58 func (obj);
59 msg_Dbg (obj, "thread ended");
61 return NULL;
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 * ),
72 int i_priority )
74 int i_ret;
75 vlc_object_internals_t *p_priv = vlc_internals( p_this );
77 struct vlc_thread_boot *boot = malloc (sizeof (*boot));
78 if (boot == NULL)
79 return errno;
80 boot->entry = func;
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 );
87 if( i_ret == 0 )
88 p_priv->b_thread = true;
89 else
91 errno = i_ret;
92 msg_Err( p_this, "cannot create thread (%m)" );
93 free (boot);
96 return i_ret;
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" );
111 return ESRCH;
114 #if defined( LIBVLC_USE_PTHREAD )
115 # ifndef __APPLE__
116 if( var_InheritBool( p_this, "rt-priority" ) )
117 # endif
119 int i_error, i_policy;
120 struct sched_param param;
122 memset( &param, 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;
130 else
132 param.sched_priority = i_priority;
133 i_policy = SCHED_RR;
135 if( (i_error = pthread_setschedparam( p_priv->thread_id,
136 i_policy, &param )) )
138 errno = i_error;
139 msg_Warn( p_this, "cannot set thread priority (%m)" );
140 i_priority = 0;
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" );
150 return 1;
153 #endif
155 return 0;
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);
174 if (priv->b_thread)
175 vlc_cancel (priv->thread_id);
178 /*** Global locks ***/
180 void vlc_global_mutex (unsigned n, bool acquire)
182 static vlc_mutex_t locks[] = {
183 VLC_STATIC_MUTEX,
184 VLC_STATIC_MUTEX,
185 VLC_STATIC_MUTEX,
187 assert (n < (sizeof (locks) / sizeof (locks[0])));
188 vlc_mutex_t *lock = locks + n;
190 if (acquire)
191 vlc_mutex_lock (lock);
192 else
193 vlc_mutex_unlock (lock);
195 /* Compile-time assertion ;-) */
196 char enough_locks[(sizeof (locks) / sizeof (locks[0])) - VLC_MAX_MUTEX];
197 (void) enough_locks;