Index: Source/core/workers/WorkerThread.cpp |
diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp |
index 76e11fb84e4fc2afaac33648e86ff83c665d1f4d..aedc759312180e563d7d151727a862ce804c8c8f 100644 |
--- a/Source/core/workers/WorkerThread.cpp |
+++ b/Source/core/workers/WorkerThread.cpp |
@@ -38,13 +38,12 @@ |
#include "core/workers/WorkerClients.h" |
#include "core/workers/WorkerReportingProxy.h" |
#include "core/workers/WorkerThreadStartupData.h" |
-#include "platform/PlatformThreadData.h" |
#include "platform/Task.h" |
-#include "platform/ThreadTimers.h" |
#include "platform/heap/SafePoint.h" |
#include "platform/heap/ThreadState.h" |
#include "platform/weborigin/KURL.h" |
#include "public/platform/Platform.h" |
+#include "public/platform/WebScheduler.h" |
#include "public/platform/WebThread.h" |
#include "public/platform/WebWaitableEvent.h" |
#include "wtf/Noncopyable.h" |
@@ -54,8 +53,6 @@ |
namespace blink { |
namespace { |
-const int64_t kShortIdleHandlerDelayMs = 1000; |
-const int64_t kLongIdleHandlerDelayMs = 10*1000; |
class MicrotaskRunner : public WebThread::TaskObserver { |
public: |
@@ -131,69 +128,6 @@ private: |
bool m_taskCanceled; |
}; |
-class WorkerSharedTimer : public SharedTimer { |
-public: |
- explicit WorkerSharedTimer(WorkerThread* workerThread) |
- : m_workerThread(workerThread) |
- , m_running(false) |
- { } |
- |
- typedef void (*SharedTimerFunction)(); |
- virtual void setFiredFunction(SharedTimerFunction func) |
- { |
- m_sharedTimerFunction = func; |
- } |
- |
- virtual void setFireInterval(double interval) |
- { |
- ASSERT(m_sharedTimerFunction); |
- |
- // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of |
- // why ceil is used in the interval calculation. |
- int64_t delay = static_cast<int64_t>(ceil(interval * 1000)); |
- |
- if (delay < 0) { |
- delay = 0; |
- } |
- |
- m_running = true; |
- |
- if (m_lastQueuedTask.get()) |
- m_lastQueuedTask->cancelTask(); |
- |
- // Now queue the task as a cancellable one. |
- OwnPtr<WorkerThreadCancelableTask> task = WorkerThreadCancelableTask::create(bind(&WorkerSharedTimer::OnTimeout, this)); |
- m_lastQueuedTask = task->createWeakPtr(); |
- m_workerThread->postDelayedTask(FROM_HERE, task.release(), delay); |
- } |
- |
- virtual void stop() |
- { |
- m_running = false; |
- m_lastQueuedTask = nullptr; |
- } |
- |
-private: |
- void OnTimeout() |
- { |
- ASSERT(m_workerThread->workerGlobalScope()); |
- |
- m_lastQueuedTask = nullptr; |
- |
- if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalScope()->isClosing()) |
- m_sharedTimerFunction(); |
- } |
- |
- WorkerThread* m_workerThread; |
- SharedTimerFunction m_sharedTimerFunction; |
- bool m_running; |
- |
- // The task to run OnTimeout, if any. While OnTimeout resets |
- // m_lastQueuedTask, this must be a weak pointer because the |
- // worker runloop may delete the task as it is shutting down. |
- WeakPtr<WorkerThreadCancelableTask> m_lastQueuedTask; |
-}; |
- |
class WorkerThreadTask : public blink::WebThread::Task { |
WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThreadTask); |
public: |
@@ -264,6 +198,7 @@ WorkerThread::WorkerThread(const char* threadName, PassRefPtr<WorkerLoaderProxy> |
, m_isolate(nullptr) |
, m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent())) |
, m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEvent())) |
+ , m_webScheduler(nullptr) |
{ |
MutexLocker lock(threadSetMutex()); |
workerThreads().add(this); |
@@ -299,6 +234,22 @@ PlatformThreadId WorkerThread::platformThreadId() const |
return m_thread->platformThread().threadId(); |
} |
+class WorkerThreadIdleTask : public WebThread::IdleTask { |
+public: |
+ explicit WorkerThreadIdleTask(WorkerThread* thread) |
+ : m_thread(thread) { } |
+ |
+ ~WorkerThreadIdleTask() override { } |
+ |
+ void run(double deadlineSeconds) override |
+ { |
+ m_thread->idleTask(deadlineSeconds); |
+ } |
+ |
+private: |
+ RawPtr<WorkerThread> m_thread; |
+}; |
+ |
void WorkerThread::initialize() |
{ |
KURL scriptURL = m_startupData->m_scriptURL; |
@@ -325,8 +276,6 @@ void WorkerThread::initialize() |
m_isolate = initializeIsolate(); |
m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.get() ? cachedMetaData->size() : 0); |
- |
- PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); |
} |
// The corresponding call to stopRunLoop() is in ~WorkerScriptController(). |
@@ -348,7 +297,8 @@ void WorkerThread::initialize() |
postInitialize(); |
- postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs); |
+ m_webScheduler = m_thread->platformThread().scheduler(); |
+ m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask(this)); |
rmcilroy
2015/04/17 12:59:33
Can we just use WTF::Bind here to avoid having to
alex clarke (OOO till 29th)
2015/04/17 13:37:08
I wish I could but the type ereasure of WTF::bind
rmcilroy
2015/04/17 16:33:22
Ahh sad. In that case this is fine.
|
} |
PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC() |
@@ -381,9 +331,6 @@ void WorkerThread::cleanup() |
workerReportingProxy().workerThreadTerminated(); |
m_terminationEvent->signal(); |
- |
- // Clean up PlatformThreadData before WTF::WTFThreadData goes away! |
- PlatformThreadData::current().destroy(); |
} |
class WorkerThreadShutdownFinishTask : public ExecutionContextTask { |
@@ -417,7 +364,6 @@ public: |
{ |
WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
workerGlobalScope->stopActiveDOMObjects(); |
- PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
// Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects, |
// which become dangling once Heap is destroyed. |
@@ -509,21 +455,28 @@ bool WorkerThread::isCurrentThread() const |
return m_thread && m_thread->isCurrentThread(); |
} |
-void WorkerThread::idleHandler() |
+void WorkerThread::idleTask(double deadlineSeconds) |
{ |
- ASSERT(m_workerGlobalScope.get()); |
- int64_t delay = kLongIdleHandlerDelayMs; |
+ double gcDeadlineSeconds = deadlineSeconds; |
+ |
+ // The V8 GC does some GC steps (e.g. compaction) only when the idle notification is ~1s. |
+ // TODO(rmcilroy): Refactor so extending the deadline like this this isn't needed. |
+ if (m_webScheduler->canExceedIdleDeadlineIfRequired()) |
+ gcDeadlineSeconds = Platform::current()->monotonicallyIncreasingTime() + 1.0; |
rmcilroy
2015/04/17 12:59:33
add back the kLongIdleHandlerDelay as a constant a
alex clarke (OOO till 29th)
2015/04/17 13:37:08
Done.
|
- // Do a script engine idle notification if the next event is distant enough. |
- const double kMinIdleTimespan = 0.3; |
- const double nextFireTime = PlatformThreadData::current().threadTimers().nextFireTime(); |
- if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) { |
- bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::current()->monotonicallyIncreasingTime() + 1.0); |
- if (hasMoreWork) |
- delay = kShortIdleHandlerDelayMs; |
+ if (doIdleGc(gcDeadlineSeconds)) |
rmcilroy
2015/04/17 12:59:33
nit - I would prefer this function is inlined - i.
alex clarke (OOO till 29th)
2015/04/17 13:37:08
I split the doIdleGc function off so I could test
rmcilroy
2015/04/17 16:33:22
I missed you were using this in testing. In that c
alex clarke (OOO till 29th)
2015/04/20 10:06:53
OK although I may get asked to change it back sinc
rmcilroy
2015/04/20 20:56:49
Thanks!
|
+ m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask(this)); |
+ else |
+ m_webScheduler->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this)); |
+} |
+ |
+bool WorkerThread::doIdleGc(double deadlineSeconds) |
+{ |
+ if (deadlineSeconds > Platform::current()->monotonicallyIncreasingTime()) { |
+ return isolate()->IdleNotificationDeadline(deadlineSeconds); |
} |
- postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay); |
+ return false; |
} |
void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task) |