[PATCH v2 2/2] winegstreamer: Move broad callback handling code to gst_cbs.
Derek Lesho
dlesho at codeweavers.com
Fri Mar 20 14:56:48 CDT 2020
On 2020-03-20 14:54, Derek Lesho wrote:
> Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
> ---
> v2:
> - Mark more functions and variables as static.
> - Improve formatting
> - Remove redundant logging.
> ---
> dlls/winegstreamer/gst_cbs.c | 68 ++++++++++++++++++++++++++++++++++-
> dlls/winegstreamer/gst_cbs.h | 9 ++---
> dlls/winegstreamer/gstdemux.c | 60 +++----------------------------
> 3 files changed, 74 insertions(+), 63 deletions(-)
>
> diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c
> index 71c8180098..87f93d8af2 100644
> --- a/dlls/winegstreamer/gst_cbs.c
> +++ b/dlls/winegstreamer/gst_cbs.c
> @@ -20,10 +20,76 @@
>
> #include <gst/gst.h>
>
> +#include "objbase.h"
> +
> #include "wine/list.h"
>
> #include "gst_cbs.h"
>
> +static pthread_key_t wine_gst_key;
> +
> +void mark_wine_thread(void)
> +{
> + /* set it to non-NULL to indicate that this is a Wine thread */
> + pthread_setspecific(wine_gst_key, &wine_gst_key);
> +}
> +
> +static BOOL is_wine_thread(void)
> +{
> + return pthread_getspecific(wine_gst_key) != NULL;
> +}
> +
> +static pthread_mutex_t cb_list_lock = PTHREAD_MUTEX_INITIALIZER;
> +static pthread_cond_t cb_list_cond = PTHREAD_COND_INITIALIZER;
> +static struct list cb_list = LIST_INIT(cb_list);
> +
> +static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user)
> +{
> + struct cb_data *cbdata = user;
> +
> + if (cbdata->type < GSTDEMUX_MAX)
> + perform_cb_gstdemux(cbdata);
> +
> + pthread_mutex_lock(&cbdata->lock);
> + cbdata->finished = 1;
> + pthread_cond_broadcast(&cbdata->cond);
> + pthread_mutex_unlock(&cbdata->lock);
> +}
> +
> +static DWORD WINAPI dispatch_thread(void *user)
> +{
> + struct cb_data *cbdata;
> +
> + CoInitializeEx(NULL, COINIT_MULTITHREADED);
> +
> + pthread_mutex_lock(&cb_list_lock);
> +
> + while (1)
> + {
> + pthread_cond_wait(&cb_list_cond, &cb_list_lock);
> +
> + while (!list_empty(&cb_list))
> + {
> + cbdata = LIST_ENTRY(list_head(&cb_list), struct cb_data, entry);
> + list_remove(&cbdata->entry);
> +
> + TrySubmitThreadpoolCallback(&perform_cb, cbdata, NULL);
> + }
> + }
> +
> + pthread_mutex_unlock(&cb_list_lock);
> +
> + CoUninitialize();
> +
> + return 0;
> +}
> +
> +static void start_dispatch_thread(void)
Oops, just realized that this is a public function exposed through
gst_private.h, so it shouldn't be marked static.
> +{
> + pthread_key_create(&wine_gst_key, NULL);
> + CloseHandle(CreateThread(NULL, 0, &dispatch_thread, NULL, 0, NULL));
> +}
> +
> /* gstreamer calls our callbacks from threads that Wine did not create. Some
> * callbacks execute code which requires Wine to have created the thread
> * (critical sections, debug logging, dshow client code). Since gstreamer can't
> @@ -31,7 +97,7 @@
> * callbacks in code which avoids the Wine thread requirement, and then
> * dispatch those callbacks on a thread that is known to be created by Wine.
> *
> - * This file must not contain any code that depends on the Wine TEB!
> + * This thread must not run any code that depends on the Wine TEB!
> */
>
> static void call_cb(struct cb_data *cbdata)
> diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h
> index b3e2b237bb..4725f23ad1 100644
> --- a/dlls/winegstreamer/gst_cbs.h
> +++ b/dlls/winegstreamer/gst_cbs.h
> @@ -42,7 +42,8 @@ enum CB_TYPE {
> REMOVED_DECODED_PAD,
> AUTOPLUG_BLACKLIST,
> UNKNOWN_TYPE,
> - QUERY_SINK
> + QUERY_SINK,
> + GSTDEMUX_MAX
> };
>
> struct cb_data {
> @@ -135,12 +136,8 @@ struct cb_data {
> struct list entry;
> };
>
> -extern pthread_mutex_t cb_list_lock DECLSPEC_HIDDEN;
> -extern pthread_cond_t cb_list_cond DECLSPEC_HIDDEN;
> -extern struct list cb_list DECLSPEC_HIDDEN;
> -void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) DECLSPEC_HIDDEN;
> -BOOL is_wine_thread(void) DECLSPEC_HIDDEN;
> void mark_wine_thread(void) DECLSPEC_HIDDEN;
> +void perform_cb_gstdemux(struct cb_data *data) DECLSPEC_HIDDEN;
>
> GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) DECLSPEC_HIDDEN;
> void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN;
> diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
> index 3a29a03499..3c8d0d48b7 100644
> --- a/dlls/winegstreamer/gstdemux.c
> +++ b/dlls/winegstreamer/gstdemux.c
> @@ -43,8 +43,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
>
> static const GUID MEDIASUBTYPE_CVID = {mmioFOURCC('c','v','i','d'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
>
> -static pthread_key_t wine_gst_key;
> -
> struct gstdemux
> {
> struct strmbase_filter filter;
> @@ -100,17 +98,6 @@ static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface);
> static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface);
> static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface);
>
> -void mark_wine_thread(void)
> -{
> - /* set it to non-NULL to indicate that this is a Wine thread */
> - pthread_setspecific(wine_gst_key, &wine_gst_key);
> -}
> -
> -BOOL is_wine_thread(void)
> -{
> - return pthread_getspecific(wine_gst_key) != NULL;
> -}
> -
> static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE *amt)
> {
> WAVEFORMATEXTENSIBLE *wfe;
> @@ -2168,14 +2155,8 @@ static HRESULT GST_RemoveOutputPins(struct gstdemux *This)
> return S_OK;
> }
>
> -pthread_mutex_t cb_list_lock = PTHREAD_MUTEX_INITIALIZER;
> -pthread_cond_t cb_list_cond = PTHREAD_COND_INITIALIZER;
> -struct list cb_list = LIST_INIT(cb_list);
> -
> -void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user)
> +void perform_cb_gstdemux(struct cb_data *cbdata)
> {
> - struct cb_data *cbdata = user;
> -
> switch(cbdata->type)
> {
> case WATCH_BUS:
> @@ -2259,44 +2240,11 @@ void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user)
> data->query);
> break;
> }
> - }
> -
> - pthread_mutex_lock(&cbdata->lock);
> - cbdata->finished = 1;
> - pthread_cond_broadcast(&cbdata->cond);
> - pthread_mutex_unlock(&cbdata->lock);
> -}
> -
> -static DWORD WINAPI dispatch_thread(void *user)
> -{
> - struct cb_data *cbdata;
> -
> - CoInitializeEx(NULL, COINIT_MULTITHREADED);
> -
> - pthread_mutex_lock(&cb_list_lock);
> -
> - while(1){
> - pthread_cond_wait(&cb_list_cond, &cb_list_lock);
> -
> - while(!list_empty(&cb_list)){
> - cbdata = LIST_ENTRY(list_head(&cb_list), struct cb_data, entry);
> - list_remove(&cbdata->entry);
> -
> - TrySubmitThreadpoolCallback(&perform_cb, cbdata, NULL);
> + default:
> + {
> + assert(0);
> }
> }
> -
> - pthread_mutex_unlock(&cb_list_lock);
> -
> - CoUninitialize();
> -
> - return 0;
> -}
> -
> -void start_dispatch_thread(void)
> -{
> - pthread_key_create(&wine_gst_key, NULL);
> - CloseHandle(CreateThread(NULL, 0, &dispatch_thread, NULL, 0, NULL));
> }
>
> static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
More information about the wine-devel
mailing list