Home | History | Annotate | Download | only in gtk
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     24  * THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "RunLoop.h"
     29 
     30 #include "WKBase.h"
     31 #include <glib.h>
     32 
     33 RunLoop::RunLoop()
     34 {
     35     m_runLoopContext = g_main_context_default();
     36     ASSERT(m_runLoopContext);
     37     m_runLoopMain = g_main_loop_new(m_runLoopContext, FALSE);
     38     ASSERT(m_runLoopMain);
     39 }
     40 
     41 RunLoop::~RunLoop()
     42 {
     43     if (m_runLoopMain) {
     44         if (g_main_loop_is_running(m_runLoopMain))
     45             g_main_loop_quit(m_runLoopMain);
     46         g_main_loop_unref(m_runLoopMain);
     47     }
     48 
     49     if (m_runLoopContext)
     50         g_main_context_unref(m_runLoopContext);
     51 }
     52 
     53 void RunLoop::run()
     54 {
     55     g_main_loop_run(RunLoop::main()->mainLoop());
     56 }
     57 
     58 GMainLoop* RunLoop::mainLoop()
     59 {
     60     return m_runLoopMain;
     61 }
     62 
     63 void RunLoop::stop()
     64 {
     65     g_main_loop_quit(m_runLoopMain);
     66 }
     67 
     68 gboolean RunLoop::queueWork(RunLoop* runLoop)
     69 {
     70     runLoop->performWork();
     71     return FALSE;
     72 }
     73 
     74 void RunLoop::wakeUp()
     75 {
     76     GRefPtr<GSource> source = adoptGRef(g_idle_source_new());
     77     g_source_set_priority(source.get(), G_PRIORITY_DEFAULT);
     78     g_source_set_callback(source.get(), reinterpret_cast<GSourceFunc>(&RunLoop::queueWork), this, 0);
     79     g_source_attach(source.get(), m_runLoopContext);
     80 
     81     g_main_context_wakeup(m_runLoopContext);
     82 }
     83 
     84 RunLoop::TimerBase::TimerBase(RunLoop* runLoop)
     85     : m_runLoop(runLoop)
     86     , m_timerSource(0)
     87 {
     88 }
     89 
     90 RunLoop::TimerBase::~TimerBase()
     91 {
     92     stop();
     93 }
     94 
     95 void RunLoop::TimerBase::clearTimerSource()
     96 {
     97     m_timerSource = 0;
     98 }
     99 
    100 void RunLoop::TimerBase::destroyNotifyCallback(RunLoop::TimerBase* timer)
    101 {
    102     timer->clearTimerSource();
    103 }
    104 
    105 gboolean RunLoop::TimerBase::timerFiredCallback(RunLoop::TimerBase* timer)
    106 {
    107     timer->fired();
    108     return timer->isRepeating();
    109 }
    110 
    111 void RunLoop::TimerBase::start(double fireInterval, bool repeat)
    112 {
    113     if (m_timerSource)
    114         stop();
    115 
    116     m_timerSource = adoptGRef(g_timeout_source_new(static_cast<guint>(fireInterval * 1000)));
    117     m_isRepeating = repeat;
    118     g_source_set_callback(m_timerSource.get(), reinterpret_cast<GSourceFunc>(&RunLoop::TimerBase::timerFiredCallback), this,
    119                           reinterpret_cast<GDestroyNotify>(&RunLoop::TimerBase::destroyNotifyCallback));
    120     g_source_attach(m_timerSource.get(), m_runLoop->m_runLoopContext);
    121 }
    122 
    123 void RunLoop::TimerBase::stop()
    124 {
    125     if (!m_timerSource)
    126         return;
    127 
    128     g_source_destroy(m_timerSource.get());
    129     clearTimerSource();
    130 }
    131 
    132 bool RunLoop::TimerBase::isActive() const
    133 {
    134     return m_timerSource;
    135 }
    136