Skip to content

Commit

Permalink
Merge r184072 - [GTK] WorkQueue objects are not released
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=144824

Reviewed by Žan Doberšek.

Do not keep a reference of the WorkQueue for the entire life of
its worker thread, since every task scheduled on the WorkQueue
already takes a reference. Instead, take a reference of the main
loop to make sure that when the worker thread starts, the main
loop hasn't been released to avoid runtime warnings (see
webkit.org/b/140998). Also removed the g_main_context_pop_thread_default()
from the thread body, since the thread-specific context queue will
be freed anyway when the thread exits.
If the WorkQueue is released early, before the thread has started,
schedule a main loop quit in the context, to make sure it will
be the first thing run by the main loop and the thread will exit.

* wtf/WorkQueue.h: Remove unused event loop mutex.
* wtf/gtk/WorkQueueGtk.cpp:
(WTF::WorkQueue::platformInitialize):
(WTF::WorkQueue::platformInvalidate):
  • Loading branch information
carlosgcampos committed May 12, 2015
1 parent 0a49cdf commit e01b97f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 9 deletions.
24 changes: 24 additions & 0 deletions Source/WTF/ChangeLog
@@ -1,3 +1,27 @@
2015-05-11 Carlos Garcia Campos <cgarcia@igalia.com>

[GTK] WorkQueue objects are not released
https://bugs.webkit.org/show_bug.cgi?id=144824

Reviewed by Žan Doberšek.

Do not keep a reference of the WorkQueue for the entire life of
its worker thread, since every task scheduled on the WorkQueue
already takes a reference. Instead, take a reference of the main
loop to make sure that when the worker thread starts, the main
loop hasn't been released to avoid runtime warnings (see
webkit.org/b/140998). Also removed the g_main_context_pop_thread_default()
from the thread body, since the thread-specific context queue will
be freed anyway when the thread exits.
If the WorkQueue is released early, before the thread has started,
schedule a main loop quit in the context, to make sure it will
be the first thing run by the main loop and the thread will exit.

* wtf/WorkQueue.h: Remove unused event loop mutex.
* wtf/gtk/WorkQueueGtk.cpp:
(WTF::WorkQueue::platformInitialize):
(WTF::WorkQueue::platformInvalidate):

2015-05-07 Žan Doberšek <zdobersek@igalia.com>

[GTK] Clean up RunLoop implementation
Expand Down
1 change: 0 additions & 1 deletion Source/WebKit2/Platform/WorkQueue.h
Expand Up @@ -94,7 +94,6 @@ class WorkQueue final : public FunctionDispatcher {
#elif PLATFORM(GTK)
ThreadIdentifier m_workQueueThread;
GRefPtr<GMainContext> m_eventContext;
Mutex m_eventLoopLock;
GRefPtr<GMainLoop> m_eventLoop;
GMainLoopSource m_socketEventSource;
#elif PLATFORM(EFL)
Expand Down
20 changes: 12 additions & 8 deletions Source/WebKit2/Platform/gtk/WorkQueueGtk.cpp
Expand Up @@ -52,11 +52,10 @@ void WorkQueue::platformInitialize(const char* name, Type, QOS)
if (strlen(threadName) > kVisualStudioThreadNameLimit)
threadName += strlen(threadName) - kVisualStudioThreadNameLimit;

RefPtr<WorkQueue> protector(this);
m_workQueueThread = createThread(threadName, [protector] {
g_main_context_push_thread_default(protector->m_eventContext.get());
g_main_loop_run(protector->m_eventLoop.get());
g_main_context_pop_thread_default(protector->m_eventContext.get());
GRefPtr<GMainLoop> eventLoop(m_eventLoop.get());
m_workQueueThread = createThread(threadName, [eventLoop] {
g_main_context_push_thread_default(g_main_loop_get_context(eventLoop.get()));
g_main_loop_run(eventLoop.get());
});
}

Expand All @@ -67,14 +66,19 @@ void WorkQueue::platformInvalidate()
m_workQueueThread = 0;
}

MutexLocker locker(m_eventLoopLock);
if (m_eventLoop) {
if (g_main_loop_is_running(m_eventLoop.get()))
g_main_loop_quit(m_eventLoop.get());
m_eventLoop.clear();
else {
// The thread hasn't started yet, so schedule a main loop quit to ensure the thread finishes.
GMainLoop* eventLoop = m_eventLoop.get();
GMainLoopSource::scheduleAndDeleteOnDestroy("[WebKit] WorkQueue quit main loop", [eventLoop] { g_main_loop_quit(eventLoop); },
G_PRIORITY_HIGH, nullptr, m_eventContext.get());
}
m_eventLoop = nullptr;
}

m_eventContext.clear();
m_eventContext = nullptr;
}

void WorkQueue::registerSocketEventHandler(int fileDescriptor, std::function<void ()> function, std::function<void ()> closeFunction)
Expand Down

0 comments on commit e01b97f

Please sign in to comment.