Commit e1e700b0 authored by carlosgc@webkit.org's avatar carlosgc@webkit.org
Browse files

2011-04-08 Carlos Garcia Campos <cgarcia@igalia.com>

        Reviewed by Martin Robinson.

        [GTK] Implement scheduleWorkAfterDelay() in WorkQueueGtk
        https://bugs.webkit.org/show_bug.cgi?id=57434

        * Platform/WorkQueue.h:
        * Platform/gtk/WorkQueueGtk.cpp:
        (WorkQueue::EventSource::executeEventSource): This new method
        contains the common code to execute a work item.
        (WorkQueue::EventSource::performWorkOnce): Use
        executeEventSource() to execute the work item.
        (WorkQueue::EventSource::performWork): Use executeEventSource() to
        execute the work item.
        (WorkQueue::registerEventSourceHandler): Use a GSocket instead of
        a GIOChannel since the API is newer and allows us to pass a
        cancellable object to be able to cancel the source.
        (WorkQueue::scheduleWorkOnSource): This new method contains the
        common code to attach a source to a context. It doesn't use a lock
        anymore, since g_source_attach() uses its own mutex internally.
        (WorkQueue::scheduleWork): Use an idle source instead of a timeout
        one, changing the priority to G_PRIORITY_DEFAULT.
        (WorkQueue::scheduleWorkAfterDelay): Implement it using a timeout
        source with the given delay.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@83278 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3e085bd0
