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 COMPUTER, 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 COMPUTER, 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#ifndef ThreadGlobalData_h 28#define ThreadGlobalData_h 29 30#include <wtf/HashMap.h> 31#include <wtf/HashSet.h> 32#include <wtf/Noncopyable.h> 33#include <wtf/OwnPtr.h> 34#include <wtf/text/StringHash.h> 35 36#if ENABLE(WORKERS) 37#include <wtf/ThreadSpecific.h> 38#include <wtf/Threading.h> 39using WTF::ThreadSpecific; 40#endif 41 42namespace WebCore { 43 44 class EventNames; 45 class ThreadLocalInspectorCounters; 46 class ThreadTimers; 47 48 struct CachedResourceRequestInitiators; 49 struct ICUConverterWrapper; 50 struct TECConverterWrapper; 51 52 class ThreadGlobalData { 53 WTF_MAKE_NONCOPYABLE(ThreadGlobalData); 54 public: 55 ThreadGlobalData(); 56 ~ThreadGlobalData(); 57 void destroy(); // called on workers to clean up the ThreadGlobalData before the thread exits. 58 59 const CachedResourceRequestInitiators& cachedResourceRequestInitiators() { return *m_cachedResourceRequestInitiators; } 60 EventNames& eventNames() { return *m_eventNames; } 61 ThreadTimers& threadTimers() { return *m_threadTimers; } 62 63#if USE(ICU_UNICODE) 64 ICUConverterWrapper& cachedConverterICU() { return *m_cachedConverterICU; } 65#endif 66 67#if PLATFORM(MAC) 68 TECConverterWrapper& cachedConverterTEC() { return *m_cachedConverterTEC; } 69#endif 70 71#if ENABLE(INSPECTOR) 72 ThreadLocalInspectorCounters& inspectorCounters() { return *m_inspectorCounters; } 73#endif 74 75 private: 76 OwnPtr<CachedResourceRequestInitiators> m_cachedResourceRequestInitiators; 77 OwnPtr<EventNames> m_eventNames; 78 OwnPtr<ThreadTimers> m_threadTimers; 79 80#ifndef NDEBUG 81 bool m_isMainThread; 82#endif 83 84#if USE(ICU_UNICODE) 85 OwnPtr<ICUConverterWrapper> m_cachedConverterICU; 86#endif 87 88#if PLATFORM(MAC) 89 OwnPtr<TECConverterWrapper> m_cachedConverterTEC; 90#endif 91 92#if ENABLE(INSPECTOR) 93 OwnPtr<ThreadLocalInspectorCounters> m_inspectorCounters; 94#endif 95 96#if ENABLE(WORKERS) 97 static ThreadSpecific<ThreadGlobalData>* staticData; 98#else 99 static ThreadGlobalData* staticData; 100#endif 101 friend ThreadGlobalData& threadGlobalData(); 102 }; 103 104inline ThreadGlobalData& threadGlobalData() 105{ 106 // FIXME: Workers are not necessarily the only feature that make per-thread global data necessary. 107 // We need to check for e.g. database objects manipulating strings on secondary threads. 108 109#if ENABLE(WORKERS) 110 // ThreadGlobalData is used on main thread before it could possibly be used on secondary ones, so there is no need for synchronization here. 111 if (!ThreadGlobalData::staticData) 112 ThreadGlobalData::staticData = new ThreadSpecific<ThreadGlobalData>; 113 return **ThreadGlobalData::staticData; 114#else 115 if (!ThreadGlobalData::staticData) { 116 ThreadGlobalData::staticData = static_cast<ThreadGlobalData*>(fastMalloc(sizeof(ThreadGlobalData))); 117 // ThreadGlobalData constructor indirectly uses staticData, so we need to set up the memory before invoking it. 118 new (NotNull, ThreadGlobalData::staticData) ThreadGlobalData; 119 } 120 return *ThreadGlobalData::staticData; 121#endif 122} 123 124} // namespace WebCore 125 126#endif // ThreadGlobalData_h 127