ReactOS 0.4.17-dev-691-gfdddc52
queue.c
Go to the documentation of this file.
1/*
2 * Copyright 2019-2020 Nikolay Sivov for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <assert.h>
20
21#define COBJMACROS
22#include "initguid.h"
23#include "rtworkq.h"
24#include "wine/debug.h"
25#include "wine/list.h"
26
28
29#define FIRST_USER_QUEUE_HANDLE 5
30#define MAX_USER_QUEUE_HANDLES 124
31
32#define WAIT_ITEM_KEY_MASK (0x82000000)
33#define SCHEDULED_ITEM_KEY_MASK (0x80000000)
34
36
38{
39 return ((RTWQWORKITEM_KEY)mask << 32) | key;
40}
41
43{
45}
46
48{
49 void *obj;
52};
53
59
62{
63 0, 0, &queues_section,
65 0, 0, { (DWORD_PTR)(__FILE__ ": queues_section") }
66};
67static CRITICAL_SECTION queues_section = { &queues_critsect_debug, -1, 0, 0, 0, 0 };
68
70static CO_MTA_USAGE_COOKIE mta_cookie;
71
73{
74 unsigned int idx = HIWORD(handle) - FIRST_USER_QUEUE_HANDLE;
75
77 {
79 return &user_queues[idx];
80 }
81
82 return NULL;
83}
84
85/* Should be kept in sync with corresponding MFASYNC_CALLBACK_ constants. */
87{
97};
98
99/* Should be kept in sync with corresponding MFASYNC_ constants. */
101{
107};
108
110{
119};
120
122{
126};
127
129{
132 struct list entry;
135 struct queue *queue;
141 union
142 {
146 } u;
147};
148
150{
151 return CONTAINING_RECORD(iface, struct work_item, IUnknown_iface);
152}
153
155{
159};
160
161struct queue;
162struct queue_desc;
163
165{
166 HRESULT (*init)(const struct queue_desc *desc, struct queue *queue);
168 void (*submit)(struct queue *queue, struct work_item *item);
169};
170
172{
174 const struct queue_ops *ops;
176};
177
178struct queue
179{
181 const struct queue_ops *ops;
187 /* Data used for serial queues only. */
190};
191
192static void shutdown_queue(struct queue *queue);
193
195{
196 HRESULT hr = RTWQ_E_INVALID_WORKQUEUE;
197 struct queue_handle *entry;
198
200 return S_OK;
201
204 if (entry && entry->refcount)
205 {
206 entry->refcount++;
207 hr = S_OK;
208 }
210 return hr;
211}
212
214{
215 HRESULT hr = RTWQ_E_INVALID_WORKQUEUE;
216 struct queue_handle *entry;
217
219 return S_OK;
220
223 if (entry && entry->refcount)
224 {
225 if (--entry->refcount == 0)
226 {
228 shutdown_queue((struct queue *)entry->obj);
229 free(entry->obj);
232 }
233 hr = S_OK;
234 }
236 return hr;
237}
238
240{
241 return CONTAINING_RECORD(iface, struct queue, IRtwqAsyncCallback_iface);
242}
243
245{
246 if (IsEqualIID(riid, &IID_IRtwqAsyncCallback) ||
248 {
249 *obj = iface;
250 IRtwqAsyncCallback_AddRef(iface);
251 return S_OK;
252 }
253
254 *obj = NULL;
255 return E_NOINTERFACE;
256}
257
259{
260 return 2;
261}
262
264{
265 return 1;
266}
267
269{
271
272 *flags = 0;
273 *queue_id = queue->id;
274
275 return S_OK;
276}
277
279{
280 /* Reply callback won't be called in a regular way, pending items and chained queues will make it
281 unnecessary complicated to reach actual work queue that's able to execute this item. Instead
282 serial queues are cleaned up right away on submit(). */
283 return S_OK;
284}
285
286static const IRtwqAsyncCallbackVtbl queue_serial_callback_vtbl =
287{
293};
294
296
297static struct queue *get_system_queue(DWORD queue_id)
298{
299 switch (queue_id)
300 {
307 return &system_queues[queue_id - 1];
308 default:
309 return NULL;
310 }
311}
312
313static HRESULT grab_queue(DWORD queue_id, struct queue **ret);
314
315static void CALLBACK standard_queue_cleanup_callback(void *object_data, void *group_data)
316{
317}
318
319static HRESULT pool_queue_init(const struct queue_desc *desc, struct queue *queue)
320{
322 unsigned int max_thread, i;
323
325
326 memset(&env, 0, sizeof(env));
327 env.Version = 3;
328 env.Size = sizeof(env);
329 env.Pool = queue->pool;
330 env.CleanupGroup = CreateThreadpoolCleanupGroup();
331 env.CleanupGroupCancelCallback = standard_queue_cleanup_callback;
332 env.CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL;
333 for (i = 0; i < ARRAY_SIZE(queue->envs); ++i)
334 {
335 queue->envs[i] = env;
337 }
340
341 max_thread = (desc->queue_type == RTWQ_STANDARD_WORKQUEUE || desc->queue_type == RTWQ_WINDOW_WORKQUEUE) ? 1 : 4;
342
345
346 if (desc->queue_type == RTWQ_WINDOW_WORKQUEUE)
347 FIXME("RTWQ_WINDOW_WORKQUEUE is not supported.\n");
348
349 return S_OK;
350}
351
353{
354 if (!queue->pool)
355 return FALSE;
356
359 queue->pool = NULL;
360
361 return TRUE;
362}
363
365{
366 struct work_item *item = context;
367 RTWQASYNCRESULT *result = (RTWQASYNCRESULT *)item->result;
368
369 TRACE("result object %p.\n", result);
370
371 /* Submitting from serial queue in reply mode, use different result object acting as receipt token.
372 It's submitted to user callback still, but when invoked, special serial queue callback will be used
373 to ensure correct destination queue. */
374
375 IRtwqAsyncCallback_Invoke(result->pCallback, item->reply_result ? item->reply_result : item->result);
376
377 IUnknown_Release(&item->IUnknown_iface);
378}
379
380static void pool_queue_submit(struct queue *queue, struct work_item *item)
381{
382 TP_CALLBACK_PRIORITY callback_priority;
384
385 if (item->priority == 0)
386 callback_priority = TP_CALLBACK_PRIORITY_NORMAL;
387 else if (item->priority < 0)
388 callback_priority = TP_CALLBACK_PRIORITY_LOW;
389 else
390 callback_priority = TP_CALLBACK_PRIORITY_HIGH;
391
392 env = queue->envs[callback_priority];
393 env.FinalizationCallback = item->finalization_callback;
394 /* Worker pool callback will release one reference. Grab one more to keep object alive when
395 we need finalization callback. */
396 if (item->finalization_callback)
397 IUnknown_AddRef(&item->IUnknown_iface);
400 SubmitThreadpoolWork(item->u.work_object);
401
402 TRACE("dispatched %p.\n", item->result);
403}
404
405static const struct queue_ops pool_queue_ops =
406{
410};
411
412static struct work_item * serial_queue_get_next(struct queue *queue, struct work_item *item)
413{
414 struct work_item *next_item = NULL;
415
416 list_remove(&item->entry);
417 if (!list_empty(&item->queue->pending_items))
418 next_item = LIST_ENTRY(list_head(&item->queue->pending_items), struct work_item, entry);
419
420 return next_item;
421}
422
424{
425 struct work_item *item = (struct work_item *)user_data, *next_item;
426 struct queue *target_queue, *queue = item->queue;
427 HRESULT hr;
428
430
431 if ((next_item = serial_queue_get_next(queue, item)))
432 {
434 target_queue->ops->submit(target_queue, next_item);
435 else
436 WARN("Failed to grab queue for id %#lx, hr %#lx.\n", queue->target_queue, hr);
437 }
438
440
441 IUnknown_Release(&item->IUnknown_iface);
442}
443
444static HRESULT serial_queue_init(const struct queue_desc *desc, struct queue *queue)
445{
447 queue->target_queue = desc->target_queue;
450
451 return S_OK;
452}
453
455{
457
458 return TRUE;
459}
460
462{
463 RTWQASYNCRESULT *async_result = (RTWQASYNCRESULT *)item->result;
464 struct work_item *head;
465
467 return NULL;
468
470 if (head->reply_result == item->result && async_result->pCallback == &queue->IRtwqAsyncCallback_iface)
471 return head;
472
473 return NULL;
474}
475
476static void serial_queue_submit(struct queue *queue, struct work_item *item)
477{
478 struct work_item *head, *next_item = NULL;
479 struct queue *target_queue;
480 HRESULT hr;
481
482 /* In reply mode queue will advance when 'reply_result' is invoked, in regular mode it will advance automatically,
483 via finalization callback. */
484
485 if (item->flags & RTWQ_REPLY_CALLBACK)
486 {
488 WARN("Failed to create reply object, hr %#lx.\n", hr);
489 }
490 else
491 item->finalization_callback = queue->finalization_callback;
492
493 /* Serial queues could be chained together, detach from current queue before transitioning item to this one.
494 Items are not detached when submitted to pool queues, because pool queues won't forward them further. */
495 EnterCriticalSection(&item->queue->cs);
496 list_remove(&item->entry);
497 LeaveCriticalSection(&item->queue->cs);
498
500
501 item->queue = queue;
502
504 {
505 /* Ack receipt token - pop waiting item, advance. */
506 next_item = serial_queue_get_next(queue, head);
507 IUnknown_Release(&head->IUnknown_iface);
508 }
509 else
510 {
512 next_item = item;
514 IUnknown_AddRef(&item->IUnknown_iface);
515 }
516
517 if (next_item)
518 {
520 target_queue->ops->submit(target_queue, next_item);
521 else
522 WARN("Failed to grab queue for id %#lx, hr %#lx.\n", queue->target_queue, hr);
523 }
524
526}
527
528static const struct queue_ops serial_queue_ops =
529{
533};
534
536{
538 {
539 *obj = iface;
540 IUnknown_AddRef(iface);
541 return S_OK;
542 }
543
544 *obj = NULL;
545 return E_NOINTERFACE;
546}
547
549{
551 return InterlockedIncrement(&item->refcount);
552}
553
555{
558
559 if (!refcount)
560 {
561 switch (item->type)
562 {
563 case WORK_ITEM_WORK:
564 if (item->u.work_object) CloseThreadpoolWork(item->u.work_object);
565 break;
566 case WORK_ITEM_WAIT:
567 if (item->u.wait_object) CloseThreadpoolWait(item->u.wait_object);
568 break;
569 case WORK_ITEM_TIMER:
570 if (item->u.timer_object) CloseThreadpoolTimer(item->u.timer_object);
571 break;
572 }
573 if (item->reply_result)
574 IRtwqAsyncResult_Release(item->reply_result);
575 IRtwqAsyncResult_Release(item->result);
576 free(item);
577 }
578
579 return refcount;
580}
581
582static const IUnknownVtbl work_item_vtbl =
583{
587};
588
590{
591 RTWQASYNCRESULT *async_result = (RTWQASYNCRESULT *)result;
592 DWORD flags = 0, queue_id = 0;
593 struct work_item *item;
594
595 item = calloc(1, sizeof(*item));
596
597 item->IUnknown_iface.lpVtbl = &work_item_vtbl;
598 item->result = result;
599 IRtwqAsyncResult_AddRef(item->result);
600 item->refcount = 1;
601 item->queue = queue;
602 list_init(&item->entry);
603 item->priority = priority;
604
605 if (SUCCEEDED(IRtwqAsyncCallback_GetParameters(async_result->pCallback, &flags, &queue_id)))
606 item->flags = flags;
607
608 return item;
609}
610
611static void init_work_queue(const struct queue_desc *desc, struct queue *queue)
612{
613 assert(desc->ops != NULL);
614
615 queue->ops = desc->ops;
616 if (SUCCEEDED(queue->ops->init(desc, queue)))
617 {
620 }
621}
622
623static HRESULT grab_queue(DWORD queue_id, struct queue **ret)
624{
625 struct queue *queue = get_system_queue(queue_id);
626 RTWQ_WORKQUEUE_TYPE queue_type;
627 struct queue_handle *entry;
628
629 *ret = NULL;
630
632 return RTWQ_E_SHUTDOWN;
633
634 if (queue && queue->pool)
635 {
636 *ret = queue;
637 return S_OK;
638 }
639 else if (queue)
640 {
641 struct queue_desc desc;
642
644 switch (queue_id)
645 {
650 break;
651 default:
653 }
654
655 desc.queue_type = queue_type;
656 desc.ops = &pool_queue_ops;
657 desc.target_queue = 0;
660 *ret = queue;
661 return S_OK;
662 }
663
664 /* Handles user queues. */
665 if ((entry = get_queue_obj(queue_id)))
666 *ret = entry->obj;
667
668 return *ret ? S_OK : RTWQ_E_INVALID_WORKQUEUE;
669}
670
671static void shutdown_queue(struct queue *queue)
672{
673 struct work_item *item, *item2;
674
675 if (!queue->ops || !queue->ops->shutdown(queue))
676 return;
677
680 {
681 list_remove(&item->entry);
682 IUnknown_Release(&item->IUnknown_iface);
683 }
685
687
688 memset(queue, 0, sizeof(*queue));
689}
690
692{
693 struct work_item *item;
694
696 return E_OUTOFMEMORY;
697
698 queue->ops->submit(queue, item);
699
700 return S_OK;
701}
702
704{
705 struct queue *queue;
706 HRESULT hr;
707
708 if (FAILED(hr = grab_queue(queue_id, &queue)))
709 return hr;
710
712}
713
715{
716 RTWQASYNCRESULT *result_data = (RTWQASYNCRESULT *)result;
718 HRESULT hr;
719
720 if (FAILED(IRtwqAsyncCallback_GetParameters(result_data->pCallback, &flags, &queue)))
722
725
727
729
730 return hr;
731}
732
733/* Return TRUE when the item is actually released by this function. The item could have been already
734 * removed from pending items when it got canceled. */
736{
737 struct queue *queue = item->queue;
738 BOOL ret = FALSE;
739
741 if (item->key)
742 {
743 list_remove(&item->entry);
744 ret = TRUE;
745 item->key = 0;
746 IUnknown_Release(&item->IUnknown_iface);
747 }
749 return ret;
750}
751
753 TP_WAIT_RESULT wait_result)
754{
755 struct work_item *item = context;
756
757 TRACE("result object %p.\n", item->result);
758
760
761 IUnknown_Release(&item->IUnknown_iface);
762}
763
765 TP_WAIT_RESULT wait_result)
766{
767 struct work_item *item = context;
768
769 TRACE("result object %p.\n", item->result);
770
773
774 IUnknown_Release(&item->IUnknown_iface);
775}
776
778{
779 struct work_item *item = context;
780
781 TRACE("result object %p.\n", item->result);
782
784
785 IUnknown_Release(&item->IUnknown_iface);
786}
787
789{
790 struct work_item *item = context;
791
792 TRACE("result object %p.\n", item->result);
793
796
797 IUnknown_Release(&item->IUnknown_iface);
798}
799
801{
802 struct work_item *item = context;
803
804 IUnknown_AddRef(&item->IUnknown_iface);
805
807
808 IUnknown_Release(&item->IUnknown_iface);
809}
810
812{
814 item->key = *key;
815
816 EnterCriticalSection(&item->queue->cs);
817 list_add_tail(&item->queue->pending_items, &item->entry);
818 IUnknown_AddRef(&item->IUnknown_iface);
819 LeaveCriticalSection(&item->queue->cs);
820}
821
824{
826 struct work_item *item;
827
829 return E_OUTOFMEMORY;
830
831 if (key)
832 {
835 }
836 else
838
839 item->u.wait_object = CreateThreadpoolWait(callback, item,
842 SetThreadpoolWait(item->u.wait_object, event, NULL);
843
844 TRACE("dispatched %p.\n", result);
845
846 return S_OK;
847}
848
851{
853 struct work_item *item;
854 FILETIME filetime;
856
857 if (!(item = alloc_work_item(queue, 0, result)))
858 return E_OUTOFMEMORY;
859
860 if (key)
861 {
863 }
864
865 if (period)
867 else
869
870 t.QuadPart = timeout * 1000 * 10;
871 filetime.dwLowDateTime = t.u.LowPart;
872 filetime.dwHighDateTime = t.u.HighPart;
873
874 item->u.timer_object = CreateThreadpoolTimer(callback, item,
877 SetThreadpoolTimer(item->u.timer_object, &filetime, period, 0);
878
879 TRACE("dispatched %p.\n", result);
880
881 return S_OK;
882}
883
885{
888 struct work_item *item;
889
892 {
893 if (item->key == key)
894 {
895 /* We can't immediately release the item here, because the callback could already be
896 * running somewhere else. And if we release it here, the callback will access freed memory.
897 * So instead we have to make sure the callback is really stopped, or has really finished
898 * running before we do that. And we can't do that in this critical section, which would be a
899 * deadlock. So we first keep an extra reference to it, then leave the critical section to
900 * wait for the thread-pool objects, finally we re-enter critical section to release it. */
901 key >>= 32;
902 IUnknown_AddRef(&item->IUnknown_iface);
904 {
905 wait_object = item->u.wait_object;
906 item->u.wait_object = NULL;
908
912 }
914 {
915 timer_object = item->u.timer_object;
916 item->u.timer_object = NULL;
918
922 }
923 else
924 {
925 WARN("Unknown item key mask %#I64x.\n", key);
927 }
928
930 {
931 /* This means the callback wasn't run during our wait, so we can invoke the
932 * callback with a canceled status, and release the work item. */
934 {
935 IRtwqAsyncResult_SetStatus(item->result, RTWQ_E_OPERATION_CANCELLED);
937 }
938 IUnknown_Release(&item->IUnknown_iface);
939 }
940 IUnknown_Release(&item->IUnknown_iface);
941 return S_OK;
942 }
943 }
945
946 return RTWQ_E_NOT_FOUND;
947}
948
949static HRESULT alloc_user_queue(const struct queue_desc *desc, DWORD *queue_id)
950{
951 struct queue_handle *entry;
952 struct queue *queue;
953 unsigned int idx;
954
956
957 if (platform_lock <= 0)
958 return RTWQ_E_SHUTDOWN;
959
960 if (!(queue = calloc(1, sizeof(*queue))))
961 return E_OUTOFMEMORY;
962
964
966
968 if (entry)
972 else
973 {
975 free(queue);
976 WARN("Out of user queue handles.\n");
977 return E_OUTOFMEMORY;
978 }
979
980 entry->refcount = 1;
981 entry->obj = queue;
982 if (++queue_generation == 0xffff) queue_generation = 1;
983 entry->generation = queue_generation;
985 *queue_id = (idx << 16) | entry->generation;
986
988
989 return S_OK;
990}
991
993{
994 RTWQASYNCRESULT result;
998};
999
1001{
1002 return CONTAINING_RECORD(iface, struct async_result, result.AsyncResult);
1003}
1004
1006{
1007 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
1008
1009 if (IsEqualIID(riid, &IID_IRtwqAsyncResult) ||
1011 {
1012 *obj = iface;
1013 IRtwqAsyncResult_AddRef(iface);
1014 return S_OK;
1015 }
1016
1017 *obj = NULL;
1018 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
1019 return E_NOINTERFACE;
1020}
1021
1023{
1026
1027 TRACE("%p, %lu.\n", iface, refcount);
1028
1029 return refcount;
1030}
1031
1033{
1036
1037 TRACE("%p, %lu.\n", iface, refcount);
1038
1039 if (!refcount)
1040 {
1041 if (result->result.pCallback)
1042 IRtwqAsyncCallback_Release(result->result.pCallback);
1043 if (result->object)
1044 IUnknown_Release(result->object);
1045 if (result->state)
1046 IUnknown_Release(result->state);
1047 if (result->result.hEvent)
1048 CloseHandle(result->result.hEvent);
1049 free(result);
1050
1052 }
1053
1054 return refcount;
1055}
1056
1058{
1060
1061 TRACE("%p, %p.\n", iface, state);
1062
1063 if (!result->state)
1064 return E_POINTER;
1065
1066 *state = result->state;
1067 IUnknown_AddRef(*state);
1068
1069 return S_OK;
1070}
1071
1073{
1075
1076 TRACE("%p.\n", iface);
1077
1078 return result->result.hrStatusResult;
1079}
1080
1082{
1084
1085 TRACE("%p, %#lx.\n", iface, status);
1086
1087 result->result.hrStatusResult = status;
1088
1089 return S_OK;
1090}
1091
1093{
1095
1096 TRACE("%p, %p.\n", iface, object);
1097
1098 if (!result->object)
1099 return E_POINTER;
1100
1101 *object = result->object;
1102 IUnknown_AddRef(*object);
1103
1104 return S_OK;
1105}
1106
1108{
1110
1111 TRACE("%p.\n", iface);
1112
1113 return result->state;
1114}
1115
1116static const IRtwqAsyncResultVtbl async_result_vtbl =
1117{
1126};
1127
1129{
1130 struct async_result *result;
1131
1132 if (!out)
1133 return E_INVALIDARG;
1134
1135 if (!(result = calloc(1, sizeof(*result))))
1136 return E_OUTOFMEMORY;
1137
1139
1140 result->result.AsyncResult.lpVtbl = &async_result_vtbl;
1141 result->refcount = 1;
1142 result->object = object;
1143 if (result->object)
1144 IUnknown_AddRef(result->object);
1145 result->result.pCallback = callback;
1146 if (result->result.pCallback)
1147 IRtwqAsyncCallback_AddRef(result->result.pCallback);
1148 result->state = state;
1149 if (result->state)
1150 IUnknown_AddRef(result->state);
1151
1152 *out = &result->result.AsyncResult;
1153
1154 TRACE("Created async result object %p.\n", *out);
1155
1156 return S_OK;
1157}
1158
1161{
1162 TRACE("%p, %p, %p, %p.\n", object, callback, state, out);
1163
1164 return create_async_result(object, callback, state, out);
1165}
1166
1168{
1170
1171 return S_OK;
1172}
1173
1175{
1177
1178 return S_OK;
1179}
1180
1181static void init_system_queues(void)
1182{
1183 struct queue_desc desc;
1184 HRESULT hr;
1185
1186 /* Always initialize standard queue, keep the rest lazy. */
1187
1189
1191 {
1193 return;
1194 }
1195
1197 WARN("Failed to initialize MTA, hr %#lx.\n", hr);
1198
1199 desc.queue_type = RTWQ_STANDARD_WORKQUEUE;
1200 desc.ops = &pool_queue_ops;
1201 desc.target_queue = 0;
1203
1205}
1206
1208{
1210 {
1212 }
1213
1214 return S_OK;
1215}
1216
1217static void shutdown_system_queues(void)
1218{
1219 unsigned int i;
1220 HRESULT hr;
1221
1223
1224 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
1225 {
1227 }
1228
1230 WARN("Failed to uninitialize MTA, hr %#lx.\n", hr);
1231
1233}
1234
1236{
1237 if (platform_lock <= 0)
1238 return S_OK;
1239
1241 {
1243 }
1244
1245 return S_OK;
1246}
1247
1249{
1250 struct queue *queue;
1251 HRESULT hr;
1252
1253 TRACE("%p, %ld, %p, %p.\n", event, priority, result, key);
1254
1256 return hr;
1257
1259
1260 return hr;
1261}
1262
1264{
1265 struct queue *queue;
1266 HRESULT hr;
1267
1269 return hr;
1270
1271 TRACE("%p, %s, %p.\n", result, wine_dbgstr_longlong(timeout), key);
1272
1274}
1275
1277{
1278 TRACE("%p, %s, %p.\n", result, wine_dbgstr_longlong(timeout), key);
1279
1281}
1282
1284{
1287 RTWQPERIODICCALLBACK callback;
1288};
1289
1291{
1293}
1294
1296{
1297 if (IsEqualIID(riid, &IID_IRtwqAsyncCallback) ||
1299 {
1300 *obj = iface;
1301 IRtwqAsyncCallback_AddRef(iface);
1302 return S_OK;
1303 }
1304
1305 *obj = NULL;
1306 return E_NOINTERFACE;
1307}
1308
1310{
1313
1314 TRACE("%p, %lu.\n", iface, refcount);
1315
1316 return refcount;
1317}
1318
1320{
1323
1324 TRACE("%p, %lu.\n", iface, refcount);
1325
1326 if (!refcount)
1327 free(callback);
1328
1329 return refcount;
1330}
1331
1333{
1334 return E_NOTIMPL;
1335}
1336
1338{
1341
1342 if (FAILED(IRtwqAsyncResult_GetObject(result, &context)))
1343 WARN("Expected object to be set for result object.\n");
1344
1345 callback->callback(context);
1346
1347 if (context)
1348 IUnknown_Release(context);
1349
1350 return S_OK;
1351}
1352
1353static const IRtwqAsyncCallbackVtbl periodic_callback_vtbl =
1354{
1360};
1361
1363{
1364 struct periodic_callback *object;
1365
1366 if (!(object = calloc(1, sizeof(*object))))
1367 return E_OUTOFMEMORY;
1368
1369 object->IRtwqAsyncCallback_iface.lpVtbl = &periodic_callback_vtbl;
1370 object->refcount = 1;
1371 object->callback = callback;
1372
1373 *out = &object->IRtwqAsyncCallback_iface;
1374
1375 return S_OK;
1376}
1377
1379{
1381 RTWQWORKITEM_KEY workitem_key;
1383 struct queue *queue;
1384 HRESULT hr;
1385
1386 TRACE("%p, %p, %p.\n", callback, context, key);
1387
1389 return hr;
1390
1392 return hr;
1393
1395 IRtwqAsyncCallback_Release(periodic_callback);
1396 if (FAILED(hr))
1397 return hr;
1398
1399 /* Same period MFGetTimerPeriodicity() returns. */
1400 hr = queue_submit_timer(queue, result, 0, 10, key ? &workitem_key : NULL);
1401
1402 IRtwqAsyncResult_Release(result);
1403
1404 if (key)
1405 *key = workitem_key;
1406
1407 return S_OK;
1408}
1409
1411{
1412 struct queue *queue;
1413 HRESULT hr;
1414
1415 TRACE("%#lx.\n", key);
1416
1418 return hr;
1419
1421}
1422
1424{
1425 struct queue *queue;
1426 HRESULT hr;
1427
1428 TRACE("%s.\n", wine_dbgstr_longlong(key));
1429
1431 return hr;
1432
1433 return queue_cancel_item(queue, key);
1434}
1435
1437{
1438 TRACE("%p.\n", result);
1439
1441}
1442
1444{
1445 TRACE("%#lx, %ld, %p.\n", queue, priority, result);
1446
1448}
1449
1451{
1452 struct queue_desc desc;
1453
1454 TRACE("%d, %p.\n", queue_type, queue);
1455
1456 desc.queue_type = queue_type;
1457 desc.ops = &pool_queue_ops;
1458 desc.target_queue = 0;
1459 return alloc_user_queue(&desc, queue);
1460}
1461
1463{
1464 TRACE("%#lx.\n", queue);
1465
1466 return lock_user_queue(queue);
1467}
1468
1470{
1471 TRACE("%#lx.\n", queue);
1472
1473 return unlock_user_queue(queue);
1474}
1475
1477{
1478 struct queue *queue;
1479 HRESULT hr;
1480 int i;
1481
1482 TRACE("%#lx, %d.\n", queue_id, enable);
1483
1484 lock_user_queue(queue_id);
1485
1486 if (SUCCEEDED(hr = grab_queue(queue_id, &queue)))
1487 {
1488 for (i = 0; i < ARRAY_SIZE(queue->envs); ++i)
1489 queue->envs[i].u.s.LongFunction = !!enable;
1490 }
1491
1492 unlock_user_queue(queue_id);
1493
1494 return hr;
1495}
1496
1498{
1499 struct queue_desc desc;
1500 HRESULT hr;
1501
1502 TRACE("%s, %ld, %p, %p.\n", debugstr_w(usageclass), priority, taskid, queue);
1503
1504 if (!usageclass)
1505 return E_POINTER;
1506
1507 if (!*usageclass && taskid)
1508 return E_INVALIDARG;
1509
1510 if (*usageclass)
1511 FIXME("Class name is ignored.\n");
1512
1514
1515 if (shared_mt_queue)
1517 else
1518 {
1520 desc.ops = &pool_queue_ops;
1521 desc.target_queue = 0;
1523 }
1524
1526
1528
1529 return hr;
1530}
1531
1533{
1534 FIXME("%#lx, %s, %p.\n", queue_id, wine_dbgstr_longlong(deadline), request);
1535
1536 return E_NOTIMPL;
1537}
1538
1540{
1541 FIXME("%#lx, %s, %s, %p.\n", queue_id, wine_dbgstr_longlong(deadline), wine_dbgstr_longlong(predeadline), request);
1542
1543 return E_NOTIMPL;
1544}
1545
1547{
1548 FIXME("%p.\n", request);
1549
1550 return E_NOTIMPL;
1551}
1552
1554{
1555 struct queue_desc desc;
1556
1557 TRACE("%#lx, %p.\n", target_queue, queue);
1558
1559 desc.queue_type = RTWQ_STANDARD_WORKQUEUE;
1560 desc.ops = &serial_queue_ops;
1561 desc.target_queue = target_queue;
1562 return alloc_user_queue(&desc, queue);
1563}
1564
1566{
1567 FIXME("%#lx, %p, %p.\n", queue, hFile, cookie);
1568
1569 return E_NOTIMPL;
1570}
1571
1573{
1574 FIXME("%#lx, %p.\n", queue, cookie);
1575
1576 return E_NOTIMPL;
1577}
1578
1580{
1581 FIXME("%#lx, %p, %p.\n", queue, class, length);
1582
1583 return E_NOTIMPL;
1584}
1585
1587{
1588 FIXME("%#lx, %p.\n", queue, taskid);
1589
1590 return E_NOTIMPL;
1591}
1592
1594{
1595 FIXME("%#lx, %p.\n", queue, priority);
1596
1597 return E_NOTIMPL;
1598}
1599
1601{
1602 FIXME("%s, %p, %ld.\n", debugstr_w(class), taskid, priority);
1603
1604 return E_NOTIMPL;
1605}
1606
1608{
1609 FIXME("\n");
1610
1611 return E_NOTIMPL;
1612}
1613
1616{
1617 FIXME("%#lx, %s, %lu, %ld, %p, %p.\n", queue, debugstr_w(class), taskid, priority, callback, state);
1618
1619 return E_NOTIMPL;
1620}
1621
1623{
1624 FIXME("%p, %p.\n", result, taskid);
1625
1626 return E_NOTIMPL;
1627}
1628
1630{
1631 FIXME("%#lx, %p, %p.\n", queue, callback, state);
1632
1633 return E_NOTIMPL;
1634}
1635
1637{
1638 FIXME("%p.\n", result);
1639
1640 return E_NOTIMPL;
1641}
1642
1644{
1645 FIXME("%p.\n", events);
1646
1647 return E_NOTIMPL;
1648}
1649
1651{
1652 FIXME("%p.\n", events);
1653
1654 return E_NOTIMPL;
1655}
COMPILER_DEPENDENT_INT64 INT64
Definition: actypes.h:132
struct outqueuenode * head
Definition: adnsresfilter.c:66
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
Definition: list.h:37
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:171
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:40
unsigned int idx
Definition: utils.c:41
HRESULT WINAPI CoIncrementMTAUsage(CO_MTA_USAGE_COOKIE *cookie)
Definition: combase.c:2907
HRESULT WINAPI CoDecrementMTAUsage(CO_MTA_USAGE_COOKIE cookie)
Definition: combase.c:2917
#define CloseHandle
Definition: compat.h:739
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define CALLBACK
Definition: compat.h:35
PTP_POOL WINAPI DECLSPEC_HOTPATCH CreateThreadpool(void *reserved)
Definition: threadpool.c:132
PTP_WAIT WINAPI DECLSPEC_HOTPATCH CreateThreadpoolWait(PTP_WAIT_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:63
PTP_TIMER WINAPI DECLSPEC_HOTPATCH CreateThreadpoolTimer(PTP_TIMER_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:20
PTP_CLEANUP_GROUP WINAPI DECLSPEC_HOTPATCH CreateThreadpoolCleanupGroup(void)
Definition: threadpool.c:115
PTP_WORK WINAPI DECLSPEC_HOTPATCH CreateThreadpoolWork(PTP_WORK_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: threadpool.c:82
static void * user_data
Definition: metahost.c:106
#define assert(_expr)
Definition: assert.h:32
static ULONG WINAPI queue_serial_callback_Release(IRtwqAsyncCallback *iface)
Definition: queue.c:263
static HRESULT alloc_user_queue(const struct queue_desc *desc, DWORD *queue_id)
Definition: queue.c:949
HRESULT WINAPI RtwqSetDeadline2(DWORD queue_id, LONGLONG deadline, LONGLONG predeadline, HANDLE *request)
Definition: queue.c:1539
rtwq_callback_queue_id
Definition: queue.c:87
@ RTWQ_CALLBACK_QUEUE_MULTITHREADED
Definition: queue.c:93
@ RTWQ_CALLBACK_QUEUE_IO
Definition: queue.c:91
@ RTWQ_CALLBACK_QUEUE_RT
Definition: queue.c:90
@ RTWQ_CALLBACK_QUEUE_LONG_FUNCTION
Definition: queue.c:94
@ RTWQ_CALLBACK_QUEUE_TIMER
Definition: queue.c:92
@ RTWQ_CALLBACK_QUEUE_UNDEFINED
Definition: queue.c:88
@ RTWQ_CALLBACK_QUEUE_PRIVATE_MASK
Definition: queue.c:95
@ RTWQ_CALLBACK_QUEUE_STANDARD
Definition: queue.c:89
@ RTWQ_CALLBACK_QUEUE_ALL
Definition: queue.c:96
static ULONG WINAPI periodic_callback_Release(IRtwqAsyncCallback *iface)
Definition: queue.c:1319
static LONG next_item_key
Definition: queue.c:35
static ULONG WINAPI work_item_Release(IUnknown *iface)
Definition: queue.c:554
static struct work_item * work_item_impl_from_IUnknown(IUnknown *iface)
Definition: queue.c:149
HRESULT WINAPI RtwqGetWorkQueueMMCSSPriority(DWORD queue, LONG *priority)
Definition: queue.c:1593
static HRESULT WINAPI periodic_callback_QueryInterface(IRtwqAsyncCallback *iface, REFIID riid, void **obj)
Definition: queue.c:1295
static HRESULT WINAPI queue_serial_callback_QueryInterface(IRtwqAsyncCallback *iface, REFIID riid, void **obj)
Definition: queue.c:244
static BOOL queue_release_pending_item(struct work_item *item)
Definition: queue.c:735
static HRESULT grab_queue(DWORD queue_id, struct queue **ret)
Definition: queue.c:623
static struct queue_handle * get_queue_obj(DWORD handle)
Definition: queue.c:72
static void pool_queue_submit(struct queue *queue, struct work_item *item)
Definition: queue.c:380
#define FIRST_USER_QUEUE_HANDLE
Definition: queue.c:29
static const IUnknownVtbl work_item_vtbl
Definition: queue.c:582
HRESULT WINAPI RtwqCancelWorkItem(RTWQWORKITEM_KEY key)
Definition: queue.c:1423
HRESULT WINAPI RtwqUnjoinWorkQueue(DWORD queue, HANDLE cookie)
Definition: queue.c:1572
static void CALLBACK standard_queue_worker(TP_CALLBACK_INSTANCE *instance, void *context, TP_WORK *work)
Definition: queue.c:364
static WORD queue_generation
Definition: queue.c:57
static ULONG WINAPI async_result_Release(IRtwqAsyncResult *iface)
Definition: queue.c:1032
static HRESULT create_periodic_callback_obj(RTWQPERIODICCALLBACK callback, IRtwqAsyncCallback **out)
Definition: queue.c:1362
static HRESULT queue_cancel_item(struct queue *queue, RTWQWORKITEM_KEY key)
Definition: queue.c:884
static void queue_mark_item_pending(DWORD mask, struct work_item *item, RTWQWORKITEM_KEY *key)
Definition: queue.c:811
static void shutdown_system_queues(void)
Definition: queue.c:1217
static LONG platform_lock
Definition: queue.c:69
HRESULT WINAPI RtwqCancelDeadline(HANDLE request)
Definition: queue.c:1546
static void CALLBACK standard_queue_cleanup_callback(void *object_data, void *group_data)
Definition: queue.c:315
HRESULT WINAPI RtwqInvokeCallback(IRtwqAsyncResult *result)
Definition: queue.c:1436
HRESULT WINAPI RtwqAllocateSerialWorkQueue(DWORD target_queue, DWORD *queue)
Definition: queue.c:1553
HRESULT WINAPI RtwqPutWorkItem(DWORD queue, LONG priority, IRtwqAsyncResult *result)
Definition: queue.c:1443
HRESULT WINAPI RtwqPutWaitingWorkItem(HANDLE event, LONG priority, IRtwqAsyncResult *result, RTWQWORKITEM_KEY *key)
Definition: queue.c:1248
static HRESULT WINAPI async_result_GetObject(IRtwqAsyncResult *iface, IUnknown **object)
Definition: queue.c:1092
HRESULT WINAPI RtwqUnregisterPlatformFromMMCSS(void)
Definition: queue.c:1607
static const struct queue_ops pool_queue_ops
Definition: queue.c:405
HRESULT WINAPI RtwqRegisterPlatformEvents(IRtwqPlatformEvents *events)
Definition: queue.c:1643
static HRESULT invoke_async_callback(IRtwqAsyncResult *result)
Definition: queue.c:714
static void CALLBACK waiting_item_cancelable_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_WAIT *wait, TP_WAIT_RESULT wait_result)
Definition: queue.c:764
static CO_MTA_USAGE_COOKIE mta_cookie
Definition: queue.c:70
static ULONG WINAPI queue_serial_callback_AddRef(IRtwqAsyncCallback *iface)
Definition: queue.c:258
static CRITICAL_SECTION_DEBUG queues_critsect_debug
Definition: queue.c:61
#define MAX_USER_QUEUE_HANDLES
Definition: queue.c:30
#define WAIT_ITEM_KEY_MASK
Definition: queue.c:32
static void CALLBACK scheduled_item_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_TIMER *timer)
Definition: queue.c:777
static struct queue_handle user_queues[MAX_USER_QUEUE_HANDLES]
Definition: queue.c:54
static HRESULT create_async_result(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state, IRtwqAsyncResult **out)
Definition: queue.c:1128
static const struct queue_ops serial_queue_ops
Definition: queue.c:528
static struct work_item * serial_queue_is_ack_token(struct queue *queue, struct work_item *item)
Definition: queue.c:461
static void init_system_queues(void)
Definition: queue.c:1181
static HRESULT queue_put_work_item(DWORD queue_id, LONG priority, IRtwqAsyncResult *result)
Definition: queue.c:703
static void CALLBACK scheduled_item_cancelable_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_TIMER *timer)
Definition: queue.c:788
HRESULT WINAPI RtwqRegisterPlatformWithMMCSS(const WCHAR *class, DWORD *taskid, LONG priority)
Definition: queue.c:1600
static HRESULT queue_submit_timer(struct queue *queue, IRtwqAsyncResult *result, INT64 timeout, DWORD period, RTWQWORKITEM_KEY *key)
Definition: queue.c:849
static void CALLBACK periodic_item_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_TIMER *timer)
Definition: queue.c:800
static BOOL serial_queue_shutdown(struct queue *queue)
Definition: queue.c:454
HRESULT WINAPI RtwqUnlockPlatform(void)
Definition: queue.c:1174
static RTWQWORKITEM_KEY generate_item_key(DWORD mask)
Definition: queue.c:42
static struct work_item * alloc_work_item(struct queue *queue, LONG priority, IRtwqAsyncResult *result)
Definition: queue.c:589
static const IRtwqAsyncCallbackVtbl queue_serial_callback_vtbl
Definition: queue.c:286
static ULONG WINAPI work_item_AddRef(IUnknown *iface)
Definition: queue.c:548
#define SCHEDULED_ITEM_KEY_MASK
Definition: queue.c:33
static ULONG WINAPI periodic_callback_AddRef(IRtwqAsyncCallback *iface)
Definition: queue.c:1309
static IUnknown *WINAPI async_result_GetStateNoAddRef(IRtwqAsyncResult *iface)
Definition: queue.c:1107
static HRESULT WINAPI queue_serial_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result)
Definition: queue.c:278
HRESULT WINAPI RtwqAddPeriodicCallback(RTWQPERIODICCALLBACK callback, IUnknown *context, DWORD *key)
Definition: queue.c:1378
HRESULT WINAPI RtwqRemovePeriodicCallback(DWORD key)
Definition: queue.c:1410
static const IRtwqAsyncResultVtbl async_result_vtbl
Definition: queue.c:1116
static RTWQWORKITEM_KEY get_item_key(DWORD mask, DWORD key)
Definition: queue.c:37
static HRESULT unlock_user_queue(DWORD queue)
Definition: queue.c:213
static void CALLBACK waiting_item_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_WAIT *wait, TP_WAIT_RESULT wait_result)
Definition: queue.c:752
static HRESULT schedule_work_item(IRtwqAsyncResult *result, INT64 timeout, RTWQWORKITEM_KEY *key)
Definition: queue.c:1263
static HRESULT WINAPI queue_serial_callback_GetParameters(IRtwqAsyncCallback *iface, DWORD *flags, DWORD *queue_id)
Definition: queue.c:268
static void init_work_queue(const struct queue_desc *desc, struct queue *queue)
Definition: queue.c:611
HRESULT WINAPI RtwqEndRegisterWorkQueueWithMMCSS(IRtwqAsyncResult *result, DWORD *taskid)
Definition: queue.c:1622
HRESULT WINAPI RtwqUnregisterPlatformEvents(IRtwqPlatformEvents *events)
Definition: queue.c:1650
HRESULT WINAPI RtwqSetDeadline(DWORD queue_id, LONGLONG deadline, HANDLE *request)
Definition: queue.c:1532
static struct async_result * impl_from_IRtwqAsyncResult(IRtwqAsyncResult *iface)
Definition: queue.c:1000
static HRESULT WINAPI periodic_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result)
Definition: queue.c:1337
static CRITICAL_SECTION queues_section
Definition: queue.c:60
static HRESULT queue_submit_item(struct queue *queue, LONG priority, IRtwqAsyncResult *result)
Definition: queue.c:691
HRESULT WINAPI RtwqStartup(void)
Definition: queue.c:1207
HRESULT WINAPI RtwqGetWorkQueueMMCSSClass(DWORD queue, WCHAR *class, DWORD *length)
Definition: queue.c:1579
HRESULT WINAPI RtwqShutdown(void)
Definition: queue.c:1235
static const IRtwqAsyncCallbackVtbl periodic_callback_vtbl
Definition: queue.c:1353
static HRESULT WINAPI work_item_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
Definition: queue.c:535
HRESULT WINAPI RtwqEndUnregisterWorkQueueWithMMCSS(IRtwqAsyncResult *result)
Definition: queue.c:1636
static DWORD shared_mt_queue
Definition: queue.c:58
HRESULT WINAPI RtwqCreateAsyncResult(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state, IRtwqAsyncResult **out)
Definition: queue.c:1159
static struct queue_handle * next_free_user_queue
Definition: queue.c:55
HRESULT WINAPI RtwqLockPlatform(void)
Definition: queue.c:1167
static BOOL pool_queue_shutdown(struct queue *queue)
Definition: queue.c:352
static HRESULT WINAPI async_result_GetState(IRtwqAsyncResult *iface, IUnknown **state)
Definition: queue.c:1057
HRESULT WINAPI RtwqAllocateWorkQueue(RTWQ_WORKQUEUE_TYPE queue_type, DWORD *queue)
Definition: queue.c:1450
static struct queue_handle * next_unused_user_queue
Definition: queue.c:56
static void shutdown_queue(struct queue *queue)
Definition: queue.c:671
static HRESULT lock_user_queue(DWORD queue)
Definition: queue.c:194
HRESULT WINAPI RtwqSetLongRunning(DWORD queue_id, BOOL enable)
Definition: queue.c:1476
static ULONG WINAPI async_result_AddRef(IRtwqAsyncResult *iface)
Definition: queue.c:1022
static struct work_item * serial_queue_get_next(struct queue *queue, struct work_item *item)
Definition: queue.c:412
rtwq_callback_flags
Definition: queue.c:101
@ RTWQ_REPLY_CALLBACK
Definition: queue.c:105
@ RTWQ_LOCALIZE_REMOTE_CALLBACK
Definition: queue.c:106
@ RTWQ_BLOCKING_CALLBACK
Definition: queue.c:104
@ RTWQ_FAST_IO_PROCESSING_CALLBACK
Definition: queue.c:102
@ RTWQ_SIGNAL_CALLBACK
Definition: queue.c:103
HRESULT WINAPI RtwqGetWorkQueueMMCSSTaskId(DWORD queue, DWORD *taskid)
Definition: queue.c:1586
HRESULT WINAPI RtwqJoinWorkQueue(DWORD queue, HANDLE hFile, HANDLE *cookie)
Definition: queue.c:1565
HRESULT WINAPI RtwqBeginRegisterWorkQueueWithMMCSS(DWORD queue, const WCHAR *class, DWORD taskid, LONG priority, IRtwqAsyncCallback *callback, IUnknown *state)
Definition: queue.c:1614
static void serial_queue_submit(struct queue *queue, struct work_item *item)
Definition: queue.c:476
static struct queue * queue_impl_from_IRtwqAsyncCallback(IRtwqAsyncCallback *iface)
Definition: queue.c:239
static HRESULT WINAPI async_result_QueryInterface(IRtwqAsyncResult *iface, REFIID riid, void **obj)
Definition: queue.c:1005
static HRESULT WINAPI async_result_SetStatus(IRtwqAsyncResult *iface, HRESULT status)
Definition: queue.c:1081
HRESULT WINAPI RtwqScheduleWorkItem(IRtwqAsyncResult *result, INT64 timeout, RTWQWORKITEM_KEY *key)
Definition: queue.c:1276
static HRESULT WINAPI periodic_callback_GetParameters(IRtwqAsyncCallback *iface, DWORD *flags, DWORD *queue)
Definition: queue.c:1332
HRESULT WINAPI RtwqLockSharedWorkQueue(const WCHAR *usageclass, LONG priority, DWORD *taskid, DWORD *queue)
Definition: queue.c:1497
work_item_type
Definition: queue.c:122
@ WORK_ITEM_WORK
Definition: queue.c:123
@ WORK_ITEM_TIMER
Definition: queue.c:124
@ WORK_ITEM_WAIT
Definition: queue.c:125
HRESULT WINAPI RtwqLockWorkQueue(DWORD queue)
Definition: queue.c:1462
static HRESULT WINAPI async_result_GetStatus(IRtwqAsyncResult *iface)
Definition: queue.c:1072
static HRESULT serial_queue_init(const struct queue_desc *desc, struct queue *queue)
Definition: queue.c:444
static struct periodic_callback * impl_from_IRtwqAsyncCallback(IRtwqAsyncCallback *iface)
Definition: queue.c:1290
static void CALLBACK serial_queue_finalization_callback(PTP_CALLBACK_INSTANCE instance, void *user_data)
Definition: queue.c:423
system_queue_index
Definition: queue.c:110
@ SYS_QUEUE_IO
Definition: queue.c:113
@ SYS_QUEUE_COUNT
Definition: queue.c:118
@ SYS_QUEUE_TIMER
Definition: queue.c:114
@ SYS_QUEUE_LONG_FUNCTION
Definition: queue.c:117
@ SYS_QUEUE_RT
Definition: queue.c:112
@ SYS_QUEUE_STANDARD
Definition: queue.c:111
@ SYS_QUEUE_MULTITHREADED
Definition: queue.c:115
@ SYS_QUEUE_DO_NOT_USE
Definition: queue.c:116
static HRESULT pool_queue_init(const struct queue_desc *desc, struct queue *queue)
Definition: queue.c:319
HRESULT WINAPI RtwqBeginUnregisterWorkQueueWithMMCSS(DWORD queue, IRtwqAsyncCallback *callback, IUnknown *state)
Definition: queue.c:1629
static struct queue system_queues[SYS_QUEUE_COUNT]
Definition: queue.c:295
static struct queue * get_system_queue(DWORD queue_id)
Definition: queue.c:297
HRESULT WINAPI RtwqUnlockWorkQueue(DWORD queue)
Definition: queue.c:1469
static HRESULT queue_submit_wait(struct queue *queue, HANDLE event, LONG priority, IRtwqAsyncResult *result, RTWQWORKITEM_KEY *key)
Definition: queue.c:822
return ret
Definition: mutex.c:147
_In_ uint64_t _In_ uint64_t _In_ uint64_t generation
Definition: btrfs.c:2996
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble t
Definition: gl.h:2047
struct _cl_event * event
Definition: glext.h:7739
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
GLboolean enable
Definition: glext.h:11120
const GLuint const GLclampf * priorities
Definition: glext.h:8103
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
#define InterlockedExchangeAdd
Definition: interlocked.h:196
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
HANDLE events[2]
Definition: event.c:4
static IPrintDialogCallback callback
Definition: printdlg.c:326
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
static const struct metadata_item item2[]
Definition: metadata.c:3608
static int priority
Definition: timer.c:163
_In_ HANDLE hFile
Definition: mswsock.h:90
#define BOOL
Definition: nt_native.h:43
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define calloc
Definition: rosglue.h:14
RTWQ_WORKQUEUE_TYPE
Definition: rtworkq.idl:22
@ RTWQ_WINDOW_WORKQUEUE
Definition: rtworkq.idl:24
@ RTWQ_MULTITHREADED_WORKQUEUE
Definition: rtworkq.idl:25
@ RTWQ_STANDARD_WORKQUEUE
Definition: rtworkq.idl:23
unsigned __int64 RTWQWORKITEM_KEY
Definition: rtworkq.idl:28
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwHighDateTime
Definition: mapidefs.h:66
DWORD dwLowDateTime
Definition: mapidefs.h:65
PTP_CLEANUP_GROUP CleanupGroup
Definition: winnt_old.h:4805
TP_CALLBACK_PRIORITY CallbackPriority
Definition: winnt_old.h:4818
union _TP_CALLBACK_ENVIRON_V3::@4726 u
struct _TP_CALLBACK_ENVIRON_V3::@4726::@4727 s
IUnknown * object
Definition: queue.c:996
RTWQASYNCRESULT result
Definition: queue.c:994
IUnknown * state
Definition: queue.c:997
LONG refcount
Definition: queue.c:995
Definition: http.c:7252
Definition: cookie.c:34
uacpi_u8 type
Definition: interpreter.c:38
Definition: copy.c:22
Definition: list.h:15
RTWQPERIODICCALLBACK callback
Definition: queue.c:1287
IRtwqAsyncCallback IRtwqAsyncCallback_iface
Definition: queue.c:1285
DWORD target_queue
Definition: queue.c:175
RTWQ_WORKQUEUE_TYPE queue_type
Definition: queue.c:173
const struct queue_ops * ops
Definition: queue.c:174
LONG refcount
Definition: queue.c:50
void * obj
Definition: queue.c:49
WORD generation
Definition: queue.c:51
HRESULT(* init)(const struct queue_desc *desc, struct queue *queue)
Definition: queue.c:166
BOOL(* shutdown)(struct queue *queue)
Definition: queue.c:167
void(* submit)(struct queue *queue, struct work_item *item)
Definition: queue.c:168
Definition: queue.c:179
DWORD target_queue
Definition: queue.c:189
queue()
Definition: _queue.h:86
struct list pending_items
Definition: queue.c:185
IRtwqAsyncCallback IRtwqAsyncCallback_iface
Definition: queue.c:180
PTP_SIMPLE_CALLBACK finalization_callback
Definition: queue.c:188
TP_POOL * pool
Definition: queue.c:182
CRITICAL_SECTION cs
Definition: queue.c:184
TP_CALLBACK_ENVIRON_V3 envs[ARRAY_SIZE(priorities)]
Definition: queue.c:183
const struct queue_ops * ops
Definition: queue.c:181
DWORD id
Definition: queue.c:186
Definition: tftpd.h:86
Definition: ps.c:97
Definition: dhcpd.h:248
enum work_item_type type
Definition: queue.c:140
PTP_SIMPLE_CALLBACK finalization_callback
Definition: queue.c:139
TP_WORK * work_object
Definition: queue.c:143
union work_item::@575 u
LONG priority
Definition: queue.c:137
IUnknown IUnknown_iface
Definition: queue.c:130
struct list entry
Definition: queue.c:132
IRtwqAsyncResult * reply_result
Definition: queue.c:134
TP_WAIT * wait_object
Definition: queue.c:144
LONG refcount
Definition: queue.c:131
TP_TIMER * timer_object
Definition: queue.c:145
IRtwqAsyncResult * result
Definition: queue.c:133
struct queue * queue
Definition: queue.c:135
DWORD flags
Definition: queue.c:138
RTWQWORKITEM_KEY key
Definition: queue.c:136
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:687
#define LIST_ENTRY(type)
Definition: queue.h:175
WINBASEAPI VOID WINAPI WaitForThreadpoolTimerCallbacks(_Inout_ PTP_TIMER pti, _In_ BOOL fCancelPendingCallbacks)
WINBASEAPI VOID WINAPI CloseThreadpoolWork(_Inout_ PTP_WORK pwk)
WINBASEAPI VOID WINAPI CloseThreadpoolTimer(_Inout_ PTP_TIMER pti)
WINBASEAPI VOID WINAPI SetThreadpoolTimer(_Inout_ PTP_TIMER pti, _In_opt_ PFILETIME pftDueTime, _In_ DWORD msPeriod, _In_opt_ DWORD msWindowLength)
WINBASEAPI VOID WINAPI SubmitThreadpoolWork(_Inout_ PTP_WORK pwk)
WINBASEAPI BOOL WINAPI SetThreadpoolThreadMinimum(_Inout_ PTP_POOL ptpp, _In_ DWORD cthrdMic)
WINBASEAPI VOID WINAPI SetThreadpoolWait(_Inout_ PTP_WAIT pwa, _In_opt_ HANDLE h, _In_opt_ PFILETIME pftTimeout)
WINBASEAPI VOID WINAPI CloseThreadpool(_Inout_ PTP_POOL ptpp)
WINBASEAPI VOID WINAPI CloseThreadpoolWait(_Inout_ PTP_WAIT pwa)
WINBASEAPI VOID WINAPI WaitForThreadpoolWaitCallbacks(_Inout_ PTP_WAIT pwa, _In_ BOOL fCancelPendingCallbacks)
WINBASEAPI VOID WINAPI CloseThreadpoolCleanupGroupMembers(_Inout_ PTP_CLEANUP_GROUP ptpcg, _In_ BOOL fCancelPendingCallbacks, _Inout_opt_ PVOID pvCleanupContext)
WINBASEAPI VOID WINAPI SetThreadpoolThreadMaximum(_Inout_ PTP_POOL ptpp, _In_ DWORD cthrdMost)
#define DWORD_PTR
Definition: treelist.c:76
int64_t LONGLONG
Definition: typedefs.h:68
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480
@ TP_CALLBACK_PRIORITY_NORMAL
Definition: winnt_old.h:4766
@ TP_CALLBACK_PRIORITY_HIGH
Definition: winnt_old.h:4765
@ TP_CALLBACK_PRIORITY_LOW
Definition: winnt_old.h:4767
VOID(NTAPI * PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PTP_WAIT, TP_WAIT_RESULT)
Definition: winnt_old.h:4797
struct _TP_CALLBACK_INSTANCE * PTP_CALLBACK_INSTANCE
Definition: winnt_old.h:4756
struct _TP_POOL TP_POOL
Definition: winnt_old.h:4754
DWORD TP_WAIT_RESULT
Definition: winnt_old.h:4761
struct _TP_WAIT TP_WAIT
Definition: winnt_old.h:4758
enum _TP_CALLBACK_PRIORITY TP_CALLBACK_PRIORITY
struct _TP_WORK TP_WORK
Definition: winnt_old.h:4755
struct _TP_TIMER TP_TIMER
Definition: winnt_old.h:4757
VOID(NTAPI * PTP_SIMPLE_CALLBACK)(_Inout_ PTP_CALLBACK_INSTANCE Instance, _Inout_opt_ PVOID Context)
Definition: winnt_old.h:4787
VOID(NTAPI * PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE, PVOID, PTP_TIMER)
Definition: winnt_old.h:4796
struct _TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE
Definition: winnt_old.h:4756