Ignore:
Timestamp:
Jan 22, 2010, 2:00:37 PM (15 years ago)
Author:
[email protected]
Message:

Fix the leak of ThreadIdentifiers in threadMap across threads.
https://bugs.webkit.org/show_bug.cgi?id=32689

Reviewed by Maciej Stachowiak.

JavaScriptCore:

Test is added to DumpRenderTree.mm.

  • Android.mk: Added file ThreadIdentifierDataPthreads.(h|cpp) to build.
  • Android.v8.wtf.mk: Ditto.
  • GNUmakefile.am: Ditto.
  • JavaScriptCore.gyp/JavaScriptCore.gyp: Ditto.
  • JavaScriptCore.gypi: Ditto.
  • JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
  • wtf/ThreadIdentifierDataPthreads.cpp: Added. Contains custom implementation of thread-specific data that uses custom destructor.

(WTF::ThreadIdentifierData::~ThreadIdentifierData): Removes the ThreadIdentifier from the threadMap.
(WTF::ThreadIdentifierData::identifier):
(WTF::ThreadIdentifierData::initialize):
(WTF::ThreadIdentifierData::destruct): Custom thread-specific destructor. Resets the value for the key again to cause second invoke.
(WTF::ThreadIdentifierData::initializeKeyOnceHelper):
(WTF::ThreadIdentifierData::initializeKeyOnce): Need to use pthread_once since initialization may come on any thread(s).

  • wtf/ThreadIdentifierDataPthreads.h: Added.

(WTF::ThreadIdentifierData::ThreadIdentifierData):

  • wtf/Threading.cpp:

(WTF::threadEntryPoint): Move initializeCurrentThreadInternal to after the lock to make

sure it is invoked when ThreadIdentifier is already established.

  • wtf/Threading.h: Rename setThreadNameInternal -> initializeCurrentThreadInternal since it does more then only set the name now.
  • wtf/ThreadingNone.cpp:

(WTF::initializeCurrentThreadInternal): Ditto.

  • wtf/ThreadingWin.cpp:

(WTF::initializeCurrentThreadInternal): Ditto.
(WTF::initializeThreading): Ditto.

  • wtf/gtk/ThreadingGtk.cpp:

(WTF::initializeCurrentThreadInternal): Ditto.

  • wtf/qt/ThreadingQt.cpp:

(WTF::initializeCurrentThreadInternal): Ditto.

  • wtf/ThreadingPthreads.cpp:

(WTF::establishIdentifierForPthreadHandle):
(WTF::clearPthreadHandleForIdentifier): Make it not 'static' so the ~ThreadIdentifierData() in another file can call it.
(WTF::initializeCurrentThreadInternal): Set the thread-specific data. The ThreadIdentifier is already established by creating thread.
(WTF::waitForThreadCompletion): Remove call to clearPthreadHandleForIdentifier(threadID) since it is now done in ~ThreadIdentifierData().
(WTF::detachThread): Ditto.
(WTF::currentThread): Use the thread-specific data to get the ThreadIdentifier. It's many times faster then Mutex-protected iteration through the map.

Also, set the thread-specific data if called first time on the thread.

WebKitTools:

Add a new test to verify the ThreadIdentifiers are not reused across threads.
The test runs in the beginning of DumpRenderTree and spawns 2 non-WTF treads sequentially,
waiting for the previous thread to terminate before starting the next.
The treads use WTF::currentThread() in their thread function. Without a fix, this
causes both threads to have the same ThreadIdentifier which triggers ASSERT in thread function.
It also starts another thread using WTF. Without the fix, this finds pthread handle from previous
threads in the WTF threadMap and asserts in WTF::establishIdentifierForPthreadHandle().
The test practically does not affect the DRT run time because the threads end immediately.

  • DumpRenderTree/mac/DumpRenderTree.mm:

(runThread): Test thread function.
(testThreadIdentifierMap):
(dumpRenderTree):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/ThreadingPthreads.cpp

    r52791 r53714  
    3838#include "RandomNumberSeed.h"
    3939#include "StdLibExtras.h"
     40#include "ThreadIdentifierDataPthreads.h"
     41#include "ThreadSpecific.h"
    4042#include "UnusedParam.h"
    4143#include <errno.h>
     
    109111}
    110112
    111 static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle)
     113static ThreadIdentifier establishIdentifierForPthreadHandle(const pthread_t& pthreadHandle)
    112114{
    113115    ASSERT(!identifierByPthreadHandle(pthreadHandle));
     
    129131}
    130132
    131 static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
     133void clearPthreadHandleForIdentifier(ThreadIdentifier id)
    132134{
    133135    MutexLocker locker(threadMapMutex());
     
    186188#endif
    187189
    188 void setThreadNameInternal(const char* threadName)
     190void initializeCurrentThreadInternal(const char* threadName)
    189191{
    190192#if HAVE(PTHREAD_SETNAME_NP)
     
    193195    UNUSED_PARAM(threadName);
    194196#endif
     197
     198    ThreadIdentifier id = identifierByPthreadHandle(pthread_self());
     199    ASSERT(id);
     200    ThreadIdentifierData::initialize(id);
    195201}
    196202
     
    205211        LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
    206212
    207     clearPthreadHandleForIdentifier(threadID);
    208213    return joinResult;
    209214}
     
    216221
    217222    pthread_detach(pthreadHandle);
    218 
    219     clearPthreadHandleForIdentifier(threadID);
    220223}
    221224
    222225ThreadIdentifier currentThread()
    223226{
    224     pthread_t currentThread = pthread_self();
    225     if (ThreadIdentifier id = identifierByPthreadHandle(currentThread))
     227    ThreadIdentifier id = ThreadIdentifierData::identifier();
     228    if (id)
    226229        return id;
    227     return establishIdentifierForPthreadHandle(currentThread);
     230
     231    // Not a WTF-created thread, ThreadIdentifier is not established yet.
     232    id = establishIdentifierForPthreadHandle(pthread_self());
     233    ThreadIdentifierData::initialize(id);
     234    return id;
    228235}
    229236
Note: See TracChangeset for help on using the changeset viewer.