VLC  4.0.0-dev
mta_holder.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * mta_holder.c: Hold a MTA from another thread
3  *****************************************************************************
4  * Copyright (C) 2002-2017 the VideoLAN and AUTHORS
5  *
6  * Author: Hugo BeauzĂ©e-Luyssen <hugo@beauzee.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22 
23 #ifndef MTA_HOLDER_H
24 # define MTA_HOLDER_H
25 
26 #include <vlc_common.h>
27 
28 #include <assert.h>
29 #include <windows.h>
30 #include <objbase.h>
31 
32 typedef struct vlc_mta_holder
33 {
35  int i_refcount;
39 
40 static inline void* MtaMainLoop( void* opaque )
41 {
42  vlc_mta_holder* p_mta = (vlc_mta_holder*)opaque;
43  CoInitializeEx( NULL, COINIT_MULTITHREADED );
44 
45  vlc_sem_post( &p_mta->ready_sem );
46 
47  vlc_sem_wait( &p_mta->release_sem );
48 
49  CoUninitialize();
50  return NULL;
51 }
52 
53 /**
54  * Ensure an MTA context will be available until vlc_mta_release gets called.
55  *
56  * In the background, this will create a thread that does nothing but to keep the MTA
57  * refcount greater than 0.
58  *
59  * This is usefull in order not to commit a thread to a specific concurrency model.
60  * This function is win32 specific.
61  */
62 static inline bool vlc_mta_acquire( vlc_object_t *p_parent )
63 {
65 
66  vlc_global_lock( VLC_MTA_MUTEX );
67  vlc_mta_holder* p_mta = (vlc_mta_holder*)var_CreateGetAddress( vlc, "mta-holder" );
68  if ( p_mta == NULL )
69  {
70  p_mta = (vlc_mta_holder*)malloc( sizeof( *p_mta ) );
71  if ( unlikely( p_mta == NULL ) )
72  {
73  vlc_global_unlock( VLC_MTA_MUTEX );
74  return false;
75  }
76  vlc_sem_init( &p_mta->ready_sem, 0 );
77  vlc_sem_init( &p_mta->release_sem, 0 );
78  p_mta->i_refcount = 1;
79  if ( vlc_clone( &p_mta->thread, MtaMainLoop, p_mta, VLC_THREAD_PRIORITY_LOW ) )
80  {
81  free( p_mta );
82  p_mta = NULL;
83  vlc_global_unlock( VLC_MTA_MUTEX );
84  return false;
85  }
86  var_SetAddress( vlc, "mta-holder", p_mta );
87  vlc_sem_wait( &p_mta->ready_sem );
88  }
89  else
90  ++p_mta->i_refcount;
91  vlc_global_unlock( VLC_MTA_MUTEX );
92  return true;
93 }
94 
95 /**
96  * Releases a reference to the MTA holder.
97  *
98  * When its refcount reaches 0, the thread created by
99  */
100 static inline void vlc_mta_release( vlc_object_t* p_parent )
101 {
102  vlc_object_t *vlc = VLC_OBJECT(vlc_object_instance(p_parent));
103 
104  vlc_global_lock( VLC_MTA_MUTEX );
105  vlc_mta_holder *p_mta = (vlc_mta_holder*)var_InheritAddress( vlc, "mta-holder" );
106  assert( p_mta != NULL );
107  int i_refcount = --p_mta->i_refcount;
108  if ( i_refcount == 0 )
109  var_SetAddress( vlc, "mta-holder", NULL );
110  vlc_global_unlock( VLC_MTA_MUTEX );
111  if ( i_refcount == 0 )
112  {
113  vlc_sem_post( &p_mta->release_sem );
114 
115  vlc_join( p_mta->thread, NULL );
116 
117  free( p_mta );
118  }
119 }
120 
121 #endif
VLC_SYSDATA_DIR
@ VLC_SYSDATA_DIR
Global architecture-independent read-only data directory (e.g.
Definition: vlc_configuration.h:280
VLC_CACHE_DIR
@ VLC_CACHE_DIR
Definition: vlc_configuration.h:310
VLC_VIDEOS_DIR
@ VLC_VIDEOS_DIR
Definition: vlc_configuration.h:319
vlc_global_lock
#define vlc_global_lock(n)
Acquires a global mutex.
Definition: vlc_threads.h:1107
vlc_mta_acquire
static bool vlc_mta_acquire(vlc_object_t *p_parent)
Ensure an MTA context will be available until vlc_mta_release gets called.
Definition: mta_holder.h:62
vlc_mta_holder::release_sem
vlc_sem_t release_sem
Definition: mta_holder.h:57
VLC_PKG_LIB_DIR
@ VLC_PKG_LIB_DIR
Package-specific architecture-dependent read-only data directory (e.g.
Definition: vlc_configuration.h:275
vlc_sem_init
void vlc_sem_init(vlc_sem_t *sem, unsigned value)
Initializes a semaphore.
Definition: threads.c:442
unlikely
#define unlikely(p)
Predicted false condition.
Definition: vlc_common.h:227
vlc_common.h
VLC_DESKTOP_DIR
@ VLC_DESKTOP_DIR
Definition: vlc_configuration.h:312
VLC_THREAD_PRIORITY_LOW
#define VLC_THREAD_PRIORITY_LOW
Definition: vlc_threads.h:207
vlc_mta_release
static void vlc_mta_release(vlc_object_t *p_parent)
Releases a reference to the MTA holder.
Definition: mta_holder.h:100
config_GetAppDir
static char * config_GetAppDir(void)
Definition: dirs-uap.c:157
vlc_global_unlock
#define vlc_global_unlock(n)
Releases a global mutex.
Definition: vlc_threads.h:1112
vlc_charset.h
config_GetShellDir
static char * config_GetShellDir(vlc_userdir_t csidl)
Definition: dirs-uap.c:66
var_CreateGetAddress
static void * var_CreateGetAddress(vlc_object_t *p_obj, const char *psz_name)
Create an address variable with inherit and get its value.
Definition: vlc_variables.h:584
getenv
static char * getenv(const char *name)
Definition: vlc_fixups.h:292
vlc_mta_holder::ready_sem
vlc_sem_t ready_sem
Definition: mta_holder.h:56
vlc_mta_holder::thread
vlc_thread_t thread
Definition: mta_holder.h:54
asprintf
int asprintf(char **, const char *,...)
VLC_HOME_DIR
@ VLC_HOME_DIR
Definition: vlc_configuration.h:307
vlc_clone
int vlc_clone(vlc_thread_t *th, void *(*entry)(void *), void *data, int priority)
Creates and starts a new thread.
Definition: thread.c:144
vlc_assert_unreachable
#define vlc_assert_unreachable()
Impossible branch assertion.
Definition: vlc_common.h:253
config_GetUserDir
char * config_GetUserDir(vlc_userdir_t type)
Definition: dirs-uap.c:277
GetFolderName
static char * GetFolderName(IStorageFolder *folder)
Definition: dirs-uap.c:44
vlc_mta_holder
struct vlc_mta_holder vlc_mta_holder
VLC_LOCALE_DIR
@ VLC_LOCALE_DIR
Base directory for package read-only locale data.
Definition: vlc_configuration.h:288
VLC_DOCUMENTS_DIR
@ VLC_DOCUMENTS_DIR
Definition: vlc_configuration.h:316
VLC_PICTURES_DIR
@ VLC_PICTURES_DIR
Definition: vlc_configuration.h:318
VLC_CONFIG_DIR
@ VLC_CONFIG_DIR
Definition: vlc_configuration.h:308
MtaMainLoop
static void * MtaMainLoop(void *opaque)
Definition: mta_holder.h:40
vlc_thread_t
Thread handle.
Definition: vlc_threads.h:180
VLC_PKG_DATA_DIR
@ VLC_PKG_DATA_DIR
Package-specific architecture-independent read-only data directory (e.g.
Definition: vlc_configuration.h:273
VLC_PUBLICSHARE_DIR
@ VLC_PUBLICSHARE_DIR
Definition: vlc_configuration.h:315
vlc_sem_wait
void vlc_sem_wait(vlc_sem_t *sem)
Waits on a semaphore.
Definition: threads.c:463
vlc_mta_holder
Definition: mta_holder.h:32
vlc_object_t
VLC object common members.
Definition: vlc_objects.h:43
vlc_sem_t
Semaphore.
Definition: vlc_threads.h:449
strdup
char * strdup(const char *)
config_GetSysPath
char * config_GetSysPath(vlc_sysdir_t type, const char *filename)
Gets an installation directory.
Definition: dirs-uap.c:124
vlc_mta_holder::i_refcount
int i_refcount
Definition: mta_holder.h:55
config_GetDataDir
static char * config_GetDataDir(void)
Definition: dirs-uap.c:118
vlc_sysdir_t
enum vlc_system_dir vlc_sysdir_t
System directory identifiers.
VLC_DOWNLOAD_DIR
@ VLC_DOWNLOAD_DIR
Definition: vlc_configuration.h:313
vlc_sem_post
int vlc_sem_post(vlc_sem_t *sem)
Increments the value of a semaphore.
Definition: threads.c:447
var_InheritAddress
static void * var_InheritAddress(vlc_object_t *obj, const char *name)
Definition: vlc_variables.h:720
VLC_TEMPLATES_DIR
@ VLC_TEMPLATES_DIR
Definition: vlc_configuration.h:314
var_SetAddress
static int var_SetAddress(vlc_object_t *p_obj, const char *psz_name, void *ptr)
Set the value of a pointer variable.
Definition: vlc_variables.h:360
VLC_USERDATA_DIR
@ VLC_USERDATA_DIR
Definition: vlc_configuration.h:309
VLC_OBJECT
#define VLC_OBJECT(x)
Type-safe vlc_object_t cast.
Definition: vlc_objects.h:70
vlc_join
void vlc_join(vlc_thread_t handle, void **result)
Waits for a thread to complete (if needed), then destroys it.
Definition: thread.c:151
vlc_userdir_t
enum vlc_user_dir vlc_userdir_t
vlc_object_instance
#define vlc_object_instance(o)
Definition: vlc_objects.h:195
VLC_MUSIC_DIR
@ VLC_MUSIC_DIR
Definition: vlc_configuration.h:317
VLC_PKG_LIBEXEC_DIR
@ VLC_PKG_LIBEXEC_DIR
Package-specific executable read-only directory (e.g.
Definition: vlc_configuration.h:277