[vlc-devel] [PATCH 1/2] win32: Add a vlc_mta_holder
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Fri Jun 23 13:00:27 CEST 2017
On Fri, Jun 23, 2017, at 12:58 PM, Hugo Beauzée-Luyssen wrote:
> This small helper will hold on to the MTA to ensure it won't be
> destroyed between two calls to CoInitializeEx.
> This will help us not leaking our TA configurations to libvlc/libvlccore
> threads
> ---
> include/vlc_threads.h | 1 +
> src/Makefile.am | 2 +-
> src/misc/threads.c | 1 +
> src/win32/mta_holder.h | 121
> +++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 124 insertions(+), 1 deletion(-)
> create mode 100644 src/win32/mta_holder.h
>
> diff --git a/include/vlc_threads.h b/include/vlc_threads.h
> index 9911d2eacf..fdf1dc4a9d 100644
> --- a/include/vlc_threads.h
> +++ b/include/vlc_threads.h
> @@ -1053,6 +1053,7 @@ enum
> VLC_XLIB_MUTEX,
> VLC_MOSAIC_MUTEX,
> VLC_HIGHLIGHT_MUTEX,
> + VLC_MTA_MUTEX,
> /* Insert new entry HERE */
> VLC_MAX_MUTEX
> };
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 87cf8e3e29..c93a4021ee 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -468,7 +468,7 @@ libvlccore_la_LDFLAGS = \
> libvlccore_la_DEPENDENCIES = libvlccore.sym
> if HAVE_WIN32
> libvlccore_la_DEPENDENCIES += libvlc_win32_rc.$(OBJEXT)
> -libvlccore_la_LDFLAGS += -Wl,libvlc_win32_rc.$(OBJEXT) -avoid-version
> -Wc,-static
> +libvlccore_la_LDFLAGS += -Wl,libvlc_win32_rc.$(OBJEXT) -avoid-version
> -Wc,-static $(LIBCOM)
> endif
> if HAVE_OS2
> libvlccore_la_LDFLAGS += -avoid-version
> diff --git a/src/misc/threads.c b/src/misc/threads.c
> index dc8b89f702..f95a06c0e6 100644
> --- a/src/misc/threads.c
> +++ b/src/misc/threads.c
> @@ -37,6 +37,7 @@ void vlc_global_mutex (unsigned n, bool acquire)
> VLC_STATIC_MUTEX,
> VLC_STATIC_MUTEX,
> VLC_STATIC_MUTEX,
> + VLC_STATIC_MUTEX,
> };
> static_assert (VLC_MAX_MUTEX == (sizeof (locks) / sizeof
> (locks[0])),
> "Wrong number of global mutexes");
> diff --git a/src/win32/mta_holder.h b/src/win32/mta_holder.h
> new file mode 100644
> index 0000000000..e5f4523b0a
> --- /dev/null
> +++ b/src/win32/mta_holder.h
> @@ -0,0 +1,121 @@
> +/*****************************************************************************
> + * mta_holder.c: Hold a MTA from another thread
> +
> *****************************************************************************
> + * Copyright (C) 2002-2017 the VideoLAN and AUTHORS
> + *
> + * Author: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
> 02110-1301, USA.
> +
> *****************************************************************************/
> +
> +#ifndef MTA_HOLDER_H
> +# define MTA_HOLDER_H
> +
> +#include <vlc_common.h>
> +
> +#include <assert.h>
> +#include <windows.h>
> +#include <objbase.h>
> +
> +typedef struct vlc_mta_holder
> +{
> + vlc_thread_t thread;
> + int i_refcount;
> + vlc_sem_t ready_sem;
> + vlc_sem_t release_sem;
> +} vlc_mta_holder;
> +
> +static inline void* MtaMainLoop( void* opaque )
> +{
> + vlc_mta_holder* p_mta = (vlc_mta_holder*)opaque;
> + CoInitializeEx( NULL, COINIT_MULTITHREADED );
> +
> + vlc_sem_post( &p_mta->ready_sem );
> +
> + vlc_sem_wait( &p_mta->release_sem );
> +
> + CoUninitialize();
> + return NULL;
> +}
> +
> +/**
> + * Ensure an MTA context will be available until vlc_mta_release gets
> called.
> + *
> + * In the background, this will create a thread that does nothing but to
> keep the MTA
> + * refcount greater than 0.
> + *
> + * This is usefull in order not to commit a thread to a specific
> concurrency model.
> + * This function is win32 specific.
> + */
> +static inline vlc_mta_holder* vlc_mta_acquire( vlc_object_t *p_parent )
> +{
> + vlc_global_lock( VLC_MTA_MUTEX );
> + vlc_mta_holder* p_mta = (vlc_mta_holder*)var_CreateGetAddress(
> p_parent->obj.libvlc, "mta-holder" );
> + if ( p_mta == NULL )
> + {
> + p_mta = (vlc_mta_holder*)malloc( sizeof( *p_mta ) );
> + if ( unlikely( p_mta == NULL ) )
> + {
> + vlc_global_unlock( VLC_MTA_MUTEX );
> + return NULL;
> + }
> + vlc_sem_init( &p_mta->ready_sem, 0 );
> + vlc_sem_init( &p_mta->release_sem, 0 );
> + p_mta->i_refcount = 1;
> + if ( vlc_clone( &p_mta->thread, MtaMainLoop, p_mta,
> VLC_THREAD_PRIORITY_LOW ) )
> + {
> + vlc_sem_destroy( &p_mta->release_sem );
> + vlc_sem_destroy( &p_mta->ready_sem );
> + free( p_mta );
> + p_mta = NULL;
> + vlc_global_unlock( VLC_MTA_MUTEX );
> + return NULL;
> + }
> + var_SetAddress( p_parent->obj.libvlc, "mta-holder", p_mta );
> + vlc_sem_wait( &p_mta->ready_sem );
> + }
> + else
> + ++p_mta->i_refcount;
> + vlc_global_unlock( VLC_MTA_MUTEX );
> + return p_mta;
> +}
> +
> +/**
> + * Releases a reference to the MTA holder.
> + *
> + * When its refcount reaches 0, the thread created by
> + */
> +static inline void vlc_mta_release( vlc_object_t* p_parent )
> +{
> + vlc_global_lock( VLC_MTA_MUTEX );
> + vlc_mta_holder *p_mta = (vlc_mta_holder*)var_InheritAddress(
> p_parent->obj.libvlc, "mta-holder" );
> + assert( p_mta != NULL );
> + int i_refcount = --p_mta->i_refcount;
> + if ( i_refcount == 0 )
> + var_SetAddress( p_parent->obj.libvlc, "mta-holder", NULL );
> + vlc_global_unlock( VLC_MTA_MUTEX );
> + if ( i_refcount == 0 )
> + {
> + vlc_sem_post( &p_mta->release_sem );
> +
> + vlc_join( p_mta->thread, NULL );
> +
> + vlc_sem_destroy( &p_mta->release_sem );
> + vlc_sem_destroy( &p_mta->ready_sem );
> + free( p_mta );
> + }
> +}
> +
> +#endif
> --
> 2.11.0
>
Woops, I forgot to include the changes in this revision:
- Give up on VLC_ADDRESS_EXCHANGE
- Use vlc_global_lock
- Use a semaphore instead of a condition variable to wait for MTA to be
released
Regards,
--
Hugo Beauzée-Luyssen
hugo at beauzee.fr
More information about the vlc-devel
mailing list