Changeset 165952 in webkit


Ignore:
Timestamp:
Mar 20, 2014 12:56:38 AM (10 years ago)
Author:
Carlos Garcia Campos
Message:

[GLIB] Add GMainLoopSource class to wrap idle and timeout sources
https://bugs.webkit.org/show_bug.cgi?id=130027

Reviewed by Martin Robinson.

GLib main loop sources like idle and timeouts are sometimes
unconvenient to use and it's very common to forget canceling the
source when the object is destroyed or reset the source ID in the
callback when called. GMainLoopSource is a wrapper class to make it
easier to handle sources and also to avoid those typical mistakes.
It forces to create sources with a name and the user doesn't have
to deal with the source ID anymore. The source is cancelled when
the object is deleted or when a new source is scheduled. It uses
std::function for callbacks so that we no longer need to use the
"proxy" static callbacks either. We can use std::bind to use a
function pointer or a member or even lambda functions. It also handles
repeating sources automatically depending on whether the given
function returns a bool or not.

  • GNUmakefile.list.am:
  • wtf/PlatformEfl.cmake:
  • wtf/PlatformGTK.cmake:
  • wtf/RunLoop.h:
  • wtf/gobject/GMainLoopSource.cpp: Added.

(WTF::GMainLoopSource::createAndDeleteOnDestroy):
(WTF::GMainLoopSource::GMainLoopSource):
(WTF::GMainLoopSource::~GMainLoopSource):
(WTF::GMainLoopSource::cancel):
(WTF::GMainLoopSource::reset):
(WTF::GMainLoopSource::scheduleIdleSource):
(WTF::GMainLoopSource::schedule):
(WTF::GMainLoopSource::scheduleTimeoutSource):
(WTF::GMainLoopSource::scheduleAfterDelay):
(WTF::GMainLoopSource::voidCallback):
(WTF::GMainLoopSource::boolCallback):
(WTF::GMainLoopSource::socketCallback):
(WTF::GMainLoopSource::destroy):
(WTF::GMainLoopSource::voidSourceCallback):
(WTF::GMainLoopSource::boolSourceCallback):
(WTF::GMainLoopSource::socketSourceCallback):

  • wtf/gobject/GMainLoopSource.h: Added.

(WTF::GMainLoopSource::isScheduled):

  • wtf/gtk/MainThreadGtk.cpp:

(WTF::scheduleDispatchFunctionsOnMainThread):

  • wtf/gtk/RunLoopGtk.cpp:

(WTF::RunLoop::wakeUp):
(WTF::RunLoop::TimerBase::TimerBase):
(WTF::RunLoop::TimerBase::start):
(WTF::RunLoop::TimerBase::stop):
(WTF::RunLoop::TimerBase::isActive):

