Commit fcebb0df authored by Nate Chapin's avatar Nate Chapin Committed by Commit Bot

Add a generic way to run a task on all WorkerThreads

This allows us to hide the HashSet of all current WorkerThreads, which
is valuable since the callers outside WorkerThread don't have access to
the necessary mutex to access it safely.

Convert TimeZoneMonitorClient to use this helper.

Change-Id: I5aa743a1fa0c789a8f9496a05d7cfecde9238004
Reviewed-on: https://chromium-review.googlesource.com/1228950Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Commit-Queue: Nate Chapin <japhet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592116}
parent 29028a2d
......@@ -72,7 +72,7 @@ constexpr TimeDelta kForcibleTerminationDelay = TimeDelta::FromSeconds(2);
} // namespace
static Mutex& ThreadSetMutex() {
Mutex& WorkerThread::ThreadSetMutex() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, ());
return mutex;
}
......
......@@ -136,6 +136,7 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
// workers are shut down. Please be careful when using this function, because
// after the synchronous termination any V8 APIs may suddenly start to return
// empty handles and it may cause crashes.
// WARNING: This is not safe if a nested worker is running.
static void TerminateAllWorkersForTesting();
// WebThread::TaskObserver.
......@@ -182,9 +183,19 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
// Number of active worker threads.
static unsigned WorkerThreadCount();
// Returns a set of all worker threads. This must be called only on the main
// thread and the returned set must not be stored for future use.
static HashSet<WorkerThread*>& WorkerThreads();
// Runs |function| with |parameters| on each worker thread, and
// adds the current WorkerThread* as the first parameter |function|.
template <typename FunctionType, typename... Parameters>
static void CallOnAllWorkerThreads(FunctionType function,
Parameters&&... parameters) {
MutexLocker lock(ThreadSetMutex());
for (WorkerThread* thread : WorkerThreads()) {
PostCrossThreadTask(
*thread->GetTaskRunner(TaskType::kInternalWorker), FROM_HERE,
CrossThreadBind(function, WTF::CrossThreadUnretained(thread),
parameters...));
}
}
int GetWorkerThreadId() const { return worker_thread_id_; }
......@@ -240,6 +251,9 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
FRIEND_TEST_ALL_PREFIXES(WorkerThreadTest,
Terminate_WhileDebuggerTaskIsRunning);
static HashSet<WorkerThread*>& WorkerThreads();
static Mutex& ThreadSetMutex();
// Represents the state of this worker thread.
enum class ThreadState {
kNotStarted,
......
......@@ -65,21 +65,7 @@ void TimeZoneMonitorClient::OnTimeZoneChange(const String& time_zone_info) {
}
NotifyTimezoneChangeToV8(V8PerIsolateData::MainThreadIsolate());
HashSet<WorkerThread*>& threads = WorkerThread::WorkerThreads();
HashSet<WorkerBackingThread*> posted;
for (WorkerThread* thread : threads) {
// Ensure every WorkerBackingThread(holding one platform thread) only get
// the task posted once, because one WorkerBackingThread could be shared
// among multiple WorkerThreads.
if (posted.Contains(&thread->GetWorkerBackingThread()))
continue;
PostCrossThreadTask(*thread->GetTaskRunner(TaskType::kInternalDefault),
FROM_HERE,
CrossThreadBind(&NotifyTimezoneChangeOnWorkerThread,
WTF::CrossThreadUnretained(thread)));
posted.insert(&thread->GetWorkerBackingThread());
}
WorkerThread::CallOnAllWorkerThreads(&NotifyTimezoneChangeOnWorkerThread);
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment