]> git.sesse.net Git - vlc/blob - src/misc/exit.c
vlc_global_mutex: common functions for process-wide mutexes
[vlc] / src / misc / exit.c
1 /*****************************************************************************
2  * quit.c: LibVLC termination event
3  *****************************************************************************
4  * Copyright (C) 2009-2010 the VideoLAN team
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <vlc_common.h>
26 #include <vlc_interface.h>
27 #include "libvlc.h"
28 #include "control/libvlc_internal.h"
29
30 void vlc_ExitInit( vlc_exit_t *exit )
31 {
32     vlc_mutex_init( &exit->lock );
33     exit->handler = NULL;
34     exit->opaque = NULL;
35     exit->killed = false;
36 }
37
38 void vlc_ExitDestroy( vlc_exit_t *exit )
39 {
40     vlc_mutex_destroy( &exit->lock );
41 }
42
43
44 /**
45  * Registers a callback for the LibVLC exit event.
46  *
47  * @note This function conflicts with libvlc_InternalWait().
48  * Use either or none of them, but not both.
49  */
50 void libvlc_SetExitHandler( libvlc_int_t *p_libvlc, void (*handler) (void *),
51                             void *opaque )
52 {
53     vlc_exit_t *exit = &libvlc_priv( p_libvlc )->exit;
54
55     vlc_mutex_lock( &exit->lock );
56     if( exit->killed ) /* already exited! (race condition) */
57         handler( opaque );
58     exit->handler = handler;
59     exit->opaque = opaque;
60     vlc_mutex_unlock( &exit->lock );
61 }
62
63 /**
64  * Posts an exit signal to LibVLC instance. This only emits a notification to
65  * the main thread. It might take a while before the actual cleanup occurs.
66  * This function should only be called on behalf of the user.
67  */
68 void libvlc_Quit( libvlc_int_t *p_libvlc )
69 {
70     vlc_exit_t *exit = &libvlc_priv( p_libvlc )->exit;
71
72     vlc_mutex_lock( &exit->lock );
73     if( !exit->killed )
74     {
75         msg_Dbg( p_libvlc, "exiting" );
76         exit->killed = true;
77         if( exit->handler != NULL )
78             exit->handler( exit->opaque );
79     }
80     vlc_mutex_unlock( &exit->lock );
81 }
82
83
84 static void exit_wakeup( void *data )
85 {
86     vlc_cond_signal( data );
87 }
88
89 /**
90  * Waits until the LibVLC instance gets an exit signal.
91  * This normally occurs when the user "exits" an interface plugin. But it can
92  * also be triggered by the special vlc://quit item, the update checker, or
93  * the playlist engine.
94  */
95 void libvlc_InternalWait( libvlc_int_t *p_libvlc )
96 {
97     vlc_exit_t *exit = &libvlc_priv( p_libvlc )->exit;
98     vlc_cond_t wait;
99
100     vlc_cond_init( &wait );
101
102     vlc_mutex_lock( &exit->lock );
103     exit->handler = exit_wakeup;
104     exit->opaque = &wait;
105     while( !exit->killed )
106         vlc_cond_wait( &wait, &exit->lock );
107     vlc_mutex_unlock( &exit->lock );
108
109     vlc_cond_destroy( &wait );
110 }