<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[199621] trunk/Source/WTF</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/199621">199621</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2016-04-15 21:52:18 -0700 (Fri, 15 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>iTunes crashing JavaScriptCore.dll
https://bugs.webkit.org/show_bug.cgi?id=156647

Reviewed by Geoffrey Garen.

If a thread was created without using the WTF thread apis and that thread uses
a JavaScript VM and that thread exits with the VM still around, JSC won't know
that the thread has exited.  Currently, we use ThreadSpecificThreadExit() to
clean up any thread specific keys.  Cleaning up these keys is how JSC is
notified of a thread exit.  We only call ThreadSpecificThreadExit() from
wtfThreadEntryPoint() when the thread entry point function returns.
This mechanism was put in place for Windos because we layer the WTF::ThreadSpecific
functionality on top of TLS (Thread Local Storage), but TLS doesn't have
a thread exiting callback the way that pthread_create_key.

The fix is to change from using TLS to using FLS (Fiber Local Storage).  Although
Windows allows multiple fibers per thread, WebKit is not designed to work with a
multiple fibers per thread.  When ther is only one fiber per thread, FLS works just
like TLS, but it has the destroy callback.

I restructured the Windows version of WTF::ThreadSpecific to be almost the same
as the pthread version.
        
* wtf/ThreadSpecific.h:
(WTF::threadSpecificKeyCreate):
(WTF::threadSpecificKeyDelete):
(WTF::threadSpecificSet):
(WTF::threadSpecificGet):
(WTF::ThreadSpecific&lt;T&gt;::ThreadSpecific):
(WTF::ThreadSpecific&lt;T&gt;::~ThreadSpecific):
(WTF::ThreadSpecific&lt;T&gt;::get):
(WTF::ThreadSpecific&lt;T&gt;::set):
(WTF::ThreadSpecific&lt;T&gt;::destroy):
Restructured to use FLS.  Renamed TLS* to FLS*.

* wtf/ThreadSpecificWin.cpp:
(WTF::flsKeyCount):
(WTF::flsKeys):
Renamed from tlsKey*() to flsKey*().

(WTF::destructorsList): Deleted.
(WTF::destructorsMutex): Deleted.
(WTF::PlatformThreadSpecificKey::PlatformThreadSpecificKey): Deleted.
(WTF::PlatformThreadSpecificKey::~PlatformThreadSpecificKey): Deleted.
(WTF::PlatformThreadSpecificKey::setValue): Deleted.
(WTF::PlatformThreadSpecificKey::value): Deleted.
(WTF::PlatformThreadSpecificKey::callDestructor): Deleted.
(WTF::tlsKeyCount): Deleted.
(WTF::tlsKeys): Deleted.
(WTF::threadSpecificKeyCreate): Deleted.
(WTF::threadSpecificKeyDelete): Deleted.
(WTF::threadSpecificSet): Deleted.
(WTF::threadSpecificGet): Deleted.
(WTF::ThreadSpecificThreadExit): Deleted.

