Improve use of NeverDestroyed
[WebKit-https.git] / Source / WebKitLegacy / Storage / StorageThread.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "StorageThread.h"
27
28 #include <wtf/AutodrainedPool.h>
29 #include <wtf/HashSet.h>
30 #include <wtf/MainThread.h>
31 #include <wtf/NeverDestroyed.h>
32
33 namespace WebCore {
34
35 static HashSet<StorageThread*>& activeStorageThreads()
36 {
37     ASSERT(isMainThread());
38     static NeverDestroyed<HashSet<StorageThread*>> threads;
39     return threads;
40 }
41
42 StorageThread::StorageThread()
43 {
44     ASSERT(isMainThread());
45 }
46
47 StorageThread::~StorageThread()
48 {
49     ASSERT(isMainThread());
50     ASSERT(!m_thread);
51 }
52
53 bool StorageThread::start()
54 {
55     ASSERT(isMainThread());
56     if (!m_thread) {
57         m_thread = Thread::create("WebCore: LocalStorage", [this] {
58             threadEntryPoint();
59         });
60     }
61     activeStorageThreads().add(this);
62     return m_thread;
63 }
64
65 void StorageThread::threadEntryPoint()
66 {
67     ASSERT(!isMainThread());
68
69     while (auto function = m_queue.waitForMessage()) {
70         AutodrainedPool pool;
71         (*function)();
72     }
73 }
74
75 void StorageThread::dispatch(Function<void ()>&& function)
76 {
77     ASSERT(isMainThread());
78     ASSERT(!m_queue.killed() && m_thread);
79     m_queue.append(std::make_unique<Function<void ()>>(WTFMove(function)));
80 }
81
82 void StorageThread::terminate()
83 {
84     ASSERT(isMainThread());
85     ASSERT(!m_queue.killed() && m_thread);
86     activeStorageThreads().remove(this);
87     // Even in weird, exceptional cases, don't wait on a nonexistent thread to terminate.
88     if (!m_thread)
89         return;
90
91     m_queue.append(std::make_unique<Function<void ()>>([this] {
92         performTerminate();
93     }));
94     m_thread->waitForCompletion();
95     ASSERT(m_queue.killed());
96     m_thread = nullptr;
97 }
98
99 void StorageThread::performTerminate()
100 {
101     ASSERT(!isMainThread());
102     m_queue.kill();
103 }
104
105 void StorageThread::releaseFastMallocFreeMemoryInAllThreads()
106 {
107     for (auto& thread : activeStorageThreads())
108         thread->dispatch(&WTF::releaseFastMallocFreeMemory);
109 }
110
111 }