void ThreadGlobalData::setWebCoreThreadData()
{
    ASSERT(isWebThread());
    ASSERT(&threadGlobalData() != ThreadGlobalData::sharedMainThreadStaticData);

    // Set WebThread's ThreadGlobalData object to be the same as the main UI thread.
    ThreadGlobalData::staticData->replace(ThreadGlobalData::sharedMainThreadStaticData);

    ASSERT(&threadGlobalData() == ThreadGlobalData::sharedMainThreadStaticData);
}
Пример #2
0
 RunLoopSetup(WorkerRunLoop& runLoop)
     : m_runLoop(runLoop)
 {
     if (!m_runLoop.m_nestedCount)
         threadGlobalData().threadTimers().setSharedTimer(m_runLoop.m_sharedTimer.get());
     m_runLoop.m_nestedCount++;
 }
Пример #3
0
 ~RunLoopSetup()
 {
     m_runLoop.m_nestedCount--;
     if (!m_runLoop.m_nestedCount)
         threadGlobalData().threadTimers().setSharedTimer(0);
     InspectorInstrumentation::didLeaveNestedRunLoop(m_context);
 }
Пример #4
0
void TimerBase::setNextFireTime(double newTime)
{
    ASSERT(m_thread == currentThread());

    // Keep heap valid while changing the next-fire time.
    double oldTime = m_nextFireTime;
    if (oldTime != newTime) {
        m_nextFireTime = newTime;
        static unsigned currentHeapInsertionOrder;
        m_heapInsertionOrder = currentHeapInsertionOrder++;

        bool wasFirstTimerInHeap = m_heapIndex == 0;

        if (oldTime == 0)
            heapInsert();
        else if (newTime == 0)
            heapDelete();
        else if (newTime < oldTime)
            heapDecreaseKey();
        else
            heapIncreaseKey();

        bool isFirstTimerInHeap = m_heapIndex == 0;

        if (wasFirstTimerInHeap || isFirstTimerInHeap)
            threadGlobalData().threadTimers().updateSharedTimer();
    }

    checkConsistency();
}
Пример #5
0
 RunLoopSetup(WorkerRunLoop& runLoop, WorkerGlobalScope* context)
     : m_runLoop(runLoop)
     , m_context(context)
 {
     if (!m_runLoop.m_nestedCount)
         threadGlobalData().threadTimers().setSharedTimer(m_runLoop.m_sharedTimer.get());
     m_runLoop.m_nestedCount++;
     InspectorInstrumentation::willEnterNestedRunLoop(m_context);
 }
Пример #6
0
void ThreadTimers::sharedTimerFired()
{
    TRACE_EVENT_SAMPLING_STATE0("WebKit\0WebKitInternal");

    // Redirect to non-static method.
    threadGlobalData().threadTimers().sharedTimerFiredInternal();

    TRACE_EVENT_SAMPLING_STATE0("WebKit\0WebKitSleeping");
}
Пример #7
0
void WorkerThread::workerThread()
{
    // Propagate the mainThread's fenv to workers.
#if PLATFORM(IOS)
    FloatingPointEnvironment::singleton().propagateMainThreadEnvironment();
#endif

#if PLATFORM(GTK)
    GRefPtr<GMainContext> mainContext = adoptGRef(g_main_context_new());
    g_main_context_push_thread_default(mainContext.get());
#endif

    {
        LockHolder lock(m_threadCreationMutex);
        m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, m_startupData->m_contentSecurityPolicyResponseHeaders, m_startupData->m_shouldBypassMainWorldContentSecurityPolicy, WTFMove(m_startupData->m_topOrigin));

        if (m_runLoop.terminated()) {
            // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
            // forbidExecution() couldn't be called from stop().
            m_workerGlobalScope->script()->forbidExecution();
        }
    }

    WorkerScriptController* script = m_workerGlobalScope->script();
    script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
    // all ref/derefs of these objects are happening on the thread at this point). Note that
    // WorkerThread::~WorkerThread happens on a different thread where it was created.
    m_startupData = nullptr;

    runEventLoop();

#if PLATFORM(GTK)
    g_main_context_pop_thread_default(mainContext.get());
#endif

    ThreadIdentifier threadID = m_threadID;

    ASSERT(m_workerGlobalScope->hasOneRef());

    // The below assignment will destroy the context, which will in turn notify messaging proxy.
    // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
    m_workerGlobalScope = nullptr;

    // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away!
    threadGlobalData().destroy();

    // The thread object may be already destroyed from notification now, don't try to access "this".
    detachThread(threadID);
}
Пример #8
0
// A worker thread may initialize SharedTimer after some timers are created.
// Also, SharedTimer can be replaced with nullptr before all timers are destroyed.
void ThreadTimers::setSharedTimer(SharedTimer* sharedTimer)
{
    if (m_sharedTimer) {
        m_sharedTimer->setFiredFunction(nullptr);
        m_sharedTimer->stop();
        m_pendingSharedTimerFireTime = 0;
    }
    
    m_sharedTimer = sharedTimer;
    
    if (sharedTimer) {
        m_sharedTimer->setFiredFunction([] { threadGlobalData().threadTimers().sharedTimerFiredInternal(); });
        updateSharedTimer();
    }
}
Пример #9
0
void WorkerThread::workerThread()
{
    // Propagate the mainThread's fenv to workers.
#if PLATFORM(IOS)
    fesetenv(&mainThreadFEnv);
#endif

    {
        MutexLocker lock(m_threadCreationMutex);
        m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, std::move(m_startupData->m_groupSettings), m_startupData->m_contentSecurityPolicy, m_startupData->m_contentSecurityPolicyType, m_startupData->m_topOrigin.release());

        if (m_runLoop.terminated()) {
            // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
            // forbidExecution() couldn't be called from stop().
            m_workerGlobalScope->script()->forbidExecution();
        }
    }

    WorkerScriptController* script = m_workerGlobalScope->script();