* wtf/ThreadingWin.cpp:
(WTF::wtfThreadEntryPoint): Eliminated call to ThreadSpecificThreadExit.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfThreadSpecifich">trunk/Source/WTF/wtf/ThreadSpecific.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadSpecificWincpp">trunk/Source/WTF/wtf/ThreadSpecificWin.cpp</a></li>
<li><a href="#trunkSourceWTFwtfThreadingWincpp">trunk/Source/WTF/wtf/ThreadingWin.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (199620 => 199621)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-04-16 04:29:32 UTC (rev 199620)
+++ trunk/Source/WTF/ChangeLog        2016-04-16 04:52:18 UTC (rev 199621)
</span><span class="lines">@@ -1,3 +1,63 @@
</span><ins>+2016-04-15  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        iTunes crashing JavaScriptCore.dll
+        https://bugs.webkit.org/show_bug.cgi?id=156647
+
+        Reviewed by Geoffrey Garen.
+
+        If a thread was created without using the WTF thread apis and that thread uses
+        a JavaScript VM and that thread exits with the VM still around, JSC won't know
+        that the thread has exited.  Currently, we use ThreadSpecificThreadExit() to
+        clean up any thread specific keys.  Cleaning up these keys is how JSC is
+        notified of a thread exit.  We only call ThreadSpecificThreadExit() from
+        wtfThreadEntryPoint() when the thread entry point function returns.
+        This mechanism was put in place for Windos because we layer the WTF::ThreadSpecific
+        functionality on top of TLS (Thread Local Storage), but TLS doesn't have
+        a thread exiting callback the way that pthread_create_key.
+
+        The fix is to change from using TLS to using FLS (Fiber Local Storage).  Although
+        Windows allows multiple fibers per thread, WebKit is not designed to work with a
+        multiple fibers per thread.  When ther is only one fiber per thread, FLS works just
+        like TLS, but it has the destroy callback.
+
+        I restructured the Windows version of WTF::ThreadSpecific to be almost the same
+        as the pthread version.
+        
+        * wtf/ThreadSpecific.h:
+        (WTF::threadSpecificKeyCreate):
+        (WTF::threadSpecificKeyDelete):
+        (WTF::threadSpecificSet):
+        (WTF::threadSpecificGet):
+        (WTF::ThreadSpecific&lt;T&gt;::ThreadSpecific):
+        (WTF::ThreadSpecific&lt;T&gt;::~ThreadSpecific):
+        (WTF::ThreadSpecific&lt;T&gt;::get):
+        (WTF::ThreadSpecific&lt;T&gt;::set):
+        (WTF::ThreadSpecific&lt;T&gt;::destroy):
+        Restructured to use FLS.  Renamed TLS* to FLS*.
+
+        * wtf/ThreadSpecificWin.cpp:
+        (WTF::flsKeyCount):
+        (WTF::flsKeys):
+        Renamed from tlsKey*() to flsKey*().
+
+        (WTF::destructorsList): Deleted.
+        (WTF::destructorsMutex): Deleted.
+        (WTF::PlatformThreadSpecificKey::PlatformThreadSpecificKey): Deleted.
+        (WTF::PlatformThreadSpecificKey::~PlatformThreadSpecificKey): Deleted.
+        (WTF::PlatformThreadSpecificKey::setValue): Deleted.
+        (WTF::PlatformThreadSpecificKey::value): Deleted.
+        (WTF::PlatformThreadSpecificKey::callDestructor): Deleted.
+        (WTF::tlsKeyCount): Deleted.
+        (WTF::tlsKeys): Deleted.
+        (WTF::threadSpecificKeyCreate): Deleted.
+        (WTF::threadSpecificKeyDelete): Deleted.
+        (WTF::threadSpecificSet): Deleted.
+        (WTF::threadSpecificGet): Deleted.
+        (WTF::ThreadSpecificThreadExit): Deleted.
+
+        * wtf/ThreadingWin.cpp:
+        (WTF::wtfThreadEntryPoint): Eliminated call to ThreadSpecificThreadExit.
+
</ins><span class="cx"> 2016-04-12  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         PolymorphicAccess should buffer AccessCases before regenerating
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadSpecifich"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ThreadSpecific.h (199620 => 199621)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadSpecific.h        2016-04-16 04:29:32 UTC (rev 199620)
+++ trunk/Source/WTF/wtf/ThreadSpecific.h        2016-04-16 04:52:18 UTC (rev 199621)
</span><span class="lines">@@ -94,9 +94,6 @@
</span><span class="cx"> 
</span><span class="cx">         T* value;
</span><span class="cx">         ThreadSpecific&lt;T&gt;* owner;
</span><del>-#if OS(WINDOWS)
-        void (*destructor)(void*);
-#endif
</del><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx"> #if USE(PTHREADS)
</span><span class="lines">@@ -158,47 +155,64 @@
</span><span class="cx"> 
</span><span class="cx"> #elif OS(WINDOWS)
</span><span class="cx"> 
</span><del>-// The maximum number of TLS keys that can be created. For simplification, we assume that:
</del><ins>+// The maximum number of FLS keys that can be created. For simplification, we assume that:
</ins><span class="cx"> // 1) Once the instance of ThreadSpecific&lt;&gt; is created, it will not be destructed until the program dies.
</span><span class="cx"> // 2) We do not need to hold many instances of ThreadSpecific&lt;&gt; data. This fixed number should be far enough.
</span><del>-const int kMaxTlsKeySize = 256;
</del><ins>+const int kMaxFlsKeySize = 100;
</ins><span class="cx"> 
</span><del>-WTF_EXPORT_PRIVATE long&amp; tlsKeyCount();
-WTF_EXPORT_PRIVATE DWORD* tlsKeys();
</del><ins>+WTF_EXPORT_PRIVATE long&amp; flsKeyCount();
+WTF_EXPORT_PRIVATE DWORD* flsKeys();
</ins><span class="cx"> 
</span><del>-class PlatformThreadSpecificKey;
-typedef PlatformThreadSpecificKey* ThreadSpecificKey;
</del><ins>+typedef DWORD ThreadSpecificKey;
</ins><span class="cx"> 
</span><del>-WTF_EXPORT_PRIVATE void threadSpecificKeyCreate(ThreadSpecificKey*, void (*)(void *));
-WTF_EXPORT_PRIVATE void threadSpecificKeyDelete(ThreadSpecificKey);
-WTF_EXPORT_PRIVATE void threadSpecificSet(ThreadSpecificKey, void*);
-WTF_EXPORT_PRIVATE void* threadSpecificGet(ThreadSpecificKey);
</del><ins>+inline void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
+{
+    DWORD flsKey = FlsAlloc(reinterpret_cast&lt;PFLS_CALLBACK_FUNCTION&gt;(destructor));
+    if (flsKey == FLS_OUT_OF_INDEXES)
+        CRASH();
</ins><span class="cx"> 
</span><ins>+    *key = flsKey;
+}
+
+inline void threadSpecificKeyDelete(ThreadSpecificKey key)
+{
+    FlsFree(key);
+}
+
+inline void threadSpecificSet(ThreadSpecificKey key, void* data)
+{
+    FlsSetValue(key, data);
+}
+
+inline void* threadSpecificGet(ThreadSpecificKey key)
+{
+    return FlsGetValue(key);
+}
+
</ins><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> inline ThreadSpecific&lt;T&gt;::ThreadSpecific()
</span><span class="cx">     : m_index(-1)
</span><span class="cx"> {
</span><del>-    DWORD tlsKey = TlsAlloc();
-    if (tlsKey == TLS_OUT_OF_INDEXES)
</del><ins>+    DWORD flsKey = FlsAlloc(reinterpret_cast&lt;PFLS_CALLBACK_FUNCTION&gt;(destroy));
+    if (flsKey == FLS_OUT_OF_INDEXES)
</ins><span class="cx">         CRASH();
</span><span class="cx"> 
</span><del>-    m_index = InterlockedIncrement(&amp;tlsKeyCount()) - 1;
-    if (m_index &gt;= kMaxTlsKeySize)
</del><ins>+    m_index = InterlockedIncrement(&amp;flsKeyCount()) - 1;
+    if (m_index &gt;= kMaxFlsKeySize)
</ins><span class="cx">         CRASH();
</span><del>-    tlsKeys()[m_index] = tlsKey;
</del><ins>+    flsKeys()[m_index] = flsKey;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> inline ThreadSpecific&lt;T&gt;::~ThreadSpecific()
</span><span class="cx"> {
</span><del>-    // Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached.
-    TlsFree(tlsKeys()[m_index]);
</del><ins>+    FlsFree(flsKeys()[m_index]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> inline T* ThreadSpecific&lt;T&gt;::get()
</span><span class="cx"> {
</span><del>-    Data* data = static_cast&lt;Data*&gt;(TlsGetValue(tlsKeys()[m_index]));
</del><ins>+    Data* data = static_cast&lt;Data*&gt;(FlsGetValue(flsKeys()[m_index]));
</ins><span class="cx">     return data ? data-&gt;value : 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -207,8 +221,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!get());
</span><span class="cx">     Data* data = new Data(ptr, this);
</span><del>-    data-&gt;destructor = &amp;ThreadSpecific&lt;T&gt;::destroy;
-    TlsSetValue(tlsKeys()[m_index], data);
</del><ins>+    FlsSetValue(flsKeys()[m_index], data);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #else
</span><span class="lines">@@ -232,7 +245,7 @@
</span><span class="cx"> #if USE(PTHREADS)
</span><span class="cx">     pthread_setspecific(data-&gt;owner-&gt;m_key, 0);
</span><span class="cx"> #elif OS(WINDOWS)
</span><del>-    TlsSetValue(tlsKeys()[data-&gt;owner-&gt;m_index], 0);
</del><ins>+    FlsSetValue(flsKeys()[data-&gt;owner-&gt;m_index], 0);
</ins><span class="cx"> #else
</span><span class="cx"> #error ThreadSpecific is not implemented for this platform.
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadSpecificWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ThreadSpecificWin.cpp (199620 => 199621)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadSpecificWin.cpp        2016-04-16 04:29:32 UTC (rev 199620)
+++ trunk/Source/WTF/wtf/ThreadSpecificWin.cpp        2016-04-16 04:52:18 UTC (rev 199621)
</span><span class="lines">@@ -24,117 +24,22 @@
</span><span class="cx"> 
</span><span class="cx"> #if OS(WINDOWS)
</span><span class="cx"> 
</span><del>-#include &quot;StdLibExtras.h&quot;
-#include &quot;ThreadingPrimitives.h&quot;
-#include &lt;wtf/DoublyLinkedList.h&gt;
-
</del><span class="cx"> #if !USE(PTHREADS)
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-static DoublyLinkedList&lt;PlatformThreadSpecificKey&gt;&amp; destructorsList()
</del><ins>+long&amp; flsKeyCount()
</ins><span class="cx"> {
</span><del>-    static DoublyLinkedList&lt;PlatformThreadSpecificKey&gt; staticList;
-    return staticList;
-}
-
-static Mutex&amp; destructorsMutex()
-{
-    static Mutex staticMutex;
-    return staticMutex;
-}
-
-class PlatformThreadSpecificKey : public DoublyLinkedListNode&lt;PlatformThreadSpecificKey&gt; {
-public:
-    friend class DoublyLinkedListNode&lt;PlatformThreadSpecificKey&gt;;
-
-    PlatformThreadSpecificKey(void (*destructor)(void *))
-        : m_destructor(destructor)
-    {
-        m_tlsKey = TlsAlloc();
-        if (m_tlsKey == TLS_OUT_OF_INDEXES)
-            CRASH();
-    }
-
-    ~PlatformThreadSpecificKey()
-    {
-        TlsFree(m_tlsKey);
-    }
-
-    void setValue(void* data) { TlsSetValue(m_tlsKey, data); }
-    void* value() { return TlsGetValue(m_tlsKey); }
-
-    void callDestructor()
-    {
-       if (void* data = value())
-            m_destructor(data);
-    }
-
-private:
-    void (*m_destructor)(void *);
-    DWORD m_tlsKey;
-    PlatformThreadSpecificKey* m_prev;
-    PlatformThreadSpecificKey* m_next;
-};
-
-long&amp; tlsKeyCount()
-{
</del><span class="cx">     static long count;
</span><span class="cx">     return count;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-DWORD* tlsKeys()
</del><ins>+DWORD* flsKeys()
</ins><span class="cx"> {
</span><del>-    static DWORD keys[kMaxTlsKeySize];
</del><ins>+    static DWORD keys[kMaxFlsKeySize];
</ins><span class="cx">     return keys;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
-{
-    // Use the original malloc() instead of fastMalloc() to use this function in FastMalloc code.
-    *key = static_cast&lt;PlatformThreadSpecificKey*&gt;(::malloc(sizeof(PlatformThreadSpecificKey)));
-    new (*key) PlatformThreadSpecificKey(destructor);
-
-    MutexLocker locker(destructorsMutex());
-    destructorsList().push(*key);
-}
-
-void threadSpecificKeyDelete(ThreadSpecificKey key)
-{
-    MutexLocker locker(destructorsMutex());
-    destructorsList().remove(key);
-    key-&gt;~PlatformThreadSpecificKey();
-    ::free(key);
-}
-
-void threadSpecificSet(ThreadSpecificKey key, void* data)
-{
-    key-&gt;setValue(data);
-}
-
-void* threadSpecificGet(ThreadSpecificKey key)
-{
-    return key-&gt;value();
-}
-
-void ThreadSpecificThreadExit()
-{
-    for (long i = 0; i &lt; tlsKeyCount(); i++) {
-        // The layout of ThreadSpecific&lt;T&gt;::Data does not depend on T. So we are safe to do the static cast to ThreadSpecific&lt;int&gt; in order to access its data member.
-        ThreadSpecific&lt;int&gt;::Data* data = static_cast&lt;ThreadSpecific&lt;int&gt;::Data*&gt;(TlsGetValue(tlsKeys()[i]));
-        if (data)
-            data-&gt;destructor(data);
-    }
-
-    MutexLocker locker(destructorsMutex());
-    PlatformThreadSpecificKey* key = destructorsList().head();
-    while (key) {
-        PlatformThreadSpecificKey* nextKey = key-&gt;next();
-        key-&gt;callDestructor();
-        key = nextKey;
-    }
-}
-
</del><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> #endif // !USE(PTHREADS)
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadingWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ThreadingWin.cpp (199620 => 199621)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadingWin.cpp        2016-04-16 04:29:32 UTC (rev 199620)
+++ trunk/Source/WTF/wtf/ThreadingWin.cpp        2016-04-16 04:52:18 UTC (rev 199621)
</span><span class="lines">@@ -102,10 +102,6 @@
</span><span class="cx"> #include &lt;wtf/RandomNumberSeed.h&gt;
</span><span class="cx"> #include &lt;wtf/WTFThreadData.h&gt;
</span><span class="cx"> 
</span><del>-#if !USE(PTHREADS) &amp;&amp; OS(WINDOWS)
-#include &quot;ThreadSpecific.h&quot;
-#endif
-
</del><span class="cx"> #if HAVE(ERRNO_H)
</span><span class="cx"> #include &lt;errno.h&gt;
</span><span class="cx"> #endif
</span><span class="lines">@@ -199,11 +195,6 @@
</span><span class="cx">     std::unique_ptr&lt;ThreadFunctionInvocation&gt; invocation(static_cast&lt;ThreadFunctionInvocation*&gt;(param));
</span><span class="cx">     invocation-&gt;function(invocation-&gt;data);
</span><span class="cx"> 
</span><del>-#if !USE(PTHREADS) &amp;&amp; OS(WINDOWS)
-    // Do the TLS cleanup.
-    ThreadSpecificThreadExit();
-#endif
-
</del><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>