Location:
trunk/Source/WTF
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r165946 r165952  
     12014-03-18  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GLIB] Add GMainLoopSource class to wrap idle and timeout sources
     4        https://bugs.webkit.org/show_bug.cgi?id=130027
     5
     6        Reviewed by Martin Robinson.
     7
     8        GLib main loop sources like idle and timeouts are sometimes
     9        unconvenient to use and it's very common to forget canceling the
     10        source when the object is destroyed or reset the source ID in the
     11        callback when called. GMainLoopSource is a wrapper class to make it
     12        easier to handle sources and also to avoid those typical mistakes.
     13        It forces to create sources with a name and the user doesn't have
     14        to deal with the source ID anymore. The source is cancelled when
     15        the object is deleted or when a new source is scheduled. It uses
     16        std::function for callbacks so that we no longer need to use the
     17        "proxy" static callbacks either. We can use std::bind to use a
     18        function pointer or a member or even lambda functions. It also handles
     19        repeating sources automatically depending on whether the given
     20        function returns a bool or not.
     21
     22        * GNUmakefile.list.am:
     23        * wtf/PlatformEfl.cmake:
     24        * wtf/PlatformGTK.cmake:
     25        * wtf/RunLoop.h:
     26        * wtf/gobject/GMainLoopSource.cpp: Added.
     27        (WTF::GMainLoopSource::createAndDeleteOnDestroy):
     28        (WTF::GMainLoopSource::GMainLoopSource):
     29        (WTF::GMainLoopSource::~GMainLoopSource):
     30        (WTF::GMainLoopSource::cancel):
     31        (WTF::GMainLoopSource::reset):
     32        (WTF::GMainLoopSource::scheduleIdleSource):
     33        (WTF::GMainLoopSource::schedule):
     34        (WTF::GMainLoopSource::scheduleTimeoutSource):
     35        (WTF::GMainLoopSource::scheduleAfterDelay):
     36        (WTF::GMainLoopSource::voidCallback):
     37        (WTF::GMainLoopSource::boolCallback):
     38        (WTF::GMainLoopSource::socketCallback):
     39        (WTF::GMainLoopSource::destroy):
     40        (WTF::GMainLoopSource::voidSourceCallback):
     41        (WTF::GMainLoopSource::boolSourceCallback):
     42        (WTF::GMainLoopSource::socketSourceCallback):
     43        * wtf/gobject/GMainLoopSource.h: Added.
     44        (WTF::GMainLoopSource::isScheduled):
     45        * wtf/gtk/MainThreadGtk.cpp:
     46        (WTF::scheduleDispatchFunctionsOnMainThread):
     47        * wtf/gtk/RunLoopGtk.cpp:
     48        (WTF::RunLoop::wakeUp):
     49        (WTF::RunLoop::TimerBase::TimerBase):
     50        (WTF::RunLoop::TimerBase::start):
     51        (WTF::RunLoop::TimerBase::stop):
     52        (WTF::RunLoop::TimerBase::isActive):
     53
    1542014-03-19  Gavin Barraclough  <barraclough@apple.com>
    255
  • trunk/Source/WTF/GNUmakefile.list.am

    r164430 r165952  
    213213    Source/WTF/wtf/dtoa/strtod.h \
    214214    Source/WTF/wtf/dtoa/utils.h \
     215    Source/WTF/wtf/gobject/GMainLoopSource.cpp \
     216    Source/WTF/wtf/gobject/GMainLoopSource.h \
    215217    Source/WTF/wtf/gobject/GMutexLocker.h \
    216218    Source/WTF/wtf/gobject/GRefPtr.cpp \
  • trunk/Source/WTF/wtf/PlatformEfl.cmake

    r163797 r165952  
    55    efl/RunLoopEfl.cpp
    66
     7    gobject/GMainLoopSource.cpp
    78    gobject/GRefPtr.cpp
    89)
  • trunk/Source/WTF/wtf/PlatformGTK.cmake

    r163797 r165952  
    11list(APPEND WTF_SOURCES
     2    gobject/GMainLoopSource.cpp
    23    gobject/GRefPtr.cpp
    34    gobject/GlibUtilities.cpp
  • trunk/Source/WTF/wtf/RunLoop.h

    r165746 r165952  
    3838
    3939#if USE(GLIB)
    40 #include <wtf/gobject/GRefPtr.h>
     40#include <wtf/gobject/GMainLoopSource.h>
    4141#endif
    4242
     
    100100        bool m_isRepeating;
    101101#elif USE(GLIB)
    102         static gboolean timerFiredCallback(RunLoop::TimerBase*);
    103         gboolean isRepeating() const { return m_isRepeating; }
    104         void clearTimerSource();
    105         GRefPtr<GSource> m_timerSource;
    106         gboolean m_isRepeating;
     102        GMainLoopSource m_timerSource;
    107103#endif
    108104    };
  • trunk/Source/WTF/wtf/gtk/MainThreadGtk.cpp

    r158103 r165952  
    3131#include "MainThread.h"
    3232
    33 #include <glib.h>
     33#include <wtf/gobject/GMainLoopSource.h>
    3434
    3535namespace WTF {
     
    3939}
    4040
    41 static gboolean timeoutFired(gpointer)
    42 {
    43     dispatchFunctionsFromMainThread();
    44     return FALSE;
    45 }
    46 
    4741void scheduleDispatchFunctionsOnMainThread()
    4842{
    49     g_idle_add_full(G_PRIORITY_DEFAULT, timeoutFired, 0, 0);
     43    GMainLoopSource::createAndDeleteOnDestroy().schedule("[WebKit] dispatchFunctionsFromMainThread", dispatchFunctionsFromMainThread);
    5044}
    5145
  • trunk/Source/WTF/wtf/gtk/RunLoopGtk.cpp

    r165746 r165952  
    9898}
    9999
    100 gboolean RunLoop::queueWork(RunLoop* runLoop)
    101 {
    102     runLoop->performWork();
    103     return FALSE;
    104 }
    105 
    106100void RunLoop::wakeUp()
    107101{
    108     GRefPtr<GSource> source = adoptGRef(g_idle_source_new());
    109     g_source_set_priority(source.get(), G_PRIORITY_DEFAULT);
    110     g_source_set_callback(source.get(), reinterpret_cast<GSourceFunc>(&RunLoop::queueWork), this, 0);
    111     g_source_attach(source.get(), m_runLoopContext.get());
    112 
     102    ref();
     103    GMainLoopSource::createAndDeleteOnDestroy().schedule("[WebKit] RunLoop work", std::bind(&RunLoop::performWork, this),
     104        G_PRIORITY_DEFAULT, [this] { deref(); });
    113105    g_main_context_wakeup(m_runLoopContext.get());
    114106}
     
    116108RunLoop::TimerBase::TimerBase(RunLoop& runLoop)
    117109    : m_runLoop(runLoop)
    118     , m_timerSource(0)
    119110{
    120111}
     
    125116}
    126117
    127 void RunLoop::TimerBase::clearTimerSource()
    128 {
    129     m_timerSource = 0;
    130 }
    131 
    132 gboolean RunLoop::TimerBase::timerFiredCallback(RunLoop::TimerBase* timer)
    133 {
    134     GSource* currentTimerSource = timer->m_timerSource.get();
    135     bool isRepeating = timer->isRepeating();
    136     // This can change the timerSource by starting a new timer within the callback.
    137     if (!isRepeating && currentTimerSource == timer->m_timerSource.get())
    138         timer->clearTimerSource();
    139 
    140     timer->fired();
    141     return isRepeating;
    142 }
    143 
    144118void RunLoop::TimerBase::start(double fireInterval, bool repeat)
    145119{
    146     if (m_timerSource)
    147         stop();
    148 
    149     m_timerSource = adoptGRef(g_timeout_source_new(static_cast<guint>(fireInterval * 1000)));
    150     m_isRepeating = repeat;
    151     g_source_set_callback(m_timerSource.get(), reinterpret_cast<GSourceFunc>(&RunLoop::TimerBase::timerFiredCallback), this, 0);
    152     g_source_attach(m_timerSource.get(), m_runLoop.m_runLoopContext.get());
     120    m_timerSource.scheduleAfterDelay("[WebKit] RunLoop::Timer", std::function<bool ()>([this, repeat] { fired(); return repeat; }),
     121        std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<double>(fireInterval)));
    153122}
    154123
    155124void RunLoop::TimerBase::stop()
    156125{
    157     if (!m_timerSource)
    158         return;
    159 
    160     g_source_destroy(m_timerSource.get());
    161     clearTimerSource();
     126    m_timerSource.cancel();
    162127}
    163128
    164129bool RunLoop::TimerBase::isActive() const
    165130{
    166     return m_timerSource;
     131    return m_timerSource.isScheduled();
    167132}
    168133
Note: See TracChangeset for help on using the changeset viewer.