1/*
2 * Copyright (C) 2008, 2014 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
27#include "config.h"
28#include "ThreadGlobalData.h"
29
30#include "CachedResourceRequestInitiators.h"
31#include "EventNames.h"
32#include "QualifiedNameCache.h"
33#include "TextCodecICU.h"
34#include "ThreadTimers.h"
35#include <wtf/MainThread.h>
36#include <wtf/ThreadSpecific.h>
37#include <wtf/Threading.h>
38#include <wtf/text/StringImpl.h>
39
40namespace WebCore {
41
42ThreadGlobalData::ThreadGlobalData()
43 : m_cachedResourceRequestInitiators(std::make_unique<CachedResourceRequestInitiators>())
44 , m_eventNames(EventNames::create())
45 , m_threadTimers(std::make_unique<ThreadTimers>())
46 , m_qualifiedNameCache(std::make_unique<QualifiedNameCache>())
47#ifndef NDEBUG
48 , m_isMainThread(isMainThread())
49#endif
50 , m_cachedConverterICU(std::make_unique<ICUConverterWrapper>())
51{
52 // This constructor will have been called on the main thread before being called on
53 // any other thread, and is only called once per thread - this makes this a convenient
54 // point to call methods that internally perform a one-time initialization that is not
55 // threadsafe.
56 Thread::current();
57}
58
59ThreadGlobalData::~ThreadGlobalData() = default;
60
61void ThreadGlobalData::destroy()
62{
63 m_cachedConverterICU = nullptr;
64
65 m_eventNames = nullptr;
66 m_threadTimers = nullptr;
67 m_qualifiedNameCache = nullptr;
68}
69
70#if USE(WEB_THREAD)
71static ThreadSpecific<RefPtr<ThreadGlobalData>>* staticData { nullptr };
72static ThreadGlobalData* sharedMainThreadStaticData { nullptr };
73
74void ThreadGlobalData::setWebCoreThreadData()
75{
76 ASSERT(isWebThread());
77 ASSERT(&threadGlobalData() != sharedMainThreadStaticData);
78
79 // Set WebThread's ThreadGlobalData object to be the same as the main UI thread.
80 **staticData = adoptRef(sharedMainThreadStaticData);
81
82 ASSERT(&threadGlobalData() == sharedMainThreadStaticData);
83}
84
85ThreadGlobalData& threadGlobalData()
86{
87 if (UNLIKELY(!staticData)) {
88 staticData = new ThreadSpecific<RefPtr<ThreadGlobalData>>;
89 auto& result = **staticData;
90 ASSERT(!result);
91 result = adoptRef(new ThreadGlobalData);
92 // WebThread and main UI thread need to share the same object. Save it in a static
93 // here, the WebThread will pick it up in setWebCoreThreadData().
94 if (pthread_main_np()) {
95 sharedMainThreadStaticData = result.get();
96 result->ref();
97 }
98 return *result;
99 }
100
101 auto& result = **staticData;
102 if (!result)
103 result = adoptRef(new ThreadGlobalData);
104 return *result;
105}
106
107#else
108
109static ThreadSpecific<ThreadGlobalData>* staticData { nullptr };
110
111ThreadGlobalData& threadGlobalData()
112{
113 if (UNLIKELY(!staticData))
114 staticData = new ThreadSpecific<ThreadGlobalData>;
115 return **staticData;
116}
117
118#endif
119
120} // namespace WebCore
121