#if ENABLE(INSPECTOR)
    InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), m_startupData->m_startMode);
#endif
    script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
    // all ref/derefs of these objects are happening on the thread at this point). Note that
    // WorkerThread::~WorkerThread happens on a different thread where it was created.
    m_startupData.clear();

    runEventLoop();

    ThreadIdentifier threadID = m_threadID;

    ASSERT(m_workerGlobalScope->hasOneRef());

    // The below assignment will destroy the context, which will in turn notify messaging proxy.
    // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
    m_workerGlobalScope = 0;

    // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away!
    threadGlobalData().destroy();

    // The thread object may be already destroyed from notification now, don't try to access "this".
    detachThread(threadID);
}
Пример #10
0
void* WorkerThread::workerThread()
{
    {
        MutexLocker lock(m_threadCreationMutex);

#if OS(OLYMPIA)
        m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_startupData->m_groupName, m_startupData->m_userAgent);
        Olympia::Platform::didStartWorker();
#else
        m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_startupData->m_userAgent);
#endif

        if (m_runLoop.terminated()) {
            // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
            // forbidExecution() couldn't be called from stop().
           m_workerContext->script()->forbidExecution(WorkerScriptController::TerminateRunningScript);
        }
    }

    WorkerScriptController* script = m_workerContext->script();
    script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
    // all ref/derefs of these objects are happening on the thread at this point). Note that
    // WorkerThread::~WorkerThread happens on a different thread where it was created.
    m_startupData.clear();

    runEventLoop();

    ThreadIdentifier threadID = m_threadID;

    ASSERT(m_workerContext->hasOneRef());

    // The below assignment will destroy the context, which will in turn notify messaging proxy.
    // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
    m_workerContext = 0;

    // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away!
    threadGlobalData().destroy();

    // The thread object may be already destroyed from notification now, don't try to access "this".
    detachThread(threadID);

    return 0;
}
Пример #11
0
void TimerBase::setNextFireTime(double newTime)
{
    ASSERT(canAccessThreadLocalDataForThread(m_thread));
    ASSERT(!m_wasDeleted);

    if (m_unalignedNextFireTime != newTime)
        m_unalignedNextFireTime = newTime;

    // Accessing thread global data is slow. Cache the heap pointer.
    if (!m_cachedThreadGlobalTimerHeap)
        m_cachedThreadGlobalTimerHeap = &threadGlobalTimerHeap();

    // Keep heap valid while changing the next-fire time.
    double oldTime = m_nextFireTime;
    // Don't realign zero-delay timers.
    if (newTime) {
        if (auto newAlignedTime = alignedFireTime(secondsToMS(newTime)))
            newTime = msToSeconds(newAlignedTime.value());
    }

    if (oldTime != newTime) {
        m_nextFireTime = newTime;
        // FIXME: This should be part of ThreadTimers, or another per-thread structure.
        static std::atomic<unsigned> currentHeapInsertionOrder;
        m_heapInsertionOrder = currentHeapInsertionOrder++;

        bool wasFirstTimerInHeap = m_heapIndex == 0;

        updateHeapIfNeeded(oldTime);

        bool isFirstTimerInHeap = m_heapIndex == 0;

        if (wasFirstTimerInHeap || isFirstTimerInHeap)
            threadGlobalData().threadTimers().updateSharedTimer();
    }

    checkConsistency();
}
Пример #12
0
static TECConverterWrapper& cachedConverterTEC()
{
    return threadGlobalData().cachedConverterTEC();
}
void ThreadTimers::sharedTimerFired()
{
    // Redirect to non-static method.
    threadGlobalData().threadTimers().sharedTimerFiredInternal();
}
Пример #14
0
 ~RunLoopSetup()
 {
     m_runLoop.m_nestedCount--;
     if (!m_runLoop.m_nestedCount)
         threadGlobalData().threadTimers().setSharedTimer(0);
 }
bool DOMImplementation::isXMLMIMEType(const String& mimeType)
{
    if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
        return true;
    return threadGlobalData().xmlTypeRegExp().isXMLMIMEType(mimeType);
}
Пример #16
0
StringImpl* StringImpl::empty()
{
    return threadGlobalData().emptyString();
}
Пример #17
0
ThreadLocalInspectorCounters& ThreadLocalInspectorCounters::current()
{
    return threadGlobalData().inspectorCounters();
}
Пример #18
0
void TimerBase::fireTimersInNestedEventLoop()
{
    // Redirect to ThreadTimers.
    threadGlobalData().threadTimers().fireTimersInNestedEventLoop();
}
Пример #19
0
// Simple accessors to thread-specific data.
static Vector<TimerBase*>& timerHeap()
{
    return threadGlobalData().threadTimers().timerHeap();
}