Advertisement
Guest User

Untitled

a guest
Nov 24th, 2015
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.39 KB | None | 0 0
  1. From 0a58da1669740c6e14f80cc0da7af6f3f4dbca22 Mon Sep 17 00:00:00 2001
  2. From: Andrew Eikum <aeikum@codeweavers.com>
  3. Date: Tue, 17 Nov 2015 12:21:22 -0600
  4. Subject: winegstreamer: Use gstreamer threadpool API to create new Wine
  5. threads
  6. To: wine-patches <wine-patches@winehq.org>
  7. Reply-To: wine-devel <wine-devel@winehq.org>,Andrew Eikum <aeikum@codeweavers.com>
  8. MIME-Version: 1.0
  9. Content-Type: multipart/mixed; boundary="------------2.6.2"
  10.  
  11. This is a multi-part message in MIME format.
  12. --------------2.6.2
  13. Content-Type: text/plain; charset=UTF-8; format=fixed
  14. Content-Transfer-Encoding: 8bit
  15.  
  16. ---
  17. dlls/winegstreamer/Makefile.in | 6 +-
  18. dlls/winegstreamer/glibthread.c | 390 ---------------------------------------
  19. dlls/winegstreamer/gst_private.h | 5 +-
  20. dlls/winegstreamer/gstdemux.c | 37 +++-
  21. dlls/winegstreamer/main.c | 4 +-
  22. dlls/winegstreamer/threadpool.c | 128 +++++++++++++
  23. include/winbase.h | 1 +
  24. 7 files changed, 171 insertions(+), 400 deletions(-)
  25. delete mode 100644 dlls/winegstreamer/glibthread.c
  26. create mode 100644 dlls/winegstreamer/threadpool.c
  27.  
  28.  
  29. --------------2.6.2
  30. Content-Type: text/x-patch; name="0001-winegstreamer-Use-gstreamer-threadpool-API-to-create.patch"
  31. Content-Transfer-Encoding: 8bit
  32. Content-Disposition: inline; filename="0001-winegstreamer-Use-gstreamer-threadpool-API-to-create.patch"
  33.  
  34. diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
  35. index 0c14ffd..8e791f3 100644
  36. --- a/dlls/winegstreamer/Makefile.in
  37. +++ b/dlls/winegstreamer/Makefile.in
  38. @@ -1,13 +1,13 @@
  39. MODULE = winegstreamer.dll
  40. IMPORTS = strmbase strmiids uuid winmm msacm32 msvfw32 ole32 oleaut32 user32 gdi32 advapi32
  41. EXTRAINCL = $(GSTREAMER_CFLAGS)
  42. -EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
  43. +EXTRALIBS = $(GSTREAMER_LIBS)
  44.  
  45. C_SRCS = \
  46. - glibthread.c \
  47. gstdemux.c \
  48. gsttffilter.c \
  49. - main.c
  50. + main.c \
  51. + threadpool.c
  52.  
  53. RC_SRCS = \
  54. rsrc.rc
  55. diff --git a/dlls/winegstreamer/glibthread.c b/dlls/winegstreamer/glibthread.c
  56. deleted file mode 100644
  57. index 0d829a0..0000000
  58. --- a/dlls/winegstreamer/glibthread.c
  59. +++ /dev/null
  60. @@ -1,390 +0,0 @@
  61. -/* GLIB - Library of useful routines for C programming
  62. - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  63. - *
  64. - * Wine GStreamer integration
  65. - * Copyright 2010 Aric Stewart, CodeWeavers
  66. - *
  67. - * gthread.c: solaris thread system implementation
  68. - * Copyright 1998-2001 Sebastian Wilhelmi; University of Karlsruhe
  69. - * Copyright 2001 Hans Breuer
  70. - *
  71. - * This library is free software; you can redistribute it and/or
  72. - * modify it under the terms of the GNU Lesser General Public
  73. - * License as published by the Free Software Foundation; either
  74. - * version 2.1 of the License, or (at your option) any later version.
  75. - *
  76. - * This library is distributed in the hope that it will be useful,
  77. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  78. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  79. - * Lesser General Public License for more details.
  80. - *
  81. - * You should have received a copy of the GNU Lesser General Public
  82. - * License along with this library; if not, write to the Free Software
  83. - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  84. - */
  85. -
  86. -/*
  87. - * Modified by the GLib Team and others 1997-2000. See the AUTHORS
  88. - * file for a list of people on the GLib Team. See the ChangeLog
  89. - * files for a list of changes. These files are distributed with
  90. - * GLib at ftp://ftp.gtk.org/pub/gtk/.
  91. - */
  92. -
  93. -#include "config.h"
  94. -
  95. -#ifdef HAVE_PTHREAD_H
  96. -#include <pthread.h>
  97. -#endif
  98. -
  99. -#include <glib.h>
  100. -
  101. -#include <errno.h>
  102. -#include <stdarg.h>
  103. -#include <stdlib.h>
  104. -#include <stdio.h>
  105. -
  106. -#include "windef.h"
  107. -#include "winbase.h"
  108. -#include "winnls.h"
  109. -#include "wine/debug.h"
  110. -
  111. -WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
  112. -
  113. -static gchar *
  114. -g_win32_error_message (gint error)
  115. -{
  116. - gchar *retval;
  117. - WCHAR *msg = NULL;
  118. - int nchars;
  119. -
  120. - FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
  121. - |FORMAT_MESSAGE_IGNORE_INSERTS
  122. - |FORMAT_MESSAGE_FROM_SYSTEM,
  123. - NULL, error, 0,
  124. - (LPWSTR) &msg, 0, NULL);
  125. - if (msg != NULL)
  126. - {
  127. - nchars = WideCharToMultiByte(CP_UTF8, 0, msg, -1, NULL, 0, NULL, NULL);
  128. -
  129. - if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r')
  130. - msg[nchars-2] = '\0';
  131. -
  132. - retval = g_utf16_to_utf8 (msg, -1, NULL, NULL, NULL);
  133. -
  134. - LocalFree (msg);
  135. - }
  136. - else
  137. - retval = g_strdup ("");
  138. -
  139. - return retval;
  140. -}
  141. -
  142. -static gint g_thread_priority_map [G_THREAD_PRIORITY_URGENT + 1] = {
  143. - THREAD_PRIORITY_BELOW_NORMAL,
  144. - THREAD_PRIORITY_NORMAL,
  145. - THREAD_PRIORITY_ABOVE_NORMAL,
  146. - THREAD_PRIORITY_HIGHEST
  147. -};
  148. -
  149. -static DWORD g_thread_self_tls;
  150. -
  151. -/* A "forward" declaration of this structure */
  152. -static GThreadFunctions g_thread_functions_for_glib_use_default;
  153. -
  154. -typedef struct _GThreadData GThreadData;
  155. -struct _GThreadData
  156. -{
  157. - GThreadFunc func;
  158. - gpointer data;
  159. - HANDLE thread;
  160. - gboolean joinable;
  161. -};
  162. -
  163. -static GMutex *
  164. -g_mutex_new_posix_impl (void)
  165. -{
  166. - GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
  167. - pthread_mutex_init ((pthread_mutex_t *) result, NULL);
  168. - return result;
  169. -}
  170. -
  171. -static void
  172. -g_mutex_free_posix_impl (GMutex * mutex)
  173. -{
  174. - pthread_mutex_destroy ((pthread_mutex_t *) mutex);
  175. - g_free (mutex);
  176. -}
  177. -
  178. -/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
  179. - functions from gmem.c and gmessages.c; */
  180. -
  181. -/* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as
  182. - signature and semantic are right, but without error check then!!!!,
  183. - we might want to change this therefore. */
  184. -
  185. -static gboolean
  186. -g_mutex_trylock_posix_impl (GMutex * mutex)
  187. -{
  188. - int result;
  189. -
  190. - result = pthread_mutex_trylock ((pthread_mutex_t *) mutex);
  191. -
  192. - if (result == EBUSY)
  193. - return FALSE;
  194. -
  195. - if (result) ERR("pthread_mutex_trylock %x\n",result);
  196. - return TRUE;
  197. -}
  198. -
  199. -static GCond *
  200. -g_cond_new_posix_impl (void)
  201. -{
  202. - GCond *result = (GCond *) g_new (pthread_cond_t, 1);
  203. - pthread_cond_init ((pthread_cond_t *) result, NULL);
  204. - return result;
  205. -}
  206. -
  207. -/* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait
  208. - can be taken directly, as signature and semantic are right, but
  209. - without error check then!!!!, we might want to change this
  210. - therefore. */
  211. -
  212. -#define G_NSEC_PER_SEC 1000000000
  213. -
  214. -static gboolean
  215. -g_cond_timed_wait_posix_impl (GCond * cond,
  216. - GMutex * entered_mutex,
  217. - GTimeVal * abs_time)
  218. -{
  219. - int result;
  220. - struct timespec end_time;
  221. - gboolean timed_out;
  222. -
  223. - g_return_val_if_fail (cond != NULL, FALSE);
  224. - g_return_val_if_fail (entered_mutex != NULL, FALSE);
  225. -
  226. - if (!abs_time)
  227. - {
  228. - result = pthread_cond_wait ((pthread_cond_t *)cond,
  229. - (pthread_mutex_t *) entered_mutex);
  230. - timed_out = FALSE;
  231. - }
  232. - else
  233. - {
  234. - end_time.tv_sec = abs_time->tv_sec;
  235. - end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);
  236. -
  237. - g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);
  238. -
  239. - result = pthread_cond_timedwait ((pthread_cond_t *) cond,
  240. - (pthread_mutex_t *) entered_mutex,
  241. - &end_time);
  242. - timed_out = (result == ETIMEDOUT);
  243. - }
  244. -
  245. - if (!timed_out)
  246. - if (result) ERR("pthread_cond_timedwait %x\n",result);
  247. -
  248. - return !timed_out;
  249. -}
  250. -
  251. -static void
  252. -g_cond_free_posix_impl (GCond * cond)
  253. -{
  254. - pthread_cond_destroy ((pthread_cond_t *) cond);
  255. - g_free (cond);
  256. -}
  257. -
  258. -static GPrivate *
  259. -g_private_new_posix_impl (GDestroyNotify destructor)
  260. -{
  261. - GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1);
  262. - pthread_key_create ((pthread_key_t *) result, destructor);
  263. - return result;
  264. -}
  265. -
  266. -/* NOTE: the functions g_private_get and g_private_set may not use
  267. - functions from gmem.c and gmessages.c */
  268. -
  269. -static void
  270. -g_private_set_posix_impl (GPrivate * private_key, gpointer value)
  271. -{
  272. - if (!private_key)
  273. - return;
  274. - pthread_setspecific (*(pthread_key_t *) private_key, value);
  275. -}
  276. -
  277. -static gpointer
  278. -g_private_get_posix_impl (GPrivate * private_key)
  279. -{
  280. - if (!private_key)
  281. - return NULL;
  282. - return pthread_getspecific (*(pthread_key_t *) private_key);
  283. -}
  284. -
  285. -static void
  286. -g_thread_set_priority_win32_impl (gpointer thread, GThreadPriority priority)
  287. -{
  288. - GThreadData *target = *(GThreadData **)thread;
  289. -
  290. - g_return_if_fail ((int)priority >= G_THREAD_PRIORITY_LOW);
  291. - g_return_if_fail ((int)priority <= G_THREAD_PRIORITY_URGENT);
  292. -
  293. - SetThreadPriority (target->thread, g_thread_priority_map [priority]);
  294. -}
  295. -
  296. -static void
  297. -g_thread_self_win32_impl (gpointer thread)
  298. -{
  299. - GThreadData *self = TlsGetValue (g_thread_self_tls);
  300. -
  301. - if (!self)
  302. - {
  303. - /* This should only happen for the main thread! */
  304. - HANDLE handle = GetCurrentThread ();
  305. - HANDLE process = GetCurrentProcess ();
  306. - self = g_new (GThreadData, 1);
  307. - DuplicateHandle (process, handle, process, &self->thread, 0, FALSE,
  308. - DUPLICATE_SAME_ACCESS);
  309. - TlsSetValue (g_thread_self_tls, self);
  310. - self->func = NULL;
  311. - self->data = NULL;
  312. - self->joinable = FALSE;
  313. - }
  314. -
  315. - *(GThreadData **)thread = self;
  316. -}
  317. -
  318. -static void
  319. -g_thread_exit_win32_impl (void)
  320. -{
  321. - GThreadData *self = TlsGetValue (g_thread_self_tls);
  322. -
  323. - if (self)
  324. - {
  325. - if (!self->joinable)
  326. - {
  327. - CloseHandle (self->thread);
  328. - g_free (self);
  329. - }
  330. - TlsSetValue (g_thread_self_tls, NULL);
  331. - }
  332. -
  333. - ExitThread (0);
  334. -}
  335. -
  336. -static guint __stdcall
  337. -g_thread_proxy (gpointer data)
  338. -{
  339. - GThreadData *self = (GThreadData*) data;
  340. -
  341. - TlsSetValue (g_thread_self_tls, self);
  342. -
  343. - self->func (self->data);
  344. -
  345. - g_thread_exit_win32_impl ();
  346. -
  347. - g_assert_not_reached ();
  348. -
  349. - return 0;
  350. -}
  351. -
  352. -static void
  353. -g_thread_create_win32_impl (GThreadFunc func,
  354. - gpointer data,
  355. - gulong stack_size,
  356. - gboolean joinable,
  357. - gboolean bound,
  358. - GThreadPriority priority,
  359. - gpointer thread,
  360. - GError **error)
  361. -{
  362. - guint ignore;
  363. - GThreadData *retval;
  364. -
  365. - g_return_if_fail (func);
  366. - g_return_if_fail ((int)priority >= G_THREAD_PRIORITY_LOW);
  367. - g_return_if_fail ((int)priority <= G_THREAD_PRIORITY_URGENT);
  368. -
  369. - retval = g_new(GThreadData, 1);
  370. - retval->func = func;
  371. - retval->data = data;
  372. -
  373. - retval->joinable = joinable;
  374. -
  375. - retval->thread = (HANDLE) CreateThread (NULL, stack_size, g_thread_proxy,
  376. - retval, 0, &ignore);
  377. -
  378. - if (retval->thread == NULL)
  379. - {
  380. - gchar *win_error = g_win32_error_message (GetLastError ());
  381. - g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
  382. - "Error creating thread: %s", win_error);
  383. - g_free (retval);
  384. - g_free (win_error);
  385. - return;
  386. - }
  387. -
  388. - *(GThreadData **)thread = retval;
  389. -
  390. - g_thread_set_priority_win32_impl (thread, priority);
  391. -}
  392. -
  393. -static void
  394. -g_thread_yield_win32_impl (void)
  395. -{
  396. - Sleep(0);
  397. -}
  398. -
  399. -static void
  400. -g_thread_join_win32_impl (gpointer thread)
  401. -{
  402. - GThreadData *target = *(GThreadData **)thread;
  403. -
  404. - g_return_if_fail (target->joinable);
  405. -
  406. - WaitForSingleObject (target->thread, INFINITE);
  407. -
  408. - CloseHandle (target->thread);
  409. - g_free (target);
  410. -}
  411. -
  412. -static GThreadFunctions g_thread_functions_for_glib_use_default =
  413. -{
  414. - /* Posix functions here for speed */
  415. - g_mutex_new_posix_impl,
  416. - (void (*)(GMutex *)) pthread_mutex_lock,
  417. - g_mutex_trylock_posix_impl,
  418. - (void (*)(GMutex *)) pthread_mutex_unlock,
  419. - g_mutex_free_posix_impl,
  420. - g_cond_new_posix_impl,
  421. - (void (*)(GCond *)) pthread_cond_signal,
  422. - (void (*)(GCond *)) pthread_cond_broadcast,
  423. - (void (*)(GCond *, GMutex *)) pthread_cond_wait,
  424. - g_cond_timed_wait_posix_impl,
  425. - g_cond_free_posix_impl,
  426. - g_private_new_posix_impl,
  427. - g_private_get_posix_impl,
  428. - g_private_set_posix_impl,
  429. - /* win32 function required here */
  430. - g_thread_create_win32_impl, /* thread */
  431. - g_thread_yield_win32_impl,
  432. - g_thread_join_win32_impl,
  433. - g_thread_exit_win32_impl,
  434. - g_thread_set_priority_win32_impl,
  435. - g_thread_self_win32_impl,
  436. - NULL /* no equal function necessary */
  437. -};
  438. -
  439. -void g_thread_impl_init (void)
  440. -{
  441. - static gboolean beenhere = FALSE;
  442. -
  443. - if (beenhere)
  444. - return;
  445. -
  446. - beenhere = TRUE;
  447. -
  448. - g_thread_self_tls = TlsAlloc ();
  449. - g_thread_init(&g_thread_functions_for_glib_use_default);
  450. -}
  451. diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
  452. index d041d64..c74bad3 100644
  453. --- a/dlls/winegstreamer/gst_private.h
  454. +++ b/dlls/winegstreamer/gst_private.h
  455. @@ -42,6 +42,9 @@ IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *pUnkOuter, HRESULT *phr);
  456. IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *pUnkOuter, HRESULT *phr);
  457. IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr);
  458.  
  459. -void g_thread_impl_init(void);
  460. DWORD Gstreamer_init(void);
  461. +
  462. +GstTaskPool *wine_gst_pool_new(void) DECLSPEC_HIDDEN;
  463. +extern GstTaskPool *wine_gst_pool DECLSPEC_HIDDEN;
  464. +
  465. #endif /* __GST_PRIVATE_INCLUDED__ */
  466. diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
  467. index c17fc2f..6876717 100644
  468. --- a/dlls/winegstreamer/gstdemux.c
  469. +++ b/dlls/winegstreamer/gstdemux.c
  470. @@ -888,20 +888,47 @@ static GstBusSyncReply watch_bus(GstBus *bus, GstMessage *msg, gpointer data) {
  471. GSTImpl *This = data;
  472. GError *err = NULL;
  473. gchar *dbg_info = NULL;
  474. +
  475. + if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_STREAM_STATUS) {
  476. + GstStreamStatusType type;
  477. + GstElement *owner;
  478. + const GValue *val;
  479. +
  480. + gst_message_parse_stream_status(msg, &type, &owner);
  481. +
  482. + val = gst_message_get_stream_status_object(msg);
  483. +
  484. + if (val && G_VALUE_TYPE(val) == GST_TYPE_TASK) {
  485. + GstTask *task = g_value_get_object(val);
  486. + if (task && type == GST_STREAM_STATUS_TYPE_CREATE)
  487. + gst_task_set_pool(task, wine_gst_pool);
  488. + }
  489. +
  490. + return GST_BUS_PASS;
  491. + }
  492. +
  493. if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_ERROR) {
  494. gst_message_parse_error(msg, &err, &dbg_info);
  495. FIXME("%s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
  496. WARN("%s\n", dbg_info);
  497. SetEvent(This->event);
  498. - } else if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_WARNING) {
  499. + if (err)
  500. + g_error_free(err);
  501. + g_free(dbg_info);
  502. + return GST_BUS_DROP;
  503. + }
  504. +
  505. + if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_WARNING) {
  506. gst_message_parse_warning(msg, &err, &dbg_info);
  507. WARN("%s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
  508. WARN("%s\n", dbg_info);
  509. + if (err)
  510. + g_error_free(err);
  511. + g_free(dbg_info);
  512. + return GST_BUS_DROP;
  513. }
  514. - if (err)
  515. - g_error_free(err);
  516. - g_free(dbg_info);
  517. - return GST_BUS_DROP;
  518. +
  519. + return GST_BUS_PASS;
  520. }
  521.  
  522. static void unknown_type(GstElement *bin, GstPad *pad, GstCaps *caps, GSTImpl *This) {
  523. diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
  524. index 4f0e84f..6dcbf2f 100644
  525. --- a/dlls/winegstreamer/main.c
  526. +++ b/dlls/winegstreamer/main.c
  527. @@ -210,6 +210,8 @@ FactoryTemplate const g_Templates[] = {
  528.  
  529. const int g_cTemplates = sizeof(g_Templates) / sizeof (g_Templates[0]);
  530.  
  531. +GstTaskPool *wine_gst_pool = NULL;
  532. +
  533. BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
  534. {
  535. if (fdwReason == DLL_PROCESS_ATTACH)
  536. @@ -254,7 +256,7 @@ DWORD Gstreamer_init(void) {
  537. argv[0] = argv0;
  538. argv[1] = argv1;
  539. argv[2] = NULL;
  540. - g_thread_impl_init();
  541. + wine_gst_pool = wine_gst_pool_new();
  542. inited = gst_init_check(&argc, &argv, &err);
  543. HeapFree(GetProcessHeap(), 0, argv);
  544. if (err) {
  545. diff --git a/dlls/winegstreamer/threadpool.c b/dlls/winegstreamer/threadpool.c
  546. new file mode 100644
  547. index 0000000..552c926
  548. --- /dev/null
  549. +++ b/dlls/winegstreamer/threadpool.c
  550. @@ -0,0 +1,128 @@
  551. +/*
  552. + * Copyright 2015 Andrew Eikum for CodeWeavers
  553. + *
  554. + * This library is free software; you can redistribute it and/or
  555. + * modify it under the terms of the GNU Lesser General Public
  556. + * License as published by the Free Software Foundation; either
  557. + * version 2.1 of the License, or (at your option) any later version.
  558. + *
  559. + * This library is distributed in the hope that it will be useful,
  560. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  561. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  562. + * Lesser General Public License for more details.
  563. + *
  564. + * You should have received a copy of the GNU Lesser General Public
  565. + * License along with this library; if not, write to the Free Software
  566. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  567. + */
  568. +
  569. +#include "config.h"
  570. +
  571. +#include <gst/gst.h>
  572. +
  573. +#include "windef.h"
  574. +#include "winbase.h"
  575. +#include "winnls.h"
  576. +#include "wine/debug.h"
  577. +
  578. +WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
  579. +
  580. +#define WINE_GST_POOL (wine_gst_pool_get_type())
  581. +
  582. +typedef struct _WineGstPool {
  583. + GstTaskPool obj;
  584. +} WineGstPool;
  585. +
  586. +typedef struct _WineGstPoolClass {
  587. + GstTaskPoolClass parent_class;
  588. +} WineGstPoolClass;
  589. +
  590. +G_DEFINE_TYPE(WineGstPool, wine_gst_pool, GST_TYPE_TASK_POOL);
  591. +
  592. +static void wine_gst_pool_prepare(GstTaskPool *gstpool, GError **err)
  593. +{
  594. + /* noop */
  595. +}
  596. +
  597. +static void wine_gst_pool_cleanup(GstTaskPool *gstpool)
  598. +{
  599. + /* noop */
  600. +}
  601. +
  602. +typedef struct _thunk_data {
  603. + GstTaskPoolFunction fn;
  604. + gpointer data;
  605. +} thunk_data;
  606. +
  607. +typedef struct _WineGstWork {
  608. + TP_WORK *tp_work;
  609. + thunk_data userdata;
  610. +} WineGstWork;
  611. +
  612. +static void CALLBACK workfn(TP_CALLBACK_INSTANCE *instance, void *user,
  613. + TP_WORK *work)
  614. +{
  615. + thunk_data *data = user;
  616. +
  617. + data->fn(data->data);
  618. +}
  619. +
  620. +static gpointer wine_gst_pool_push(GstTaskPool *gstpool, GstTaskPoolFunction fn,
  621. + gpointer data, GError **err)
  622. +{
  623. + /* make new thread */
  624. + WineGstWork *work;
  625. +
  626. + work = HeapAlloc(GetProcessHeap(), 0, sizeof(*work));
  627. +
  628. + work->userdata.data = data;
  629. + work->userdata.fn = fn;
  630. +
  631. + work->tp_work = CreateThreadpoolWork(&workfn, &work->userdata, NULL);
  632. +
  633. + SubmitThreadpoolWork(work->tp_work);
  634. +
  635. + return work;
  636. +}
  637. +
  638. +static void wine_gst_pool_join(GstTaskPool *gstpool, gpointer id)
  639. +{
  640. + /* wait for thread */
  641. + WineGstWork *work = id;
  642. +
  643. + WaitForThreadpoolWorkCallbacks(work->tp_work, FALSE);
  644. + CloseThreadpoolWork(work->tp_work);
  645. +
  646. + HeapFree(GetProcessHeap(), 0, work);
  647. +}
  648. +
  649. +static void wine_gst_pool_init(WineGstPool *pool)
  650. +{
  651. + /* noop */
  652. +}
  653. +
  654. +static void wine_gst_pool_finalize(GObject *obj)
  655. +{
  656. + G_OBJECT_CLASS(wine_gst_pool_parent_class)->finalize(obj);
  657. +}
  658. +
  659. +static void wine_gst_pool_class_init(WineGstPoolClass *klass)
  660. +{
  661. + GObjectClass *gobj_class;
  662. + GstTaskPoolClass *gsttaskpool_class;
  663. +
  664. + gobj_class = (GObjectClass*)klass;
  665. + gsttaskpool_class = (GstTaskPoolClass*)klass;
  666. +
  667. + gobj_class->finalize = wine_gst_pool_finalize;
  668. +
  669. + gsttaskpool_class->prepare = wine_gst_pool_prepare;
  670. + gsttaskpool_class->cleanup = wine_gst_pool_cleanup;
  671. + gsttaskpool_class->push = wine_gst_pool_push;
  672. + gsttaskpool_class->join = wine_gst_pool_join;
  673. +}
  674. +
  675. +GstTaskPool *wine_gst_pool_new(void)
  676. +{
  677. + return g_object_new(WINE_GST_POOL, NULL);
  678. +}
  679. diff --git a/include/winbase.h b/include/winbase.h
  680. index 7216086..7a9a02e 100644
  681. --- a/include/winbase.h
  682. +++ b/include/winbase.h
  683. @@ -2577,6 +2577,7 @@ WINBASEAPI DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,BOOL,DW
  684. WINBASEAPI DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE*,BOOL,DWORD,BOOL);
  685. WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE,DWORD);
  686. WINBASEAPI DWORD WINAPI WaitForSingleObjectEx(HANDLE,DWORD,BOOL);
  687. +WINBASEAPI VOID WINAPI WaitForThreadpoolWorkCallbacks(TP_WORK*,BOOL);
  688. WINBASEAPI BOOL WINAPI WaitNamedPipeA(LPCSTR,DWORD);
  689. WINBASEAPI BOOL WINAPI WaitNamedPipeW(LPCWSTR,DWORD);
  690. #define WaitNamedPipe WINELIB_NAME_AW(WaitNamedPipe)
  691.  
  692. --------------2.6.2--
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement