Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 0a58da1669740c6e14f80cc0da7af6f3f4dbca22 Mon Sep 17 00:00:00 2001
- From: Andrew Eikum <aeikum@codeweavers.com>
- Date: Tue, 17 Nov 2015 12:21:22 -0600
- Subject: winegstreamer: Use gstreamer threadpool API to create new Wine
- threads
- To: wine-patches <wine-patches@winehq.org>
- Reply-To: wine-devel <wine-devel@winehq.org>,Andrew Eikum <aeikum@codeweavers.com>
- MIME-Version: 1.0
- Content-Type: multipart/mixed; boundary="------------2.6.2"
- This is a multi-part message in MIME format.
- --------------2.6.2
- Content-Type: text/plain; charset=UTF-8; format=fixed
- Content-Transfer-Encoding: 8bit
- ---
- dlls/winegstreamer/Makefile.in | 6 +-
- dlls/winegstreamer/glibthread.c | 390 ---------------------------------------
- dlls/winegstreamer/gst_private.h | 5 +-
- dlls/winegstreamer/gstdemux.c | 37 +++-
- dlls/winegstreamer/main.c | 4 +-
- dlls/winegstreamer/threadpool.c | 128 +++++++++++++
- include/winbase.h | 1 +
- 7 files changed, 171 insertions(+), 400 deletions(-)
- delete mode 100644 dlls/winegstreamer/glibthread.c
- create mode 100644 dlls/winegstreamer/threadpool.c
- --------------2.6.2
- Content-Type: text/x-patch; name="0001-winegstreamer-Use-gstreamer-threadpool-API-to-create.patch"
- Content-Transfer-Encoding: 8bit
- Content-Disposition: inline; filename="0001-winegstreamer-Use-gstreamer-threadpool-API-to-create.patch"
- diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
- index 0c14ffd..8e791f3 100644
- --- a/dlls/winegstreamer/Makefile.in
- +++ b/dlls/winegstreamer/Makefile.in
- @@ -1,13 +1,13 @@
- MODULE = winegstreamer.dll
- IMPORTS = strmbase strmiids uuid winmm msacm32 msvfw32 ole32 oleaut32 user32 gdi32 advapi32
- EXTRAINCL = $(GSTREAMER_CFLAGS)
- -EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
- +EXTRALIBS = $(GSTREAMER_LIBS)
- C_SRCS = \
- - glibthread.c \
- gstdemux.c \
- gsttffilter.c \
- - main.c
- + main.c \
- + threadpool.c
- RC_SRCS = \
- rsrc.rc
- diff --git a/dlls/winegstreamer/glibthread.c b/dlls/winegstreamer/glibthread.c
- deleted file mode 100644
- index 0d829a0..0000000
- --- a/dlls/winegstreamer/glibthread.c
- +++ /dev/null
- @@ -1,390 +0,0 @@
- -/* GLIB - Library of useful routines for C programming
- - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- - *
- - * Wine GStreamer integration
- - * Copyright 2010 Aric Stewart, CodeWeavers
- - *
- - * gthread.c: solaris thread system implementation
- - * Copyright 1998-2001 Sebastian Wilhelmi; University of Karlsruhe
- - * Copyright 2001 Hans Breuer
- - *
- - * This library is free software; you can redistribute it and/or
- - * modify it under the terms of the GNU Lesser General Public
- - * License as published by the Free Software Foundation; either
- - * version 2.1 of the License, or (at your option) any later version.
- - *
- - * This library 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
- - * Lesser General Public License for more details.
- - *
- - * You should have received a copy of the GNU Lesser General Public
- - * License along with this library; if not, write to the Free Software
- - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- - */
- -
- -/*
- - * Modified by the GLib Team and others 1997-2000. See the AUTHORS
- - * file for a list of people on the GLib Team. See the ChangeLog
- - * files for a list of changes. These files are distributed with
- - * GLib at ftp://ftp.gtk.org/pub/gtk/.
- - */
- -
- -#include "config.h"
- -
- -#ifdef HAVE_PTHREAD_H
- -#include <pthread.h>
- -#endif
- -
- -#include <glib.h>
- -
- -#include <errno.h>
- -#include <stdarg.h>
- -#include <stdlib.h>
- -#include <stdio.h>
- -
- -#include "windef.h"
- -#include "winbase.h"
- -#include "winnls.h"
- -#include "wine/debug.h"
- -
- -WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
- -
- -static gchar *
- -g_win32_error_message (gint error)
- -{
- - gchar *retval;
- - WCHAR *msg = NULL;
- - int nchars;
- -
- - FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
- - |FORMAT_MESSAGE_IGNORE_INSERTS
- - |FORMAT_MESSAGE_FROM_SYSTEM,
- - NULL, error, 0,
- - (LPWSTR) &msg, 0, NULL);
- - if (msg != NULL)
- - {
- - nchars = WideCharToMultiByte(CP_UTF8, 0, msg, -1, NULL, 0, NULL, NULL);
- -
- - if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r')
- - msg[nchars-2] = '\0';
- -
- - retval = g_utf16_to_utf8 (msg, -1, NULL, NULL, NULL);
- -
- - LocalFree (msg);
- - }
- - else
- - retval = g_strdup ("");
- -
- - return retval;
- -}
- -
- -static gint g_thread_priority_map [G_THREAD_PRIORITY_URGENT + 1] = {
- - THREAD_PRIORITY_BELOW_NORMAL,
- - THREAD_PRIORITY_NORMAL,
- - THREAD_PRIORITY_ABOVE_NORMAL,
- - THREAD_PRIORITY_HIGHEST
- -};
- -
- -static DWORD g_thread_self_tls;
- -
- -/* A "forward" declaration of this structure */
- -static GThreadFunctions g_thread_functions_for_glib_use_default;
- -
- -typedef struct _GThreadData GThreadData;
- -struct _GThreadData
- -{
- - GThreadFunc func;
- - gpointer data;
- - HANDLE thread;
- - gboolean joinable;
- -};
- -
- -static GMutex *
- -g_mutex_new_posix_impl (void)
- -{
- - GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
- - pthread_mutex_init ((pthread_mutex_t *) result, NULL);
- - return result;
- -}
- -
- -static void
- -g_mutex_free_posix_impl (GMutex * mutex)
- -{
- - pthread_mutex_destroy ((pthread_mutex_t *) mutex);
- - g_free (mutex);
- -}
- -
- -/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
- - functions from gmem.c and gmessages.c; */
- -
- -/* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as
- - signature and semantic are right, but without error check then!!!!,
- - we might want to change this therefore. */
- -
- -static gboolean
- -g_mutex_trylock_posix_impl (GMutex * mutex)
- -{
- - int result;
- -
- - result = pthread_mutex_trylock ((pthread_mutex_t *) mutex);
- -
- - if (result == EBUSY)
- - return FALSE;
- -
- - if (result) ERR("pthread_mutex_trylock %x\n",result);
- - return TRUE;
- -}
- -
- -static GCond *
- -g_cond_new_posix_impl (void)
- -{
- - GCond *result = (GCond *) g_new (pthread_cond_t, 1);
- - pthread_cond_init ((pthread_cond_t *) result, NULL);
- - return result;
- -}
- -
- -/* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait
- - can be taken directly, as signature and semantic are right, but
- - without error check then!!!!, we might want to change this
- - therefore. */
- -
- -#define G_NSEC_PER_SEC 1000000000
- -
- -static gboolean
- -g_cond_timed_wait_posix_impl (GCond * cond,
- - GMutex * entered_mutex,
- - GTimeVal * abs_time)
- -{
- - int result;
- - struct timespec end_time;
- - gboolean timed_out;
- -
- - g_return_val_if_fail (cond != NULL, FALSE);
- - g_return_val_if_fail (entered_mutex != NULL, FALSE);
- -
- - if (!abs_time)
- - {
- - result = pthread_cond_wait ((pthread_cond_t *)cond,
- - (pthread_mutex_t *) entered_mutex);
- - timed_out = FALSE;
- - }
- - else
- - {
- - end_time.tv_sec = abs_time->tv_sec;
- - end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);
- -
- - g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);
- -
- - result = pthread_cond_timedwait ((pthread_cond_t *) cond,
- - (pthread_mutex_t *) entered_mutex,
- - &end_time);
- - timed_out = (result == ETIMEDOUT);
- - }
- -
- - if (!timed_out)
- - if (result) ERR("pthread_cond_timedwait %x\n",result);
- -
- - return !timed_out;
- -}
- -
- -static void
- -g_cond_free_posix_impl (GCond * cond)
- -{
- - pthread_cond_destroy ((pthread_cond_t *) cond);
- - g_free (cond);
- -}
- -
- -static GPrivate *
- -g_private_new_posix_impl (GDestroyNotify destructor)
- -{
- - GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1);
- - pthread_key_create ((pthread_key_t *) result, destructor);
- - return result;
- -}
- -
- -/* NOTE: the functions g_private_get and g_private_set may not use
- - functions from gmem.c and gmessages.c */
- -
- -static void
- -g_private_set_posix_impl (GPrivate * private_key, gpointer value)
- -{
- - if (!private_key)
- - return;
- - pthread_setspecific (*(pthread_key_t *) private_key, value);
- -}
- -
- -static gpointer
- -g_private_get_posix_impl (GPrivate * private_key)
- -{
- - if (!private_key)
- - return NULL;
- - return pthread_getspecific (*(pthread_key_t *) private_key);
- -}
- -
- -static void
- -g_thread_set_priority_win32_impl (gpointer thread, GThreadPriority priority)
- -{
- - GThreadData *target = *(GThreadData **)thread;
- -
- - g_return_if_fail ((int)priority >= G_THREAD_PRIORITY_LOW);
- - g_return_if_fail ((int)priority <= G_THREAD_PRIORITY_URGENT);
- -
- - SetThreadPriority (target->thread, g_thread_priority_map [priority]);
- -}
- -
- -static void
- -g_thread_self_win32_impl (gpointer thread)
- -{
- - GThreadData *self = TlsGetValue (g_thread_self_tls);
- -
- - if (!self)
- - {
- - /* This should only happen for the main thread! */
- - HANDLE handle = GetCurrentThread ();
- - HANDLE process = GetCurrentProcess ();
- - self = g_new (GThreadData, 1);
- - DuplicateHandle (process, handle, process, &self->thread, 0, FALSE,
- - DUPLICATE_SAME_ACCESS);
- - TlsSetValue (g_thread_self_tls, self);
- - self->func = NULL;
- - self->data = NULL;
- - self->joinable = FALSE;
- - }
- -
- - *(GThreadData **)thread = self;
- -}
- -
- -static void
- -g_thread_exit_win32_impl (void)
- -{
- - GThreadData *self = TlsGetValue (g_thread_self_tls);
- -
- - if (self)
- - {
- - if (!self->joinable)
- - {
- - CloseHandle (self->thread);
- - g_free (self);
- - }
- - TlsSetValue (g_thread_self_tls, NULL);
- - }
- -
- - ExitThread (0);
- -}
- -
- -static guint __stdcall
- -g_thread_proxy (gpointer data)
- -{
- - GThreadData *self = (GThreadData*) data;
- -
- - TlsSetValue (g_thread_self_tls, self);
- -
- - self->func (self->data);
- -
- - g_thread_exit_win32_impl ();
- -
- - g_assert_not_reached ();
- -
- - return 0;
- -}
- -
- -static void
- -g_thread_create_win32_impl (GThreadFunc func,
- - gpointer data,
- - gulong stack_size,
- - gboolean joinable,
- - gboolean bound,
- - GThreadPriority priority,
- - gpointer thread,
- - GError **error)
- -{
- - guint ignore;
- - GThreadData *retval;
- -
- - g_return_if_fail (func);
- - g_return_if_fail ((int)priority >= G_THREAD_PRIORITY_LOW);
- - g_return_if_fail ((int)priority <= G_THREAD_PRIORITY_URGENT);
- -
- - retval = g_new(GThreadData, 1);
- - retval->func = func;
- - retval->data = data;
- -
- - retval->joinable = joinable;
- -
- - retval->thread = (HANDLE) CreateThread (NULL, stack_size, g_thread_proxy,
- - retval, 0, &ignore);
- -
- - if (retval->thread == NULL)
- - {
- - gchar *win_error = g_win32_error_message (GetLastError ());
- - g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
- - "Error creating thread: %s", win_error);
- - g_free (retval);
- - g_free (win_error);
- - return;
- - }
- -
- - *(GThreadData **)thread = retval;
- -
- - g_thread_set_priority_win32_impl (thread, priority);
- -}
- -
- -static void
- -g_thread_yield_win32_impl (void)
- -{
- - Sleep(0);
- -}
- -
- -static void
- -g_thread_join_win32_impl (gpointer thread)
- -{
- - GThreadData *target = *(GThreadData **)thread;
- -
- - g_return_if_fail (target->joinable);
- -
- - WaitForSingleObject (target->thread, INFINITE);
- -
- - CloseHandle (target->thread);
- - g_free (target);
- -}
- -
- -static GThreadFunctions g_thread_functions_for_glib_use_default =
- -{
- - /* Posix functions here for speed */
- - g_mutex_new_posix_impl,
- - (void (*)(GMutex *)) pthread_mutex_lock,
- - g_mutex_trylock_posix_impl,
- - (void (*)(GMutex *)) pthread_mutex_unlock,
- - g_mutex_free_posix_impl,
- - g_cond_new_posix_impl,
- - (void (*)(GCond *)) pthread_cond_signal,
- - (void (*)(GCond *)) pthread_cond_broadcast,
- - (void (*)(GCond *, GMutex *)) pthread_cond_wait,
- - g_cond_timed_wait_posix_impl,
- - g_cond_free_posix_impl,
- - g_private_new_posix_impl,
- - g_private_get_posix_impl,
- - g_private_set_posix_impl,
- - /* win32 function required here */
- - g_thread_create_win32_impl, /* thread */
- - g_thread_yield_win32_impl,
- - g_thread_join_win32_impl,
- - g_thread_exit_win32_impl,
- - g_thread_set_priority_win32_impl,
- - g_thread_self_win32_impl,
- - NULL /* no equal function necessary */
- -};
- -
- -void g_thread_impl_init (void)
- -{
- - static gboolean beenhere = FALSE;
- -
- - if (beenhere)
- - return;
- -
- - beenhere = TRUE;
- -
- - g_thread_self_tls = TlsAlloc ();
- - g_thread_init(&g_thread_functions_for_glib_use_default);
- -}
- diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
- index d041d64..c74bad3 100644
- --- a/dlls/winegstreamer/gst_private.h
- +++ b/dlls/winegstreamer/gst_private.h
- @@ -42,6 +42,9 @@ IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *pUnkOuter, HRESULT *phr);
- IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *pUnkOuter, HRESULT *phr);
- IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr);
- -void g_thread_impl_init(void);
- DWORD Gstreamer_init(void);
- +
- +GstTaskPool *wine_gst_pool_new(void) DECLSPEC_HIDDEN;
- +extern GstTaskPool *wine_gst_pool DECLSPEC_HIDDEN;
- +
- #endif /* __GST_PRIVATE_INCLUDED__ */
- diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
- index c17fc2f..6876717 100644
- --- a/dlls/winegstreamer/gstdemux.c
- +++ b/dlls/winegstreamer/gstdemux.c
- @@ -888,20 +888,47 @@ static GstBusSyncReply watch_bus(GstBus *bus, GstMessage *msg, gpointer data) {
- GSTImpl *This = data;
- GError *err = NULL;
- gchar *dbg_info = NULL;
- +
- + if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_STREAM_STATUS) {
- + GstStreamStatusType type;
- + GstElement *owner;
- + const GValue *val;
- +
- + gst_message_parse_stream_status(msg, &type, &owner);
- +
- + val = gst_message_get_stream_status_object(msg);
- +
- + if (val && G_VALUE_TYPE(val) == GST_TYPE_TASK) {
- + GstTask *task = g_value_get_object(val);
- + if (task && type == GST_STREAM_STATUS_TYPE_CREATE)
- + gst_task_set_pool(task, wine_gst_pool);
- + }
- +
- + return GST_BUS_PASS;
- + }
- +
- if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_ERROR) {
- gst_message_parse_error(msg, &err, &dbg_info);
- FIXME("%s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
- WARN("%s\n", dbg_info);
- SetEvent(This->event);
- - } else if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_WARNING) {
- + if (err)
- + g_error_free(err);
- + g_free(dbg_info);
- + return GST_BUS_DROP;
- + }
- +
- + if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_WARNING) {
- gst_message_parse_warning(msg, &err, &dbg_info);
- WARN("%s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
- WARN("%s\n", dbg_info);
- + if (err)
- + g_error_free(err);
- + g_free(dbg_info);
- + return GST_BUS_DROP;
- }
- - if (err)
- - g_error_free(err);
- - g_free(dbg_info);
- - return GST_BUS_DROP;
- +
- + return GST_BUS_PASS;
- }
- static void unknown_type(GstElement *bin, GstPad *pad, GstCaps *caps, GSTImpl *This) {
- diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
- index 4f0e84f..6dcbf2f 100644
- --- a/dlls/winegstreamer/main.c
- +++ b/dlls/winegstreamer/main.c
- @@ -210,6 +210,8 @@ FactoryTemplate const g_Templates[] = {
- const int g_cTemplates = sizeof(g_Templates) / sizeof (g_Templates[0]);
- +GstTaskPool *wine_gst_pool = NULL;
- +
- BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
- {
- if (fdwReason == DLL_PROCESS_ATTACH)
- @@ -254,7 +256,7 @@ DWORD Gstreamer_init(void) {
- argv[0] = argv0;
- argv[1] = argv1;
- argv[2] = NULL;
- - g_thread_impl_init();
- + wine_gst_pool = wine_gst_pool_new();
- inited = gst_init_check(&argc, &argv, &err);
- HeapFree(GetProcessHeap(), 0, argv);
- if (err) {
- diff --git a/dlls/winegstreamer/threadpool.c b/dlls/winegstreamer/threadpool.c
- new file mode 100644
- index 0000000..552c926
- --- /dev/null
- +++ b/dlls/winegstreamer/threadpool.c
- @@ -0,0 +1,128 @@
- +/*
- + * Copyright 2015 Andrew Eikum for CodeWeavers
- + *
- + * This library is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU Lesser General Public
- + * License as published by the Free Software Foundation; either
- + * version 2.1 of the License, or (at your option) any later version.
- + *
- + * This library 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
- + * Lesser General Public License for more details.
- + *
- + * You should have received a copy of the GNU Lesser General Public
- + * License along with this library; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- + */
- +
- +#include "config.h"
- +
- +#include <gst/gst.h>
- +
- +#include "windef.h"
- +#include "winbase.h"
- +#include "winnls.h"
- +#include "wine/debug.h"
- +
- +WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
- +
- +#define WINE_GST_POOL (wine_gst_pool_get_type())
- +
- +typedef struct _WineGstPool {
- + GstTaskPool obj;
- +} WineGstPool;
- +
- +typedef struct _WineGstPoolClass {
- + GstTaskPoolClass parent_class;
- +} WineGstPoolClass;
- +
- +G_DEFINE_TYPE(WineGstPool, wine_gst_pool, GST_TYPE_TASK_POOL);
- +
- +static void wine_gst_pool_prepare(GstTaskPool *gstpool, GError **err)
- +{
- + /* noop */
- +}
- +
- +static void wine_gst_pool_cleanup(GstTaskPool *gstpool)
- +{
- + /* noop */
- +}
- +
- +typedef struct _thunk_data {
- + GstTaskPoolFunction fn;
- + gpointer data;
- +} thunk_data;
- +
- +typedef struct _WineGstWork {
- + TP_WORK *tp_work;
- + thunk_data userdata;
- +} WineGstWork;
- +
- +static void CALLBACK workfn(TP_CALLBACK_INSTANCE *instance, void *user,
- + TP_WORK *work)
- +{
- + thunk_data *data = user;
- +
- + data->fn(data->data);
- +}
- +
- +static gpointer wine_gst_pool_push(GstTaskPool *gstpool, GstTaskPoolFunction fn,
- + gpointer data, GError **err)
- +{
- + /* make new thread */
- + WineGstWork *work;
- +
- + work = HeapAlloc(GetProcessHeap(), 0, sizeof(*work));
- +
- + work->userdata.data = data;
- + work->userdata.fn = fn;
- +
- + work->tp_work = CreateThreadpoolWork(&workfn, &work->userdata, NULL);
- +
- + SubmitThreadpoolWork(work->tp_work);
- +
- + return work;
- +}
- +
- +static void wine_gst_pool_join(GstTaskPool *gstpool, gpointer id)
- +{
- + /* wait for thread */
- + WineGstWork *work = id;
- +
- + WaitForThreadpoolWorkCallbacks(work->tp_work, FALSE);
- + CloseThreadpoolWork(work->tp_work);
- +
- + HeapFree(GetProcessHeap(), 0, work);
- +}
- +
- +static void wine_gst_pool_init(WineGstPool *pool)
- +{
- + /* noop */
- +}
- +
- +static void wine_gst_pool_finalize(GObject *obj)
- +{
- + G_OBJECT_CLASS(wine_gst_pool_parent_class)->finalize(obj);
- +}
- +
- +static void wine_gst_pool_class_init(WineGstPoolClass *klass)
- +{
- + GObjectClass *gobj_class;
- + GstTaskPoolClass *gsttaskpool_class;
- +
- + gobj_class = (GObjectClass*)klass;
- + gsttaskpool_class = (GstTaskPoolClass*)klass;
- +
- + gobj_class->finalize = wine_gst_pool_finalize;
- +
- + gsttaskpool_class->prepare = wine_gst_pool_prepare;
- + gsttaskpool_class->cleanup = wine_gst_pool_cleanup;
- + gsttaskpool_class->push = wine_gst_pool_push;
- + gsttaskpool_class->join = wine_gst_pool_join;
- +}
- +
- +GstTaskPool *wine_gst_pool_new(void)
- +{
- + return g_object_new(WINE_GST_POOL, NULL);
- +}
- diff --git a/include/winbase.h b/include/winbase.h
- index 7216086..7a9a02e 100644
- --- a/include/winbase.h
- +++ b/include/winbase.h
- @@ -2577,6 +2577,7 @@ WINBASEAPI DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,BOOL,DW
- WINBASEAPI DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE*,BOOL,DWORD,BOOL);
- WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE,DWORD);
- WINBASEAPI DWORD WINAPI WaitForSingleObjectEx(HANDLE,DWORD,BOOL);
- +WINBASEAPI VOID WINAPI WaitForThreadpoolWorkCallbacks(TP_WORK*,BOOL);
- WINBASEAPI BOOL WINAPI WaitNamedPipeA(LPCSTR,DWORD);
- WINBASEAPI BOOL WINAPI WaitNamedPipeW(LPCWSTR,DWORD);
- #define WaitNamedPipe WINELIB_NAME_AW(WaitNamedPipe)
- --------------2.6.2--
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement