1/*
2 * Copyright (C) 2010, 2015 Apple Inc. All rights reserved.
3 * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
4 * Copyright (C) 2017 Sony Interactive Entertainment Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 * THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#pragma once
29
30#include <wtf/Forward.h>
31#include <wtf/FunctionDispatcher.h>
32#include <wtf/Seconds.h>
33#include <wtf/Threading.h>
34
35#if USE(COCOA_EVENT_LOOP)
36#include <dispatch/dispatch.h>
37#endif
38
39#if USE(WINDOWS_EVENT_LOOP)
40#include <wtf/HashMap.h>
41#include <wtf/ThreadingPrimitives.h>
42#include <wtf/Vector.h>
43#endif
44
45#if USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP)
46#include <wtf/Condition.h>
47#include <wtf/RunLoop.h>
48#endif
49
50namespace WTF {
51
52class WorkQueue final : public FunctionDispatcher {
53
54public:
55 enum class Type {
56 Serial,
57 Concurrent
58 };
59 enum class QOS {
60 UserInteractive,
61 UserInitiated,
62 Default,
63 Utility,
64 Background
65 };
66
67 WTF_EXPORT_PRIVATE static Ref<WorkQueue> create(const char* name, Type = Type::Serial, QOS = QOS::Default);
68 virtual ~WorkQueue();
69
70 WTF_EXPORT_PRIVATE void dispatch(Function<void()>&&) override;
71 WTF_EXPORT_PRIVATE void dispatchAfter(Seconds, Function<void()>&&);
72
73 WTF_EXPORT_PRIVATE static void concurrentApply(size_t iterations, WTF::Function<void(size_t index)>&&);
74
75#if USE(COCOA_EVENT_LOOP)
76 dispatch_queue_t dispatchQueue() const { return m_dispatchQueue; }
77#elif USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP)
78 RunLoop& runLoop() const { return *m_runLoop; }
79#endif
80
81private:
82 explicit WorkQueue(const char* name, Type, QOS);
83
84 void platformInitialize(const char* name, Type, QOS);
85 void platformInvalidate();
86
87#if USE(WINDOWS_EVENT_LOOP)
88 static void CALLBACK timerCallback(void* context, BOOLEAN timerOrWaitFired);
89 static DWORD WINAPI workThreadCallback(void* context);
90
91 bool tryRegisterAsWorkThread();
92 void unregisterAsWorkThread();
93 void performWorkOnRegisteredWorkThread();
94#endif
95
96#if USE(COCOA_EVENT_LOOP)
97 static void executeFunction(void*);
98 dispatch_queue_t m_dispatchQueue;
99#elif USE(WINDOWS_EVENT_LOOP)
100 volatile LONG m_isWorkThreadRegistered;
101
102 Lock m_functionQueueLock;
103 Vector<Function<void()>> m_functionQueue;
104
105 HANDLE m_timerQueue;
106#elif USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP)
107 RunLoop* m_runLoop;
108#endif
109};
110
111}
112
113using WTF::WorkQueue;
114