2011-04-08 Carlos Garcia Campos <cgarcia@igalia.com>
Reviewed by Martin Robinson.
[GTK] Implement scheduleWorkAfterDelay() in WorkQueueGtk
https://bugs.webkit.org/show_bug.cgi?id=57434
* Platform/WorkQueue.h:
* Platform/gtk/WorkQueueGtk.cpp:
(WorkQueue::EventSource::executeEventSource): This new method
contains the common code to execute a work item.
(WorkQueue::EventSource::performWorkOnce): Use
executeEventSource() to execute the work item.
(WorkQueue::EventSource::performWork): Use executeEventSource() to
execute the work item.
(WorkQueue::registerEventSourceHandler): Use a GSocket instead of
a GIOChannel since the API is newer and allows us to pass a
cancellable object to be able to cancel the source.
(WorkQueue::scheduleWorkOnSource): This new method contains the
common code to attach a source to a context. It doesn't use a lock
anymore, since g_source_attach() uses its own mutex internally.
(WorkQueue::scheduleWork): Use an idle source instead of a timeout
one, changing the priority to G_PRIORITY_DEFAULT.
(WorkQueue::scheduleWorkAfterDelay): Implement it using a timeout
source with the given delay.
2011-04-08 Carlos Garcia Campos <cgarcia@igalia.com>
Reviewed by Martin Robinson.
......
......@@ -165,6 +165,7 @@ private:
#elif PLATFORM(GTK)
static void* startWorkQueueThread(WorkQueue*);
void workQueueThreadBody();
void scheduleWorkOnSource(GSource*, PassOwnPtr<WorkItem>);
ThreadIdentifier m_workQueueThread;
GMainContext* m_eventContext;
......
......@@ -29,7 +29,9 @@
#include "WKBase.h"
#include <WebCore/NotImplemented.h>
#include <gio/gio.h>
#include <glib.h>
#include <wtf/gobject/GRefPtr.h>
// WorkQueue::EventSource
class WorkQueue::EventSource {
......@@ -43,7 +45,7 @@ public:
GSource* dispatchSource() { return m_dispatchSource; }
static gboolean performWorkOnce(EventSource* eventSource)
static gboolean executeEventSource(EventSource* eventSource)
{
ASSERT(eventSource);
WorkQueue* queue = eventSource->m_workQueue;
......@@ -54,31 +56,31 @@ public:
}
eventSource->m_workItem->execute();
return FALSE;
return TRUE;
}
static gboolean performWork(GIOChannel* channel, GIOCondition condition, EventSource* eventSource)
static gboolean performWorkOnce(EventSource* eventSource)
{
ASSERT(eventSource);
executeEventSource(eventSource);
return FALSE;
}
static gboolean performWork(GSocket* socket, GIOCondition condition, EventSource* eventSource)
{
if (!(condition & G_IO_IN) && !(condition & G_IO_HUP) && !(condition & G_IO_ERR))
return FALSE;
WorkQueue* queue = eventSource->m_workQueue;
{
MutexLocker locker(queue->m_isValidMutex);
if (!queue->m_isValid)
return FALSE;
}
eventSource->m_workItem->execute();
if (!executeEventSource(eventSource))
return FALSE;
if ((condition & G_IO_HUP) || (condition & G_IO_ERR))
return FALSE;
return TRUE;
}
static void deleteEventSource(EventSource* eventSource)
{
ASSERT(eventSource);
......@@ -132,9 +134,9 @@ void WorkQueue::workQueueThreadBody()
void WorkQueue::registerEventSourceHandler(int fileDescriptor, int condition, PassOwnPtr<WorkItem> item)
{
GIOChannel* channel = g_io_channel_unix_new(fileDescriptor);
ASSERT(channel);
GSource* dispatchSource = g_io_create_watch(channel, static_cast<GIOCondition>(condition));
GRefPtr<GSocket> socket = adoptGRef(g_socket_new_from_fd(fileDescriptor, 0));
ASSERT(socket);
GSource* dispatchSource = g_socket_create_source(socket.get(), static_cast<GIOCondition>(condition), 0);
ASSERT(dispatchSource);
EventSource* eventSource = new EventSource(dispatchSource, item, this);
ASSERT(eventSource);
......@@ -154,11 +156,7 @@ void WorkQueue::registerEventSourceHandler(int fileDescriptor, int condition, Pa
m_eventSources.set(fileDescriptor, sources);
}
// Attach the event source to the GMainContext under the mutex since this is shared across multiple threads.
{
MutexLocker locker(m_eventLoopLock);
g_source_attach(dispatchSource, m_eventContext);
}
g_source_attach(dispatchSource, m_eventContext);
}
void WorkQueue::unregisterEventSourceHandler(int fileDescriptor)
......@@ -180,23 +178,31 @@ void WorkQueue::unregisterEventSourceHandler(int fileDescriptor)
}
}
void WorkQueue::scheduleWork(PassOwnPtr<WorkItem> item)
void WorkQueue::scheduleWorkOnSource(GSource* dispatchSource, PassOwnPtr<WorkItem> item)
{
GSource* dispatchSource = g_timeout_source_new(0);
ASSERT(dispatchSource);
EventSource* eventSource = new EventSource(dispatchSource, item, this);
g_source_set_callback(dispatchSource,
reinterpret_cast<GSourceFunc>(&WorkQueue::EventSource::performWorkOnce),
eventSource,
g_source_set_callback(dispatchSource,
reinterpret_cast<GSourceFunc>(&WorkQueue::EventSource::performWorkOnce),
eventSource,
reinterpret_cast<GDestroyNotify>(&WorkQueue::EventSource::deleteEventSource));
{
MutexLocker locker(m_eventLoopLock);
g_source_attach(dispatchSource, m_eventContext);
}
g_source_attach(dispatchSource, m_eventContext);
}
void WorkQueue::scheduleWorkAfterDelay(PassOwnPtr<WorkItem>, double)
void WorkQueue::scheduleWork(PassOwnPtr<WorkItem> item)
{
notImplemented();
GRefPtr<GSource> dispatchSource = adoptGRef(g_idle_source_new());
ASSERT(dispatchSource);
g_source_set_priority(dispatchSource.get(), G_PRIORITY_DEFAULT);
scheduleWorkOnSource(dispatchSource.get(), item);
}
void WorkQueue::scheduleWorkAfterDelay(PassOwnPtr<WorkItem> item, double delay)
{
GRefPtr<GSource> dispatchSource = adoptGRef(g_timeout_source_new(static_cast<guint>(delay * 1000)));
ASSERT(dispatchSource);
scheduleWorkOnSource(dispatchSource.get(), item);
}
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